/kernel/branches/gfx_kernel/blkdev/cd_drv.inc |
---|
0,0 → 1,546 |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI) |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
; Ïðîöåäóðà äëÿ ïîëíîãî ñ÷èòûâàíèÿ âñåõ |
; äàííûõ èç ñåêòîðà êîìïàêò-äèñêà |
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ |
MaxRetr equ 3 |
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû |
; (â òèêàõ) |
BSYWaitTime equ 1000 ;2 |
;************************************************* |
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ * |
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ * |
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. * |
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. * |
;************************************************* |
ReadCD: |
pusha |
; Çàäàòü ðàçìåð ñåêòîðà |
mov [CDBlockSize],2048 ;2352 |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
; Çàäàòü êîä êîìàíäû Read CD |
mov [PacketCommand],byte 0x28 ;0xBE |
; Çàäàòü àäðåñ ñåêòîðà |
mov AX,word [CDSectorAddress+2] |
xchg AL,AH |
mov word [PacketCommand+2],AX |
mov AX,word [CDSectorAddress] |
xchg AL,AH |
mov word [PacketCommand+4],AX |
; mov eax,[CDSectorAddress] |
; mov [PacketCommand+2],eax |
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ |
mov [PacketCommand+8],byte 1 |
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå |
; mov [PacketCommand+9],byte 0xF8 |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
; call test_mario79 |
popa |
ret |
;******************************************** |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ * |
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ * |
;******************************************** |
ReadCDWRetr: |
pusha |
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå |
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê |
mov ECX,MaxRetr |
@@NextRetr: |
; Ïîäàòü êîìàíäó |
call ReadCD |
cmp [DevErrorCode],0 |
je @@End_4 |
; Çàäåðæêà íà 2,5 ñåêóíäû |
mov EAX,[timer_ticks] |
add EAX,250 ;50 |
@@Wait: |
call change_task |
cmp EAX,[timer_ticks] |
ja @@Wait |
loop @@NextRetr |
; call test_mario79 |
; Ñîîáùåíèå îá îøèáêå |
; mov SI,offset ErrS |
; call FatalError |
@@End_4: |
popa |
ret |
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå |
; ïàêåòíûõ êîìàíä â ðåæèìå PIO |
; |
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè |
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ) |
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä |
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû |
PacketCommand: rb 12 ;DB 12 DUP (?) |
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà |
;CDDataBuf DB 4096 DUP (0) |
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ |
CDBlockSize DW ? |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ |
CDSectorAddress: DD ? |
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì |
TickCounter_1 DD 0 |
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà |
WURStartTime DD 0 |
; óêàçàòåëü áóôåðà äëÿ ñ÷èòûâàíèÿ |
CDDataBuf_pointer dd 0 |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; * |
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. * |
;**************************************************** |
SendPacketDatCommand: |
pushad |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov [ATAFeatures],0 |
mov [ATASectorCount],0 |
mov [ATASectorNumber],0 |
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà |
mov AX,[CDBlockSize] |
mov [ATACylinder],AX |
mov [ATAHead],0 |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
; call test_mario79 |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice0: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
cli |
mov DX,[ATABasePortAddr] |
mov AX,[PacketCommand] |
out DX,AX |
mov AX,[PacketCommand+2] |
out DX,AX |
mov AX,[PacketCommand+4] |
out DX,AX |
mov AX,[PacketCommand+6] |
out DX,AX |
mov AX,[PacketCommand+8] |
out DX,AX |
mov AX,[PacketCommand+10] |
out DX,AX |
sti |
; Îæèäàíèå ãîòîâíîñòè äàííûõ |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice1: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_temp |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice1 |
cli |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf |
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà |
mov DX,[ATABasePortAddr] ;ïîðò 1x0h |
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ |
mov CX,[CDBlockSize] |
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ |
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2 |
; Ïðèíÿòü áëîê äàííûõ |
cld |
rep insw |
sti |
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ |
jmp @@End_8 |
; Çàïèñàòü êîä îøèáêè |
@@Err1_1: |
mov [DevErrorCode],1 |
jmp @@End_8 |
@@Err6_temp: |
mov [DevErrorCode],7 |
jmp @@End_8 |
@@Err6: |
mov [DevErrorCode],6 |
@@End_8: |
popad |
ret |
;*********************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç * |
;* ãëîáàëüíûå ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. * |
;*********************************************** |
SendPacketNoDatCommand: |
pushad |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov [ATAFeatures],0 |
mov [ATASectorCount],0 |
mov [ATASectorNumber],0 |
mov [ATACylinder],0 |
mov [ATAHead],0 |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice0_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0_1 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
; cli |
mov DX,[ATABasePortAddr] |
mov AX,word [PacketCommand] |
out DX,AX |
mov AX,word [PacketCommand+2] |
out DX,AX |
mov AX,word [PacketCommand+4] |
out DX,AX |
mov AX,word [PacketCommand+6] |
out DX,AX |
mov AX,word [PacketCommand+8] |
out DX,AX |
mov AX,word [PacketCommand+10] |
out DX,AX |
; sti |
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice1_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,40h ;ñîñòîÿíèå ñèãíàëà DRDY |
jz @@WaitDevice1_1 |
jmp @@End_9 |
; Çàïèñàòü êîä îøèáêè |
@@Err1_3: |
mov [DevErrorCode],1 |
jmp @@End_9 |
@@Err6_1: |
mov [DevErrorCode],6 |
@@End_9: |
popad |
ret |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè. * |
;**************************************************** |
SendCommandToHDD_1: |
pushad |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode],1 |
ja @@Err2_4 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3_4 |
cmp BX,2 |
ja @@Err3_4 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov AX,[ebx+StandardATABases] |
mov [ATABasePortAddr],AX |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX,[ATABasePortAddr] |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_4 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
; mov ecx,0xfff |
mov eax,[timer_ticks] |
mov [TickCounter_1],eax |
@@WaitHDReady_2: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
; dec ecx |
; cmp ecx,0 |
; je @@Err1 |
mov eax,[timer_ticks] |
sub eax,[TickCounter_1] |
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê. |
ja @@Err1_4 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady_2 |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL,08h |
jnz @@WaitHDReady_2 |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX,[ATABasePortAddr] |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL,[ATAFeatures] |
out DX,AL |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL,[ATASectorCount] |
out DX,AL |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL,[ATASectorNumber] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX,[ATACylinder] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL,AH |
out DX,AL |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL,[DiskNumber] |
shl AL,4 |
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5_4 |
or AL,[ATAHead] |
or AL,10100000b |
mov AH,[ATAAddressMode] |
shl AH,6 |
or AL,AH |
out DX,AL |
; Ïîñëàòü êîìàíäó |
mov AL,[ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode],0 |
jmp @@End_10 |
; Çàïèñàòü êîä îøèáêè |
@@Err1_4: |
mov [DevErrorCode],1 |
jmp @@End_10 |
@@Err2_4: |
mov [DevErrorCode],2 |
jmp @@End_10 |
@@Err3_4: |
mov [DevErrorCode],3 |
jmp @@End_10 |
@@Err4_4: |
mov [DevErrorCode],4 |
jmp @@End_10 |
@@Err5_4: |
mov [DevErrorCode],5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
@@End_10: |
sti |
popad |
ret |
;************************************************* |
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
WaitUnitReady: |
pusha |
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè |
mov EAX,[timer_ticks] |
mov [WURStartTime],EAX |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY |
mov [PacketCommand],word 00h |
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ |
@@SendCommand: |
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè |
call SendPacketNoDatCommand |
call change_task |
; Ïðîâåðèòü êîä îøèáêè |
cmp [DevErrorCode],0 |
je @@End_11 |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè |
mov EAX,[timer_ticks] |
sub EAX,[WURStartTime] |
cmp EAX,MaxCDWaitTime |
jb @@SendCommand |
; Îøèáêà òàéì-àóòà |
mov [DevErrorCode],1 |
@@End_11: |
popa |
ret |
;************************************************* |
;* ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
LoadMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ |
mov [PacketCommand+4],word 00000011b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
UnloadMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ |
mov [PacketCommand+4],word 00000010b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* ÎÏÐÅÄÅËÈÒÜ ÎÁÙÅÅ ÊÎËÈ×ÅÑÒÂÎ ÑÅÊÒÎÐΠÍÀ ÄÈÑÊÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
ReadCapacity: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü ðàçìåð áóôåðà â áàéòàõ |
mov [CDBlockSize],8 |
; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY |
mov [PacketCommand],word 25h |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
clear_packet_buffer: |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
mov [PacketCommand],dword 0 |
mov [PacketCommand+4],dword 0 |
mov [PacketCommand+8],dword 0 |
ret |
/kernel/branches/gfx_kernel/blkdev/cdrom.inc |
---|
0,0 → 1,261 |
sys_cd_audio: |
cmp word [cdbase],word 0 |
jnz @f |
mov eax,1 |
ret |
@@: |
; eax=1 cdplay at ebx 0x00FFSSMM |
; eax=2 get tracklist size of ecx to [ebx] |
; eax=3 stop/pause playing |
cmp eax,1 |
jnz nocdp |
call sys_cdplay |
ret |
nocdp: |
cmp eax,2 |
jnz nocdtl |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add ebx,[edi] |
call sys_cdtracklist |
ret |
nocdtl: |
cmp eax,3 |
jnz nocdpause |
call sys_cdpause |
ret |
nocdpause: |
mov eax,0xffffff01 |
ret |
sys_cd_atapi_command: |
pushad |
mov dx,word [cdbase] |
add dx,6 |
mov ax,word [cdid] |
out dx,al |
mov esi,10 |
call delay_ms |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x80 |
cmp al,0 |
jnz res |
jmp cdl6 |
res: |
mov dx,word [cdbase] |
add dx,7 |
mov al,0x8 |
out dx,al |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0xe |
out dx,al |
mov esi,1 |
call delay_ms |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0x8 |
out dx,al |
mov esi,30 |
call delay_ms |
xor cx,cx |
cdl5: |
inc cx |
cmp cx,10 |
jz cdl6 |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x88 |
cmp al,0x00 |
jz cdl5 |
mov esi,100 |
call delay_ms |
jmp cdl5 |
cdl6: |
mov dx,word [cdbase] |
add dx,4 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,5 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,7 |
mov al,0xec |
out dx,al |
mov esi,5 |
call delay_ms |
mov dx,word [cdbase] |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,128 |
out dx,al |
add dx,2 |
mov al,0xa0 |
out dx,al |
xor cx,cx |
mov dx,word [cdbase] |
add dx,7 |
cdl1: |
inc cx |
cmp cx,100 |
jz cdl2 |
in al,dx |
and ax,0x88 |
cmp al,0x8 |
jz cdl2 |
mov esi,2 |
call delay_ms |
jmp cdl1 |
cdl2: |
popad |
ret |
sys_cdplay: |
mov ax,5 |
push ax |
push ebx |
cdplay: |
call sys_cd_atapi_command |
cli |
mov dx,word [cdbase] |
mov ax,0x0047 |
out dx,ax |
mov al,1 |
mov ah,[esp+0] ; min xx |
out dx,ax |
mov ax,[esp+1] ; fr sec |
out dx,ax |
mov ax,256+99 |
out dx,ax |
mov ax,0x0001 |
out dx,ax |
mov ax,0x0000 |
out dx,ax |
mov esi,10 |
call delay_ms |
sti |
add dx,7 |
in al,dx |
test al,1 |
jz cdplayok |
mov ax,[esp+4] |
dec ax |
mov [esp+4],ax |
cmp ax,0 |
jz cdplayfail |
jmp cdplay |
cdplayfail: |
cdplayok: |
pop ebx |
pop ax |
xor eax, eax |
ret |
sys_cdtracklist: |
push ebx |
tcdplay: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x43+2*256 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,200 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
in al,dx |
mov cx,1000 |
mov dx,word [cdbase] |
add dx,7 |
cld |
cdtrnwewait: |
mov esi,10 |
call delay_ms |
in al,dx |
and al,128 |
cmp al,0 |
jz cdtrl1 |
loop cdtrnwewait |
cdtrl1: |
; read the result |
mov ecx,[esp+0] |
mov dx,word [cdbase] |
cdtrread: |
add dx,7 |
in al,dx |
and al,8 |
cmp al,8 |
jnz cdtrdone |
sub dx,7 |
in ax,dx |
mov [ecx],ax |
add ecx,2 |
jmp cdtrread |
cdtrdone: |
pop ecx |
xor eax, eax |
ret |
sys_cdpause: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x004B |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov esi,10 |
call delay_ms |
add dx,7 |
in al,dx |
xor eax, eax |
ret |
/kernel/branches/gfx_kernel/blkdev/fdc.inc |
---|
0,0 → 1,73 |
iglobal |
;function pointers. |
fdc_irq_func dd fdc_null |
endg |
uglobal |
dmasize db 0x0 |
dmamode db 0x0 |
endg |
fdc_init: ;start with clean tracks. |
mov edi,0xD201 |
mov al,0 |
mov ecx,160 |
rep stosb |
ret |
fdc_filesave: ;ebx: cluster to be saved. |
pusha ;returns immediately. does not trigger a write. |
mov eax,ebx |
add eax,31 |
mov bl,18 |
div bl |
mov ah,0 |
add eax,0xD201 |
mov [eax],byte 1 ;This track is now dirty. |
popa |
ret |
fdc_irq: |
call [fdc_irq_func] |
fdc_null: |
ret |
save_image: |
call reserve_flp |
call restorefatchain |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
mov esi,0x100000 |
call SeekTrack |
save_image_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
; call WriteSector |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_image_1 |
mov [FDD_Sector],1 |
inc [FDD_Head] |
cmp [FDD_Head],2 |
jne save_image_1 |
mov [FDD_Head],0 |
inc [FDD_Track] |
call SeekTrack |
cmp [FDD_Track],80 |
jne save_image_1 |
unnecessary_save_image: |
mov [fdc_irq_func],fdc_null |
popa |
mov [flp_status],0 |
ret |
/kernel/branches/gfx_kernel/blkdev/flp_drv.inc |
---|
0,0 → 1,615 |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ |
mov edi,[0x3010] |
mov edi,[edi+TASKDATA.mem_start] |
add edi,ecx |
give_back_application_data_1: |
mov esi,0xD000 ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
take_data_from_application: ; âçÿòü èç ïðèëîæåíèÿ |
mov esi,[0x3010] |
mov esi,[esi+TASKDATA.mem_start] |
add esi,ecx |
take_data_from_application_1: |
mov edi,0xD000 ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status) |
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå |
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà |
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà |
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà |
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí |
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå |
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî |
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá) |
MAX_Track equ 79 |
MAX_Head equ 1 |
MAX_Sector equ 18 |
uglobal |
; Ñ÷åò÷èê òèêîâ òàéìåðà |
TickCounter dd ? |
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ |
FDC_Status DB ? |
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ |
FDD_IntFlag DB ? |
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ |
FDD_Time DD ? |
; Íîìåð äèñêîâîäà |
FDD_Type db 0 |
; Êîîðäèíàòû ñåêòîðà |
FDD_Track DB ? |
FDD_Head DB ? |
FDD_Sector DB ? |
; Áëîê ðåçóëüòàòà îïåðàöèè |
FDC_ST0 DB ? |
FDC_ST1 DB ? |
FDC_ST2 DB ? |
FDC_C DB ? |
FDC_H DB ? |
FDC_R DB ? |
FDC_N DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíèÿ |
ReadRepCounter DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
RecalRepCounter DB ? |
endg |
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà |
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
fdd_motor_status db 0 |
timer_fdd_motor dd 0 |
;************************************* |
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ * |
;************************************* |
Init_FDC_DMA: |
pushad |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov al,6 ; mask channel 2 so we can reprogram it. |
out 0x0a,al |
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy |
out 0x0b,al |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov eax,0xD000 |
out 0x04,al ; set the channel 2 starting address to 0 |
shr eax,8 |
out 0x04,al |
shr eax,8 |
out 0x81,al |
mov al,0 |
out 0x0c, al ; reset flip-flop |
mov al, 0xff ;set count (actual size -1) |
out 0x5, al |
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) |
out 0x5,al |
mov al,2 |
out 0xa,al |
popad |
ret |
;*********************************** |
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC * |
;* Ïàðàìåòðû: * |
;* AL - âûâîäèìûé áàéò. * |
;*********************************** |
FDCDataOutput: |
; pusha |
push eax ecx edx |
mov AH,AL ;çàïîìíèòü áàéò â AH |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäåëèòü ðàçðÿäû 6 è 7 |
cmp AL,80h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@OutByteToFDC |
loop @@TestRS |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_5 |
; Âûâåñòè áàéò â ïîðò äàííûõ |
@@OutByteToFDC: |
inc DX |
mov AL,AH |
out DX,AL |
@@End_5: |
; popa |
pop edx ecx eax |
ret |
;****************************************** |
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC * |
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. * |
;* Âûõîäíûå äàííûå: * |
;* AL - ñ÷èòàííûé áàéò. * |
;****************************************** |
FDCDataInput: |
push ECX |
push DX |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
xor CX,CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS_1: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäëèòü ðàçðÿäû 6 è 7 |
cmp AL,0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@GetByteFromFDC |
loop @@TestRS_1 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_6 |
; Ââåñòè áàéò èç ïîðòà äàííûõ |
@@GetByteFromFDC: |
inc DX |
in AL,DX |
@@End_6: pop DX |
pop ECX |
ret |
;********************************************* |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;********************************************* |
FDCInterrupt: |
; Óñòàíîâèòü ôëàã ïðåðûâàíèÿ |
mov [FDD_IntFlag],1 |
ret |
;****************************************** |
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ * |
;* ÍÃÌÄ * |
;****************************************** |
SetUserInterrupts: |
mov [fdc_irq_func],FDCInterrupt |
ret |
;******************************************* |
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;******************************************* |
WaitFDCInterrupt: |
pusha |
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè |
mov [FDC_Status],FDC_Normal |
; Ñáðîñèòü ôëàã ïðåðûâàíèÿ |
mov [FDD_IntFlag],0 |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ |
@@TestRS_2: |
cmp [FDD_IntFlag],0 |
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;25 ;5 ;îæèäàòü 5 òèêîâ |
jb @@TestRS_2 |
; jl @@TestRS_2 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: popa |
ret |
;********************************* |
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" * |
;********************************* |
FDDMotorON: |
pusha |
; cmp [fdd_motor_status],1 |
; je fdd_motor_on |
mov al,[flp_number] |
cmp [fdd_motor_status],al |
je fdd_motor_on |
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0 |
out DX,AL |
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà |
cmp [flp_number],1 |
jne FDDMotorON_B |
; call FDDMotorOFF_B |
mov AL,1Ch ; Floppy A |
jmp FDDMotorON_1 |
FDDMotorON_B: |
; call FDDMotorOFF_A |
mov AL,2Dh ; Floppy B |
FDDMotorON_1: |
out DX,AL |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü 0,5 ñ |
@@dT: |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;10 |
jb @@dT |
cmp [flp_number],1 |
jne fdd_motor_on_B |
mov [fdd_motor_status],1 |
jmp fdd_motor_on |
fdd_motor_on_B: |
mov [fdd_motor_status],2 |
fdd_motor_on: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************** |
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ * |
;***************************************** |
save_timer_fdd_motor: |
mov eax,[timer_ticks] |
mov [timer_fdd_motor],eax |
ret |
;***************************************** |
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ * |
;***************************************** |
check_fdd_motor_status: |
cmp [fdd_motor_status],0 |
je end_check_fdd_motor_status_1 |
mov eax,[timer_ticks] |
sub eax,[timer_fdd_motor] |
cmp eax,500 |
jb end_check_fdd_motor_status |
call FDDMotorOFF |
mov [fdd_motor_status],0 |
end_check_fdd_motor_status_1: |
mov [flp_status],0 |
end_check_fdd_motor_status: |
ret |
;********************************** |
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ * |
;********************************** |
FDDMotorOFF: |
push AX |
push DX |
cmp [flp_number],1 |
jne FDDMotorOFF_1 |
call FDDMotorOFF_A |
jmp FDDMotorOFF_2 |
FDDMotorOFF_1: |
call FDDMotorOFF_B |
FDDMotorOFF_2: |
pop DX |
pop AX |
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè |
mov [root_read],0 |
mov [flp_fat],0 |
ret |
FDDMotorOFF_A: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0Ch ; Floppy A |
out DX,AL |
ret |
FDDMotorOFF_B: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,5h ; Floppy B |
out DX,AL |
ret |
;******************************* |
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" * |
;******************************* |
RecalibrateFDD: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà" |
mov AL,07h |
call FDCDataOutput |
mov AL,00h |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
; cmp [FDC_Status],0 |
; je no_fdc_status_error |
; mov [flp_status],0 |
;no_fdc_status_error: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************************** |
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;***************************************************** |
SeekTrack: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ïîèñê" |
mov AL,0Fh |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåëÿ |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà äîðîæêè |
mov AL,[FDD_Track] |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit |
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà |
mov AL,08h |
call FDCDataOutput |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_C],AL |
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà |
; Ïîèñê çàâåðøåí? |
test [FDC_ST0],100000b |
je @@Err |
; Çàäàííûé òðåê íàéäåí? |
mov AL,[FDC_C] |
cmp AL,[FDD_Track] |
jne @@Err |
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì? |
mov AL,[FDC_ST0] |
and AL,100b |
shr AL,2 |
cmp AL,[FDD_Head] |
jne @@Err |
; Îïåðàöèÿ çàâåðøåíà óñïåøíî |
mov [FDC_Status],FDC_Normal |
jmp @@Exit |
@@Err: ; Òðåê íå íàéäåí |
mov [FDC_Status],FDC_TrackNotFound |
; mov [flp_status],0 |
@@Exit: |
call save_timer_fdd_motor |
popa |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x46 |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ" |
mov AL,0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_1 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11011000b |
jnz @@Err_1 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_1 |
@@Err_1: mov [FDC_Status],FDC_SectorNotFound |
; mov [flp_status],0 |
@@Exit_1: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíèÿ |
mov [ReadRepCounter],0 |
@@ReadSector_1: |
call ReadSector |
cmp [FDC_Status],0 |
je @@Exit_2 |
cmp [FDC_Status],1 |
je @@Err_3 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíèÿ |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@ReadSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain |
; mov [flp_status],0 |
@@Exit_2: |
popa |
ret |
@@Err_3: |
mov [flp_status],0 |
popa |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x4A |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ" |
mov AL,0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_3 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11000000b ;11011000b |
jnz @@Err_2 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_3 |
@@Err_2: mov [FDC_Status],FDC_SectorNotFound |
@@Exit_3: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain_1: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíèÿ |
mov [ReadRepCounter],0 |
@@WriteSector_1: |
call WriteSector |
cmp [FDC_Status],0 |
je @@Exit_4 |
cmp [FDC_Status],1 |
je @@Err_4 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíèÿ |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@WriteSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain_1 |
@@Exit_4: |
popa |
ret |
@@Err_4: |
mov [flp_status],0 |
popa |
ret |
;********************************************* |
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ * |
;********************************************* |
GetStatusInfo: |
push AX |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_ST1],AL |
call FDCDataInput |
mov [FDC_ST2],AL |
call FDCDataInput |
mov [FDC_C],AL |
call FDCDataInput |
mov [FDC_H],AL |
call FDCDataInput |
mov [FDC_R],AL |
call FDCDataInput |
mov [FDC_N],AL |
pop AX |
ret |
/kernel/branches/gfx_kernel/blkdev/rd.inc |
---|
0,0 → 1,1956 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; RAMDISK functions ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; Addings by M.Lisovin ;; |
;; LFN support by diamond ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; calculate fat chain |
calculatefatchain: |
pushad |
mov esi,0x100000+512 |
mov edi,0x280000 |
fcnew: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
mov ecx,dword [esi+8] |
mov edx,ecx |
shr edx,4 ;8 ok |
shr dx,4 ;7 ok |
xor ch,ch |
shld ecx,ebx,20 ;6 ok |
shr cx,4 ;5 ok |
shld ebx,eax,12 |
and ebx,0x0fffffff ;4 ok |
shr bx,4 ;3 ok |
shl eax,4 |
and eax,0x0fffffff ;2 ok |
shr ax,4 ;1 ok |
mov dword [edi],eax |
mov dword [edi+4],ebx |
mov dword [edi+8],ecx |
mov dword [edi+12],edx |
add edi,16 |
add esi,12 |
cmp edi,0x280000+2856*2 ;2849 clusters |
jnz fcnew |
popad |
ret |
restorefatchain: ; restore fat chain |
pushad |
mov esi,0x280000 |
mov edi,0x100000+512 |
fcnew2: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
shl ax,4 |
shl eax,4 |
shl bx,4 |
shr ebx,4 |
shrd eax,ebx,8 |
shr ebx,8 |
mov dword [edi],eax |
mov word [edi+4],bx |
add edi,6 |
add esi,8 |
cmp edi,0x100000+512+4278 ;4274 bytes - all used FAT |
jb fcnew2 |
mov esi,0x100000+512 ; duplicate fat chain |
mov edi,0x100000+512+0x1200 |
mov ecx,1069 ;4274/4 |
cld |
rep movsd |
popad |
ret |
ramdisk_free_space: |
;--------------------------------------------- |
; |
; returns free space in edi |
; rewr.by Mihasik |
;--------------------------------------------- |
push eax ebx ecx |
mov edi,0x280000 ;start of FAT |
xor ax,ax ;Free cluster=0x0000 in FAT |
xor ebx,ebx ;counter |
mov ecx,2849 ;2849 clusters |
cld |
rdfs1: |
repne scasw |
jnz rdfs2 ;if last cluster not 0 |
inc ebx |
test ecx, ecx |
jnz rdfs1 |
rdfs2: |
shl ebx,9 ;free clusters*512 |
mov edi,ebx |
pop ecx ebx eax |
ret |
expand_filename: |
;--------------------------------------------- |
; |
; exapand filename with '.' to 11 character |
; eax - pointer to filename |
;--------------------------------------------- |
push esi edi ebx |
mov edi,esp ; check for '.' in the name |
add edi,12+8 |
mov esi,eax |
mov eax,edi |
mov [eax+0],dword ' ' |
mov [eax+4],dword ' ' |
mov [eax+8],dword ' ' |
flr1: |
cmp [esi],byte '.' |
jne flr2 |
mov edi,eax |
add edi,7 |
jmp flr3 |
flr2: |
mov bl,[esi] |
mov [edi],bl |
flr3: |
inc esi |
inc edi |
mov ebx,eax |
add ebx,11 |
cmp edi,ebx |
jbe flr1 |
pop ebx edi esi |
ret |
fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X 0=root |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
test ebx,ebx ;if ebx=0 - set to 1 |
jnz frfl5 |
inc ebx |
frfl5: |
test ecx,ecx ;if ecx=0 - set to 1 |
jnz frfl6 |
inc ecx |
frfl6: |
test esi,esi ; return ramdisk root |
jnz fr_noroot ;if not root |
cmp ebx,14 ;14 clusters=root dir |
ja oorr |
cmp ecx,14 |
ja oorr |
jmp fr_do |
oorr: |
mov eax,5 ;out of root range (fnf) |
xor ebx,ebx |
dec ebx ;0xffffffff |
ret |
fr_do: ;reading rootdir |
mov edi,edx |
dec ebx |
push edx |
mov edx,ecx |
add edx,ebx |
cmp edx,15 ;ebx+ecx=14+1 |
pushf |
jbe fr_do1 |
sub edx,14 |
sub ecx,edx |
fr_do1: |
shl ebx,9 |
mov esi,0x100000+512*19 |
add esi,ebx |
shl ecx,7 |
cld |
rep movsd |
popf |
pop edx |
jae fr_do2 |
xor eax,eax ; ok read |
xor ebx,ebx |
ret |
fr_do2: ;if last cluster |
mov eax,6 ;end of file |
xor ebx,ebx |
ret |
fr_noroot: |
sub esp,32 |
call expand_filename |
dec ebx |
push eax |
push eax ebx ecx edx esi edi |
call rd_findfile |
je fifound |
add esp,32+28 ;if file not found |
ret |
fifound: |
mov ebx,[edi-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
add edi,0xf |
movzx eax,word [edi] |
mov edi,eax ;edi=cluster |
frnew: |
add eax,31 ;bootsector+2*fat+filenames |
shl eax,9 ;*512 |
add eax,0x100000 ;image base |
mov ebx,[esp+8] |
mov ecx,512 ;[esp+4] |
cmp [esp+16],dword 0 ; wanted cluster ? |
jne frfl7 |
call memmove |
add [esp+8],dword 512 |
dec dword [esp+12] ; last wanted cluster ? |
je frnoread |
jmp frfl8 |
frfl7: |
dec dword [esp+16] |
frfl8: |
movzx eax,word [edi*2+0x280000] ; find next cluster from FAT |
mov edi,eax |
cmp edi,4095 ;eof - cluster |
jz frnoread2 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread |
sub [esp+24],dword 512 |
jmp frnew |
frnoread2: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
ret |
frnoread: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
xor eax,eax ;read ok |
ret |
filedelete: |
;-------------------------------------------- |
; |
; filedelete - sys floppy |
; in: |
; eax - pointer to filename 11 chars |
; |
; out: |
; eax - 0 = successful, 5 = file not found |
; |
;-------------------------------------------- |
sub esp,32 |
call expand_filename |
push eax ebx ecx edx esi edi |
call rd_findfile |
je fifoundd |
pop edi esi edx ecx ebx eax ;file not found |
add esp,32 |
mov eax,5 |
ret |
fifoundd: |
mov [edi-11],byte 0xE5 ;mark filename deleted |
add edi,0xf |
movzx eax,word [edi] |
mov edi,eax ;edi = cluster |
frnewd: |
shl edi,1 ;find next cluster from FAT |
add edi,0x280000 |
movzx eax,word [edi] |
mov [edi],word 0x0 ;clear fat chain cluster |
mov edi,eax |
cmp edi,dword 0xff8 ;last cluster ? |
jb frnewd |
pop edi esi edx ecx ebx eax |
add esp,32 |
xor eax,eax ; file found |
ret |
filesave: |
;---------------------------------------------------------- |
; |
; filesave - sys floppy |
; |
; eax points to filename 11 chars |
; |
; eax ; pointer to file name |
; ebx ; buffer |
; ecx ; count to write in bytes |
; edx ; 0 create new , 1 append |
; |
;----------------------------------------------------------- |
sub esp,32 |
call expand_filename |
test edx,edx |
jnz fsdel |
pusha |
call filedelete |
popa |
fsdel: |
call ramdisk_free_space |
cmp ecx,edi |
jbe rd_do_save |
add esp,32 |
mov eax,8 ;disk full |
ret |
rd_do_save: |
push eax ebx ecx edx esi edi |
mov edi,0x100000+512*18+512 ;Point at directory |
mov edx,224 +1 |
; find an empty spot for filename in the root dir |
l20ds: |
dec edx |
jz frnoreadds |
l21ds: |
cmp [edi],byte 0xE5 |
jz fifoundds |
cmp [edi],byte 0x0 |
jz fifoundds |
add edi,32 ; Advance to next entry |
jmp l20ds |
fifoundds: |
push edi ; move the filename to root dir |
mov esi,[esp+4+20] |
mov ecx,11 |
cld |
rep movsb |
pop edi |
mov edx,edi |
add edx,11+0xf ; edx <- cluster save position |
mov ebx,[esp+12] ; save file size |
mov [edi+28],ebx |
mov [edi+11],byte 0x20 ; attribute |
; Ivan Poddubny 11/12/2003: |
call get_date_for_file ; from FAT32.INC |
mov [edi+24],ax ; date |
call get_time_for_file ; from FAT32.INC |
mov [edi+22],ax ; time |
; End |
mov edi,0x280000 ;pointer to first cluster |
mov ecx,2849 |
cld |
frnewds: |
xor ax,ax |
repne scasw |
mov ebx,2848 |
sub ebx,ecx |
mov [edx],bx ; save next cluster pos. to prev cl. |
mov edx,edi ; next save pos abs mem add |
dec edx |
dec edx |
call fdc_filesave |
pusha ; move save to floppy cluster |
add ebx,31 |
shl ebx,9 |
add ebx,0x100000 |
mov eax,[esp+32+16] |
mov ecx,512 |
call memmove |
popa |
mov eax,[esp+12] |
cmp eax,512 |
jbe flnsa |
sub eax,512 |
mov [esp+12],eax |
add dword [esp+16], 512 |
jmp frnewds |
flnsa: |
mov [edi-2],word 4095 ; mark end of file - last cluster |
frnoreadds: |
pop edi esi edx ecx ebx eax |
add esp,32 |
; pusha |
; cli |
; call fdc_commitfile |
; sti |
; popa |
xor eax,eax ;ok write |
ret |
rd_findfile: |
;by Mihasik |
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx |
mov edi,0x100000+512*18+512 ;Point at directory |
cld |
rd_newsearch: |
mov esi,eax |
mov ecx,11 |
rep cmpsb |
je rd_ff |
add cl,21 |
add edi,ecx |
cmp edi,0x100000+512*33 |
jb rd_newsearch |
mov eax,5 ;if file not found - eax=5 |
xor ebx,ebx |
dec ebx ;ebx=0xffffffff and zf=0 |
rd_ff: |
ret |
; \begin{diamond} |
uni2ansi_str: |
; convert UNICODE zero-terminated string to ASCII-string (codepage 866) |
; in: esi->source, edi->buffer (may be esi=edi) |
; destroys: eax,esi,edi |
lodsw |
test ax, ax |
jz .done |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
stosb |
jmp uni2ansi_str |
.done: |
mov byte [edi], 0 |
ret |
ansi2uni_char: |
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding |
mov ah, 0 |
; 0x00-0x7F - trivial map |
cmp al, 0x80 |
jb .ret |
; 0x80-0xAF -> 0x410-0x43F |
cmp al, 0xB0 |
jae @f |
add ax, 0x410-0x80 |
.ret: |
ret |
@@: |
; 0xE0-0xEF -> 0x440-0x44F |
cmp al, 0xE0 |
jb .unk |
cmp al, 0xF0 |
jae @f |
add ax, 0x440-0xE0 |
ret |
; 0xF0 -> 0x401 |
; 0xF1 -> 0x451 |
@@: |
cmp al, 'ð' |
jz .yo1 |
cmp al, 'ñ' |
jz .yo2 |
.unk: |
mov al, '_' ; ah=0 |
ret |
.yo1: |
mov ax, 0x401 |
ret |
.yo2: |
mov ax, 0x451 |
ret |
char_toupper: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'a' |
jb .ret |
cmp al, 'z' |
jbe .az |
cmp al, ' ' |
jb .ret |
cmp al, 'à' |
jb .rus1 |
cmp al, 'ï' |
ja .ret |
; 0xE0-0xEF -> 0x90-0x9F |
sub al, 'à'-'' |
.ret: |
ret |
.rus1: |
; 0xA0-0xAF -> 0x80-0x8F |
.az: |
and al, not 0x20 |
ret |
fat_get_name: |
; in: edi->FAT entry |
; out: CF=1 - no valid entry |
; else CF=0 and ebp->ASCIIZ-name |
; (maximum length of filename is 255 (wide) symbols without trailing 0, |
; but implementation requires buffer 261 words) |
; destroys eax |
cmp byte [edi], 0 |
jz .no |
cmp byte [edi], 0xE5 |
jnz @f |
.no: |
stc |
ret |
@@: |
cmp byte [edi+11], 0xF |
jz .longname |
push ecx |
mov ecx, 8 |
push edi ebp ecx |
test byte [ebp-4], 1 |
jnz .unicode_short |
@@: |
mov al, [edi] |
inc edi |
mov [ebp], al |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp byte [ebp-1], ' ' |
jnz @f |
dec ebp |
loop @b |
@@: |
mov byte [ebp], '.' |
inc ebp |
mov ecx, 3 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
mov [ebp], al |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp byte [ebp-1], ' ' |
jnz @f |
dec ebp |
loop @b |
dec ebp |
@@: |
and byte [ebp], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.unicode_short: |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
@@: |
mov word [ebp], '.' |
inc ebp |
inc ebp |
mov ecx, 3 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
dec ebp |
dec ebp |
@@: |
and word [ebp], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.longname: |
; LFN |
mov al, byte [edi] |
and eax, 0x3F |
dec eax |
cmp al, 20 |
jae .no ; ignore invalid entries |
mov word [ebp+260*2], 0 ; force null-terminating for orphans |
imul eax, 13*2 |
add ebp, eax |
test byte [edi], 0x40 |
jz @f |
mov word [ebp+13*2], 0 |
@@: |
push eax |
; now copy name from edi to ebp ... |
mov eax, [edi+1] |
mov [ebp], eax ; symbols 1,2 |
mov eax, [edi+5] |
mov [ebp+4], eax ; 3,4 |
mov eax, [edi+9] |
mov [ebp+8], ax ; 5 |
mov eax, [edi+14] |
mov [ebp+10], eax ; 6,7 |
mov eax, [edi+18] |
mov [ebp+14], eax ; 8,9 |
mov eax, [edi+22] |
mov [ebp+18], eax ; 10,11 |
mov eax, [edi+28] |
mov [ebp+22], eax ; 12,13 |
; ... done |
pop eax |
sub ebp, eax |
test eax, eax |
jz @f |
; if this is not first entry, more processing required |
stc |
ret |
@@: |
; if this is first entry: |
test byte [ebp-4], 1 |
jnz .ret |
; buffer at ebp contains UNICODE name, convert it to ANSI |
push esi edi |
mov esi, ebp |
mov edi, ebp |
call uni2ansi_str |
pop edi esi |
.ret: |
clc |
ret |
fat_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
push ebp esi |
.loop: |
mov al, [ebp] |
inc ebp |
call char_toupper |
push eax |
lodsb |
call char_toupper |
cmp al, [esp] |
jnz .done |
pop eax |
test al, al |
jnz .loop |
dec esi |
pop eax |
pop ebp |
xor eax, eax ; set ZF flag |
ret |
.done: |
cmp al, '/' |
jnz @f |
cmp byte [esp], 0 |
jnz @f |
mov [esp+4], esi |
@@: |
pop eax |
pop esi ebp |
ret |
fat_time_to_bdfe: |
; in: eax=FAT time |
; out: eax=BDFE time |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 11 |
shl eax, 16 ; hours |
and edx, 0x1F |
add edx, edx |
mov al, dl ; seconds |
shr ecx, 5 |
and ecx, 0x3F |
mov ah, cl ; minutes |
pop edx ecx |
ret |
fat_date_to_bdfe: |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 9 |
add ax, 1980 |
shl eax, 16 ; year |
and edx, 0x1F |
mov al, dl ; day |
shr ecx, 5 |
and ecx, 0xF |
mov ah, cl ; month |
pop edx ecx |
ret |
bdfe_to_fat_time: |
push edx |
mov edx, eax |
shr eax, 16 |
and dh, 0x3F |
shl eax, 6 |
or al, dh |
shr dl, 1 |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
bdfe_to_fat_date: |
push edx |
mov edx, eax |
shr eax, 16 |
sub ax, 1980 |
and dh, 0xF |
shl eax, 4 |
or al, dh |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
fat_entry_to_bdfe: |
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi |
; destroys eax |
mov eax, [ebp-4] |
mov [esi+4], eax ; ASCII/UNICODE name |
fat_entry_to_bdfe2: |
movzx eax, byte [edi+11] |
mov [esi], eax ; attributes |
movzx eax, word [edi+14] |
call fat_time_to_bdfe |
mov [esi+8], eax ; creation time |
movzx eax, word [edi+16] |
call fat_date_to_bdfe |
mov [esi+12], eax ; creation date |
and dword [esi+16], 0 ; last access time is not supported on FAT |
movzx eax, word [edi+18] |
call fat_date_to_bdfe |
mov [esi+20], eax ; last access date |
movzx eax, word [edi+22] |
call fat_time_to_bdfe |
mov [esi+24], eax ; last write time |
movzx eax, word [edi+24] |
call fat_date_to_bdfe |
mov [esi+28], eax ; last write date |
mov eax, [edi+28] |
mov [esi+32], eax ; file size (low dword) |
xor eax, eax |
mov [esi+36], eax ; file size (high dword) |
test ebp, ebp |
jz .ret |
push ecx edi |
lea edi, [esi+40] |
mov esi, ebp |
test byte [esi-4], 1 |
jz .ansi |
mov ecx, 260/2 |
rep movsd |
mov [edi-2], ax |
@@: |
mov esi, edi |
pop edi ecx |
.ret: |
ret |
.ansi: |
mov ecx, 264/4 |
rep movsd |
mov [edi-1], al |
jmp @b |
bdfe_to_fat_entry: |
; convert BDFE at edx to FAT entry at edi |
; destroys eax |
; attributes byte |
test byte [edi+11], 8 ; volume label? |
jnz @f |
mov al, [edx] |
and al, 0x27 |
and byte [edi+11], 0x10 |
or byte [edi+11], al |
@@: |
mov eax, [edx+8] |
call bdfe_to_fat_time |
mov [edi+14], ax ; creation time |
mov eax, [edx+12] |
call bdfe_to_fat_date |
mov [edi+16], ax ; creation date |
mov eax, [edx+20] |
call bdfe_to_fat_date |
mov [edi+18], ax ; last access date |
mov eax, [edx+24] |
call bdfe_to_fat_time |
mov [edi+22], ax ; last write time |
mov eax, [edx+28] |
call bdfe_to_fat_date |
mov [edi+24], ax ; last write date |
ret |
ramdisk_root_first: |
mov edi, 0x100000+512*19 |
clc |
ret |
ramdisk_root_next: |
add edi, 0x20 |
cmp edi, 0x100000+512*33 |
cmc |
ret |
ramdisk_root_extend_dir: |
stc |
ret |
ramdisk_notroot_next: |
add edi, 0x20 |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ret ; CF=0 |
ramdisk_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
mov ecx, [ecx*2+0x280000] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae ramdisk_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
ramdisk_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
shl eax, 9 |
lea edi, [eax+(31 shl 9)+0x100000] |
clc |
ret |
.err2: |
pop ecx |
.err: |
stc |
ret |
ramdisk_notroot_next_write: |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ramdisk_root_next_write: |
ret |
ramdisk_notroot_extend_dir: |
pusha |
xor eax, eax |
mov edi, 0x280000 |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF |
sub edi, 0x280000 |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [0x280000+ecx*2], di |
mov [eax], edi |
shl edi, 9 |
add edi, (31 shl 9)+0x100000 |
mov [esp], edi |
xor eax, eax |
mov ecx, 128 |
rep stosd |
popa |
clc |
ret |
.notfound: |
popa |
stc |
ret |
rd_find_lfn: |
; in: esi->name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
push esi edi |
push 0 |
push ramdisk_root_first |
push ramdisk_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] |
mov [esp+8], eax |
mov dword [esp+4], ramdisk_notroot_first |
mov dword [esp], ramdisk_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
mov eax, [esp+8] |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRead - LFN variant for reading sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskRead: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] ; cluster |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
lea eax, [edi+31] ; bootsector+2*fat+filenames |
shl eax, 9 ; *512 |
add eax, 0x100000 ; image base |
; now eax points to data of cluster |
sub ebx, 512 |
jae .skip |
lea eax, [eax+ebx+512] |
neg ebx |
push ecx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
.skip: |
movzx edi, word [edi*2+0x280000] ; find next cluster from FAT |
jmp .new |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder |
; |
; esi points to filename; only root is folder on ramdisk |
; ebx pointer to structure 32-bit number = first wanted block |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskReadFolder: |
push edi |
cmp byte [esi], 0 |
jz .root |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push esi ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
pop ecx eax |
mov esi, edi ; esi points to block of data of folder entry (BDFE) |
.main_loop: |
mov edi, eax |
shl edi, 9 |
add edi, 0x100000 |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
test edi, 0x1FF |
jnz .do_bdfe |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+0x280000] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
mov edi, eax |
shl edi, 9 |
add edi, 0x100000 |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec ebx |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
test edi, 0x1FF |
jnz .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+0x280000] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
jmp .main_loop |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi edi |
ret |
iglobal |
label fat_legal_chars byte |
; 0 = not allowed |
; 1 = allowed only in long names |
; 3 = allowed |
times 32 db 0 |
; ! " # $ % & ' ( ) * + , - . / |
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 |
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 |
; @ A B C D E F G H I J K L M N O |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; P Q R S T U V W X Y Z [ \ ] ^ _ |
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 |
; ` a b c d e f g h i j k l m n o |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; p q r s t u v w x y z { | } ~ |
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 |
endg |
fat_name_is_legal: |
; in: esi->(long) name |
; out: CF set <=> legal |
; destroys eax |
push esi |
xor eax, eax |
@@: |
lodsb |
test al, al |
jz .done |
cmp al, 80h |
jae .big |
test [fat_legal_chars+eax], 1 |
jnz @b |
.err: |
pop esi |
clc |
ret |
.big: |
; 0x80-0xAF, 0xE0-0xEF |
cmp al, 0xB0 |
jb @b |
cmp al, 0xE0 |
jb .err |
cmp al, 0xF0 |
jb @b |
jmp .err |
.done: |
sub esi, [esp] |
cmp esi, 257 |
pop esi |
ret |
fat_next_short_name: |
; in: edi->8+3 name |
; out: name corrected |
; CF=1 <=> error |
pushad |
mov ecx, 8 |
mov al, '~' |
std |
push edi |
add edi, 7 |
repnz scasb |
pop edi |
cld |
jz .tilde |
; tilde is not found, insert "~1" at end |
add edi, 6 |
cmp word [edi], ' ' |
jnz .insert_tilde |
@@: dec edi |
cmp byte [edi], ' ' |
jz @b |
inc edi |
.insert_tilde: |
mov word [edi], '~1' |
popad |
; clc ; CF already cleared |
ret |
.tilde: |
push edi |
add edi, 7 |
xor ecx, ecx |
@@: |
; after tilde may be only digits and trailing spaces |
cmp byte [edi], '~' |
jz .break |
cmp byte [edi], ' ' |
jz .space |
cmp byte [edi], '9' |
jnz .found |
dec edi |
jmp @b |
.space: |
dec edi |
inc ecx |
jmp @b |
.found: |
inc byte [edi] |
.succ: |
pop edi |
popad |
clc |
ret |
.break: |
jecxz .noplace |
inc edi |
mov al, '1' |
@@: |
xchg al, [edi] |
inc edi |
cmp al, ' ' |
mov al, '0' |
jnz @b |
jmp .succ |
.noplace: |
dec edi |
cmp edi, [esp] |
jz .err |
add dword [esp], 8 |
mov word [edi], '~1' |
inc edi |
inc edi |
@@: |
mov byte [edi], '0' |
inc edi |
cmp edi, [esp] |
jb @b |
pop edi |
popad |
;clc ; automatically |
ret |
.err: |
pop edi |
popad |
stc |
ret |
fat_gen_short_name: |
; in: esi->long name |
; edi->buffer (8+3=11 chars) |
; out: buffer filled |
pushad |
mov eax, ' ' |
push edi |
stosd |
stosd |
stosd |
pop edi |
xor eax, eax |
push 8 |
pop ebx |
lea ecx, [edi+8] |
.loop: |
lodsb |
test al, al |
jz .done |
call char_toupper |
cmp al, ' ' |
jz .space |
cmp al, 80h |
ja .big |
test [fat_legal_chars+eax], 2 |
jnz .symbol |
.inv_symbol: |
mov al, '_' |
or bh, 1 |
.symbol: |
cmp al, '.' |
jz .dot |
.normal_symbol: |
dec bl |
jns .store |
mov bl, 0 |
.space: |
or bh, 1 |
jmp .loop |
.store: |
stosb |
jmp .loop |
.big: |
cmp al, 0xB0 |
jb .normal_symbol |
cmp al, 0xE0 |
jb .inv_symbol |
cmp al, 0xF0 |
jb .normal_symbol |
jmp .inv_symbol |
.dot: |
test bh, 2 |
jz .firstdot |
pop ebx |
add ebx, edi |
sub ebx, ecx |
push ebx |
cmp edi, ecx |
jbe .skip |
@@: |
dec edi |
mov al, ' ' |
xchg al, [edi] |
dec ebx |
mov [ebx], al |
cmp edi, ecx |
ja @b |
.skip: |
mov bh, 3 |
jmp @f |
.firstdot: |
cmp bl, 8 |
jz .space |
push edi |
or bh, 2 |
@@: |
mov edi, ecx |
mov bl, 3 |
jmp .loop |
.done: |
test bh, 2 |
jz @f |
pop edi |
@@: |
lea edi, [ecx-8] |
test bh, 1 |
jz @f |
call fat_next_short_name |
@@: |
popad |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRewrite - LFN variant for writing sys floppy |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fs_RamdiskRewrite: |
cmp byte [esi], 0 |
jz @b |
pushad |
xor ebp, ebp |
push esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea ebp, [esi-1] |
jmp @b |
@@: |
pop esi |
test ebp, ebp |
jnz .noroot |
push ramdisk_root_extend_dir |
push ramdisk_root_next_write |
push ebp |
push ramdisk_root_first |
push ramdisk_root_next |
jmp .common1 |
.noroot: |
; check existence |
mov byte [ebp], 0 |
call rd_find_lfn |
mov byte [ebp], '/' |
lea esi, [ebp+1] |
jnc @f |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push ramdisk_notroot_extend_dir |
push ramdisk_notroot_next_write |
push ebp |
push ramdisk_notroot_first |
push ramdisk_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found; must not be directory |
test byte [edi+11], 10h |
jz @f |
add esp, 20 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [0x280000 + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 20 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <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 |
.doit: |
push edx |
push ecx |
push edi |
add edi, 26 ; edi points to low word of cluster |
push edi |
jecxz .done |
mov ecx, 2849 |
mov edi, 0x280000 |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
jnz .disk_full2 |
dec edi |
dec edi |
lea eax, [edi-0x280000] |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
xchg edi, [esp] |
stosw |
pop edi |
push edi |
inc ecx |
; write data |
shl eax, 9 |
add eax, 0x100000+31*512 |
mov ebx, edx |
xchg eax, ebx |
push ecx |
mov ecx, 512 |
cmp dword [esp+12], ecx |
jae @f |
mov ecx, [esp+12] |
@@: |
call memmove |
add edx, ecx |
sub [esp+12], ecx |
pop ecx |
jnz .write_loop |
.done: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
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 |
popad |
push ERROR_DISK_FULL |
pop eax |
ret |
.read_symbol: |
or ax, -1 |
test esi, esi |
jz .retFFFF |
lodsb |
test al, al |
jnz ansi2uni_char |
xor eax, eax |
xor esi, esi |
.retFFFF: |
ret |
.read_symbols: |
call .read_symbol |
stosw |
loop .read_symbols |
ret |
fs_RamdiskGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
fs_GetFileInfo_finish: |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push esi ebp |
xor ebp, ebp |
mov esi, edx |
and dword [esi+4], 0 |
call fat_entry_to_bdfe2 |
pop ebp esi |
pop edi |
xor eax, eax |
ret |
fs_RamdiskSetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
call bdfe_to_fat_entry |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskExecute - LFN variant for executing on sys floppy |
; |
; esi points to ramdisk filename (e.g. 'launcher') |
; ebp points to full filename (e.g. '/rd/1/launcher') |
; dword [ebx] = flags |
; dword [ebx+4] = cmdline |
; |
; ret ebx,edx destroyed |
; eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
fs_RamdiskExecute: |
mov edx, [ebx] |
mov ebx, [ebx+4] |
test ebx, ebx |
jz @f |
add ebx, std_application_base_address |
@@: |
;---------------------------------------------------------------- |
; |
; fs_RamdiskExecute.flags - second entry |
; |
; esi points to ramdisk filename (kernel address) |
; ebp points to full filename |
; edx flags |
; ebx cmdline (kernel address) |
; |
; ret eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
.flags: |
cmp byte [esi], 0 |
jnz @f |
; cannot execute root! |
mov eax, -ERROR_ACCESS_DENIED |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
mov eax, -ERROR_FILE_NOT_FOUND |
ret |
.found: |
movzx eax, word [edi+26] ; cluster |
push eax |
push dword [edi+28] ; size |
push .DoRead |
call fs_execute |
add esp, 12 |
pop edi |
ret |
.DoRead: |
; read next block |
; in: eax->parameters, edi->buffer |
; out: eax = error code |
pushad |
cmp dword [eax], 0 ; file size |
jz .eof |
mov edx, [eax+4] ; cluster |
lea esi, [edx+31] |
shl esi, 9 |
add esi, 0x100000 |
mov ecx, 512/4 |
rep movsd |
mov ecx, [eax] |
sub ecx, 512 |
jae @f |
add edi, ecx |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
@@: |
mov [eax], ecx |
mov dx, [edx*2+0x280000] |
mov [eax+4], dx ; high word is already zero |
popad |
xor eax, eax |
ret |
.eof: |
popad |
mov eax, 6 |
ret |
; \end{diamond} |
/kernel/branches/gfx_kernel/blkdev/rdsave.inc |
---|
0,0 → 1,25 |
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) |
cmp ebx,1 |
jnz img_save_hd_1 |
mov edx,bootpath ; path = '/KOLIBRI ' |
jmp img_save_hd_3 |
img_save_hd_1: |
cmp ebx,2 |
jnz img_save_hd_2 |
mov edx,bootpath2 ; path = 0 (root dir) |
jmp img_save_hd_3 |
img_save_hd_2: |
cmp ebx,3 |
jnz exit_for_anyone |
mov edx,[0x3010] |
mov edx,[edx+TASKDATA.mem_start] |
add edx,ecx |
img_save_hd_3: |
call reserve_hd1 |
call restorefatchain ; restore FAT !!! |
mov eax,image_save |
mov ebx,1440*1024 ; size 1440 Kb |
mov ecx,0x100000 ; address of image |
call file_write |
mov [esp+36],eax |
ret |
/kernel/branches/gfx_kernel/boot/bootcode.inc |
---|
0,0 → 1,981 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; BOOTCODE.INC ;; |
;; ;; |
;; KolibriOS 16-bit loader, ;; |
;; based on bootcode for MenuetOS ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;========================================================================== |
; |
; 16 BIT FUNCTIONS |
; |
;========================================================================== |
include 'drawtext.inc' |
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 |
org $+0x10000 |
; table for move to extended memory (int 15h, ah=87h) |
movedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 |
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
org $-0x10000 |
include 'bootvesa.inc' |
;========================================================================= |
; |
; 16 BIT CODE |
; |
;========================================================================= |
start_of_code: |
cld |
; \begin{diamond}[02.12.2005] |
cmp ax, 'KL' |
jnz @f |
mov word [cs:cfgmanager.loader_block-0x10000], si |
mov word [cs:cfgmanager.loader_block+2-0x10000], ds |
@@: |
; \end{diamond}[02.12.2005] |
; set up stack |
mov ax, 3000h |
mov ss, ax |
mov sp, 0EC00h |
; set up segment registers |
push cs |
pop ds |
push cs |
pop es |
; set videomode |
mov ax, 3 |
int 0x10 |
if lang eq ru |
; Load & set russian VGA font (RU.INC) |
mov bp,RU_FNT1-10000h ; RU_FNT1 - First part |
mov bx,1000h ; 768 bytes |
mov cx,30h ; 48 symbols |
mov dx,80h ; 128 - position of first symbol |
mov ax,1100h |
int 10h |
mov bp,RU_FNT2-10000h ; RU_FNT2 -Second part |
mov bx,1000h ; 512 bytes |
mov cx,20h ; 32 symbols |
mov dx,0E0h ; 224 - position of first symbol |
mov ax,1100h |
int 10h |
; End set VGA russian font |
end if |
; draw frames |
push 0xb800 |
pop es |
xor di, di |
; mov si,d80x25-0x10000 |
; mov cx,80*25 |
; mov ah,1*16+15 |
; dfl1: |
; lodsb |
; stosw |
; loop dfl1 |
mov ah, 1*16+15 |
; draw top |
mov si, d80x25_top - 0x10000 |
mov cx, d80x25_top_num * 80 |
@@: |
lodsb |
stosw |
loop @b |
; draw spaces |
mov si, space_msg - 0x10000 |
mov cx, 25 - d80x25_top_num - d80x25_bottom_num |
dfl1: |
push cx |
push si |
mov cx, 80 |
@@: |
lodsb |
stosw |
loop @b |
pop si |
pop cx |
loop dfl1 |
; draw bottom |
mov si, d80x25_bottom - 0x10000 |
mov cx, d80x25_bottom_num * 80 |
@@: |
lodsb |
stosw |
loop @b |
mov byte [space_msg-0x10000+80], 0 ; now space_msg is null terminated |
_setcursor d80x25_top_num,0 |
; TEST FOR 386+ |
mov bx, 0x4000 |
pushf |
pop ax |
mov dx,ax |
xor ax,bx |
push ax |
popf |
pushf |
pop ax |
and ax,bx |
and dx,bx |
cmp ax,dx |
jnz cpugood |
mov si,not386-0x10000 |
sayerr: |
call print |
jmp $ |
cpugood: |
; set up esp |
movzx esp, sp |
; FLUSH 8042 KEYBOARD CONTROLLER |
;// mike.dld [ |
; mov al,0xED |
; out 0x60,al |
; or cx,-1 |
; @@: |
; in al,0x64 |
; test al,2 |
; jz @f |
; loop @b |
; @@: |
; mov al,0 |
; out 0x60,al |
; or cx,-1 |
; @@: |
; in al,0x64 |
; test al,2 |
; jz @f |
; loop @b |
; @@: |
;// mike.dld ] |
; mov ecx,10000 |
; fl1: |
; in al,0x64 |
; loop fl1 |
; test al,1 |
; jz fl2 |
; in al,0x60 |
; jmp fl1 |
; fl2: |
;**************************************************************** |
; The function is modified Mario79 |
;***************************************************************** |
; wait_kbd: ; variant 1 |
; mov cx,2500h ;çàäåðæêà ïîðÿäêà 10 ìñåê |
; test_kbd: |
; in al,64h ;÷èòàåì ñîñòîÿíèå êëàâèàòóðû |
; test al,2 ;ïðîâåðêà áèòà ãîòîâíîñòè |
; loopnz test_kbd |
mov al,0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå |
out 0x60,al |
xor cx,cx |
wait_loop: ; variant 2 |
; reading state of port of 8042 controller |
in al,64h |
and al,00000010b ; ready flag |
; wait until 8042 controller is ready |
loopnz wait_loop |
; --------------- APM --------------------- |
push 0 |
pop es |
mov word [es : 0x9044], 0 ; ver = 0.0 (APM not found) |
mov ax, 0x5300 |
xor bx, bx |
int 0x15 |
jc apm_end ; APM not found |
test cx, 2 |
jz apm_end ; APM 32-bit protected-mode interface not supported |
mov [es : 0x9044], ax ; Save APM Version |
mov [es : 0x9046], cx ; Save APM flags |
; Write APM ver ---- |
and ax, 0xf0f |
add ax, '00' |
mov si, msg_apm - 0x10000 |
mov [si + 5], ah |
mov [si + 7], al |
_setcursor 0, 3 |
call printplain |
_setcursor d80x25_top_num,0 |
; ------------------ |
mov ax, 0x5304 ; Disconnect interface |
xor bx, bx |
int 0x15 |
mov ax, 0x5303 ; Connect 32 bit mode interface |
xor bx, bx |
int 0x15 |
; init selectors |
movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment |
shl eax, 4 |
mov [apm_code_32 - 0x10000 + 2], ax |
shr eax, 16 |
mov [apm_code_32 - 0x10000 + 4], al |
movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment |
shl ecx, 4 |
mov [apm_code_16 - 0x10000 + 2], cx |
shr ecx, 16 |
mov [apm_code_16 - 0x10000 + 4], cl |
movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment |
shl edx, 4 |
mov [apm_data_16 - 0x10000 + 2], dx |
shr edx, 16 |
mov [apm_data_16 - 0x10000 + 4], dl |
mov [es : 0x9040], ebx ; offset of APM entry point |
apm_end: |
; ----------------------------------------- |
; DISPLAY VESA INFORMATION |
call print_vesa_info |
; \begin{diamond}[30.11.2005] |
cfgmanager: |
; settings: |
; a) preboot_graph = graphical mode |
; preboot_gprobe = probe this mode? |
; b) preboot_mtrr = use hardware acceleration? |
; c) preboot_vrrm = use VRR? |
; d) preboot_device = from what boot? |
mov di, preboot_graph-0x10000 |
; check bootloader block |
cmp [.loader_block-0x10000], 0 |
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 |
call calc_vmodes_table |
.preboot_gr_end: |
cmp [di+preboot_mtrr-preboot_graph], 1 |
adc [di+preboot_mtrr-preboot_graph], 0 |
cmp [di+preboot_vrrm-preboot_graph], 1 |
adc [di+preboot_vrrm-preboot_graph], 0 |
cmp [di+preboot_device-preboot_graph], 1 |
adc [di+preboot_device-preboot_graph], 0 |
; notify user |
mov si, linef-0x10000 |
call print |
mov si, start_msg-0x10000 |
call print |
mov si, time_msg-0x10000 |
call print |
; get start time |
call .gettime |
mov [.starttime-0x10000], eax |
mov word [.timer-0x10000], .newtimer |
mov word [.timer-0x10000+2], cs |
.printcfg: |
_setcursor 9,0 |
mov si, current_cfg_msg-0x10000 |
call print |
mov si, curvideo_msg-0x10000 |
call print |
call draw_current_vmode |
mov si, linef-0x10000 |
call printplain |
mov si, mtrr_msg-0x10000 |
cmp [preboot_mtrr-0x10000], 1 |
call .say_on_off |
mov si, vrrm_msg-0x10000 |
cmp [preboot_vrrm-0x10000], 1 |
call .say_on_off |
mov si, preboot_device_msg-0x10000 |
call print |
mov al, [preboot_device-0x10000] |
and eax, 3 |
mov si, [preboot_device_msgs-0x10000+eax*2] |
call printplain |
.wait: |
_setcursor 25,0 ; out of screen |
; set timer interrupt handler |
cli |
push 0 |
pop es |
mov eax, [es:8*4] |
mov [.oldtimer-0x10000], eax |
mov eax, [.timer-0x10000] |
mov [es:8*4], eax |
sti |
; wait for keypressed |
mov ah, 0 |
int 16h |
push ax |
; restore timer interrupt |
push 0 |
pop es |
mov eax, [.oldtimer-0x10000] |
mov [es:8*4], eax |
mov [.timer-0x10000], eax |
_setcursor (d80x25_top_num+3),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: |
.lp0: call draw_vmodes_table |
.lp1: mov al,[vm_row] |
sub al,[ln_top] |
jge @f |
dec [ln_top] |
jmp .lp0 |
@@: cmp al,[ln_num] |
jl .lp2 |
inc [ln_top] |
jmp .lp0 |
.lp2: mov cx,0x1A1B |
call draw_vmodes_table_cursor |
mov ax,0x0000 |
int 0x16 |
push ax |
mov cx,' ';0x1A1B |
call draw_vmodes_table_cursor |
pop ax |
cmp ah,0x48;x,0x48E0 ; up |
jne @f |
dec [vm_row] |
jge .lp1 |
mov [vm_row],0 |
jmp .lp1 |
@@: cmp ah,0x50;x,0x50E0 ; down |
jne @f |
inc [vm_row] |
mov al,[ln_cnt] |
dec al |
cmp [vm_row],al |
jle .lp1 |
mov [vm_row],al |
jmp .lp1 |
@@: cmp ah,0x4B;x,0x4BE0 ; left |
jne @f |
dec [vm_col] |
jge .lp1 |
mov [vm_col],0 |
jmp .lp1 |
@@: cmp ah,0x4D;x,0x4DE0 ; right |
jne @f |
inc [vm_col] |
cmp [vm_col],5 |
jle .lp1 |
mov [vm_col],5 |
jmp .lp1 |
@@: cmp al,0x0D;x,0x1C0D ; enter |
jne .lp2 |
_setcursor 10,0 |
jmp .d |
.change_b: |
_setcursor 15,0 |
mov si, gr_acc-0x10000 |
call print |
mov bx, '12' |
call getkey |
mov [preboot_mtrr-0x10000], al |
_setcursor 11,0 |
jmp .d |
.change_c: |
_setcursor 15,0 |
mov si, vrrmprint-0x10000 |
call print |
mov bx, '12' |
call getkey |
mov [preboot_vrrm-0x10000], al |
_setcursor 12,0 |
jmp .d |
.say_on_off: |
pushf |
call print |
mov si, on_msg-0x10000 |
popf |
jz @f |
mov si, off_msg-0x10000 |
@@: call printplain |
ret |
; novesa and vervesa strings are not used at the moment of executing this code |
virtual at novesa |
.oldtimer dd ? |
.starttime dd ? |
.bSettingsChanged db ? |
.timer dd ? |
end virtual |
org $+0x10000 |
.loader_block dd 0 |
org $-0x10000 |
.gettime: |
mov ah, 0 |
int 1Ah |
xchg ax, cx |
shl eax, 10h |
xchg ax, dx |
ret |
.newtimer: |
push ds |
push cs |
pop ds |
pushf |
call [.oldtimer-0x10000] |
pushad |
call .gettime |
sub eax, [.starttime-0x10000] |
sub ax, 18*5 |
jae .timergo |
neg ax |
add ax, 18-1 |
mov bx, 18 |
xor dx, dx |
div bx |
if lang eq ru |
; ¯®¤®¦¤¨â¥ 5 ᥪã¤, 4/3/2 ᥪã¤ë, 1 ᥪã¤ã |
cmp al, 5 |
mov cl, ' ' |
jae @f |
cmp al, 1 |
mov cl, 'ã' |
jz @f |
mov cl, 'ë' |
@@: mov [time_str+9-0x10000], cl |
else |
; wait 5/4/3/2 seconds, 1 second |
cmp al, 1 |
mov cl, 's' |
ja @f |
mov cl, ' ' |
@@: mov [time_str+9-0x10000], cl |
end if |
add al, '0' |
mov [time_str+1-0x10000], al |
mov si, time_msg-0x10000 |
_setcursor (d80x25_top_num+3),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], 0 |
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 |
call set_vmode |
; GRAPHICS ACCELERATION |
mov al, [preboot_mtrr-0x10000] |
mov [es:0x901C],al |
; VRR_M USE |
mov al,[preboot_vrrm-0x10000] |
mov [es:0x9030],al |
; MEMORY MODEL |
; movzx eax,byte [es:preboot_memory-0x10000] |
; cmp eax,0 |
; jne pre_mem |
;;;;;;;;;;;;;;;;;;;;;;;;; |
; mario79 - memory size ; |
;;;;;;;;;;;;;;;;;;;;;;;;; |
; mov ax,0E801h |
;;; xor bx,bx ; thanks to Alexei for bugfix [18.07.2004] |
; xor cx, cx |
; xor dx, dx |
; int 0x15 |
; movzx ebx, dx ;bx |
; movzx eax, cx ;ax |
; shl ebx,6 ; ïåðåâîä â êèëîáàéòû (x64) |
; add eax,ebx |
; add eax, 1000h ;440h |
; cmp eax,40000h ; 256? |
; jge mem_256_z |
; cmp eax,20000h ; 128? |
; jge mem_128_z |
; cmp eax,10000h ; 64? |
; jge mem_64_z |
; cmp eax,8000h ; 32? |
; jge mem_32_z |
; jmp mem_16_z |
; |
;mem_256_z: mov si,memokz256-0x10000 |
; call printplain |
; mov eax,5 |
; jmp pre_mem |
;mem_128_z: mov si,memokz128-0x10000 |
; call printplain |
; mov eax,4 |
; jmp pre_mem |
;mem_64_z: mov si,memokz64-0x10000 |
; call printplain |
; mov eax,3 |
; jmp pre_mem |
;mem_32_z: mov si,memokz32-0x10000 |
; call printplain |
; mov eax,2 |
; jmp pre_mem |
;mem_16_z: mov si,memokz16-0x10000 |
; call printplain |
; mov eax,1 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; pre_mem: |
; push word 0x0000 |
; pop es |
; mov [es:0x9030],al |
; push word 0x1000 |
; pop es |
; mov si,linef-0x10000 |
; call printplain |
; DIRECT WRITE TO LFB, PAGING DISABLED |
; movzx eax,byte [es:preboot_lfb-0x10000] |
; mov eax,1 ; paging disabled |
; cmp eax,0 |
; jne pre_lfb |
; mov si,gr_direct-0x10000 |
; call printplain |
; mov ebx,'12' |
; call getkey |
; pre_lfb: |
; push word 0x0000 |
; pop es |
; mov [es:0x901E],al |
; mov ax,0x1000 |
; mov es,ax |
; mov si,linef-0x10000 |
; call printplain |
mov [es:0x901E],byte 1 |
; BOOT DEVICE |
mov al, [preboot_device-0x10000] |
dec al |
mov [boot_dev-0x10000],al |
; READ DISKETTE TO MEMORY |
; cmp [boot_dev-0x10000],0 |
jne no_sys_on_floppy |
mov si,diskload-0x10000 |
call print |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov cx,0x0001 ; startcyl,startsector |
xor dx, dx ; starthead,drive |
push word 80*2 ; read no of sect |
reads: |
pusha |
xor si,si |
newread: |
mov bx,0xa000 ; es:bx -> data area |
mov ax,0x0200+18 ; read, no of sectors to read |
int 0x13 |
test ah, ah |
jz goodread |
inc si |
cmp si,10 |
jnz newread |
mov si,badsect-0x10000 |
sayerr_plain: |
call printplain |
jmp $ |
goodread: |
; move -> 1mb |
mov si,movedesc-0x10000 |
push es |
push ds |
pop es |
mov cx,256*18 |
mov ah,0x87 |
int 0x15 |
pop es |
test ah,ah ; was the move successfull ? |
je goodmove |
mov dx,0x3f2 ; floppy motor off |
mov al,0 |
out dx,al |
mov si,memmovefailed-0x10000 |
jmp sayerr_plain |
goodmove: |
add dword [movedesc-0x10000+0x18+2], 512*18 |
popa |
inc dh |
cmp dh,2 |
jnz bb2 |
mov dh,0 |
inc ch |
pusha ; print prosentage |
mov si,pros-0x10000 |
shr ch, 2 |
mov al, '5' |
test ch, 1 |
jnz @f |
mov al, '0' |
@@: |
mov [si+1], al |
shr ch, 1 |
add ch, '0' |
mov [si], ch |
call printplain |
popa |
bb2: |
pop ax |
dec ax |
push ax |
jnz reads |
readdone: |
pop ax |
mov si,backspace2-0x10000 |
call printplain |
mov si,okt-0x10000 |
call printplain |
no_sys_on_floppy: |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov dx,0x3f2 ; floppy motor off |
mov al,0 |
out dx,al |
push es |
; PAGE TABLE |
push dword [es:0x9018] |
map_mem equ 64 ; amount of memory to map |
push 0x6000 |
pop es ; es:di = 6000:0 |
xor di,di |
mov cx,256*map_mem ; Map (mapmem) M |
; initialize as identity mapping |
xor eax, eax |
call pagetable_set |
; 4 KB PAGE DIRECTORY |
push 0x7F00 |
pop es ; es:di = 7F00:0 |
xor di, di |
mov cx, 64 / 4 |
mov eax, 0x60007 ; for 0 M |
call pagetable_set |
xor si,si |
mov di,second_base_address shr 20 |
mov cx,64/2 |
rep movs word [es:di], [es:si] |
mov eax, 0x7F000 +8+16 ; Page directory and enable caches |
mov cr3, eax |
; SET GRAPHICS |
pop es |
push 0 |
pop es |
mov ax,[es:0x9008] ; vga & 320x200 |
mov bx, ax |
cmp ax,0x13 |
je setgr |
cmp ax,0x12 |
je setgr |
mov ax,0x4f02 ; Vesa |
setgr: |
int 0x10 |
test ah,ah |
mov si, fatalsel-0x10000 |
jnz sayerr |
; set mode 0x12 graphics registers: |
cmp bx,0x12 |
jne gmok2 |
mov al,0x05 |
mov dx,0x03ce |
push dx |
out dx,al ; select GDC mode register |
mov al,0x02 |
inc dx |
out dx,al ; set write mode 2 |
mov al,0x02 |
mov dx,0x03c4 |
out dx,al ; select VGA sequencer map mask register |
mov al,0x0f |
inc dx |
out dx,al ; set mask for all planes 0-3 |
mov al,0x08 |
pop dx |
out dx,al ; select GDC bit mask register |
; for writes to 0x03cf |
gmok2: |
push ds |
pop es |
/kernel/branches/gfx_kernel/boot/booteng.inc |
---|
0,0 → 1,133 |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
macro line_full_top { |
db 201 |
times 78 db 205 |
db 187 |
} |
macro line_full_bottom { |
db 200 |
times 78 db 205 |
db 188 |
} |
macro line_half { |
db 186,' ' |
times 76 db 0xc4 |
db ' ',186 |
} |
macro line_space { |
db 186 |
times 78 db 32 |
db 186 |
} |
d80x25_top: |
line_full_top |
verstr2: |
; 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 - ($-verstr2) |
db ' ' |
end repeat |
db 32,186 |
verstr: |
line_half |
space_msg: line_space |
d80x25_top_num = 3 |
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 |
msg_apm db " APM x.x ", 0 |
novesa db "Display: EGA/CGA",13,10,0 |
s_vesa db "VESA version: " |
.ver db "?.? (" |
.mem db "??? Mbytes)",13,10,0 |
gr_mode db "Select mode: ",13,10,0 |
s_bpp db 13,10,186," Bits per pixel: " |
.bpp dw "??",13,10,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 |
gr_acc db "Vesa 2.0+ : MTRR graphics acceleration [1-yes/2-no] ? ",0 |
bdev db "Load ramdisk from [1-floppy; 2-C:\menuet.img (FAT32);" |
db " 3-use preloaded ram-image from kernel restart]: ",0 |
not386 db "Fatal - CPU 386+ required.",0 |
fatalsel db 13,10,"Error - Selected mode is not supported.",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 |
modevesa20 db " with LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 colors",0 |
mode10 db "640x480, VGA 16 colors",0 |
mtrr_msg db " [b] Use MTRR for graphics acceleration:",0 |
on_msg db " on",13,10,0 |
off_msg db " off",13,10,0 |
vrrm_msg db " [c] Use VRR:",0 |
preboot_device_msg db " [d] Floppy image: ",0 |
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 |
pdm1 db "real floppy",13,10,0 |
pdm2 db "C:\menuet.img (FAT32)",13,10,0 |
pdm3 db "use already loaded image",13,10,0 |
loading_msg db "Loading KolibriOS...",0 |
save_quest db "Remember current settings? [y/n]: ",0 |
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 |
_oem db 'oem: ',0 |
db 5 |
s_ven_intel db 'Intel' |
db 2 |
s_ven_s3 db 'S3' |
;db 5 |
;s_ven_bochs db 'Bochs' |
;db 8 |
;s_ven_vmware db 'V M ware' |
s_mode db " ????-????-?? (?) ",0 |
s_mode1 db " 0640-0480-04 (a) 0320-0200-08 (b) ",13,10,0 |
;_tl db 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿',13,10,\ |
; '³ resolution ³ 4 ³ 8 ³ 15 ³ 16 ³ 24 ³ 32 ³',13,10,\ |
; 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄ´',13,10,0 |
;_rs db '³ ????x???? ³ - ³ - ³ - ³ - ³ - ³ - ³',13,10,0 |
;_bt db 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ',13,10,0 |
_tl db 186,' ÚÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿',13,10,\ |
186,' ³ 4 ³ 8 ³ 15 ³ 16 ³ 24 ³ 32 ³',13,10,\ |
186,' ÚÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄ¿',13,10,0 |
_rs db 186,' ³ ????x???? ³ ? ³ ? ³ ? ³ ? ³ ? ³ ? ³Û³',13,10,0 |
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÙ',13,10,0 |
_sel1 db 0x1A,0 |
_sel2 db 0x1B,0 |
/kernel/branches/gfx_kernel/boot/bootru.inc |
---|
0,0 → 1,133 |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
macro line_full_top { |
db 201 |
times 78 db 205 |
db 187 |
} |
macro line_full_bottom { |
db 200 |
times 78 db 205 |
db 188 |
} |
macro line_half { |
db 186,' ' |
times 76 db 0xc4 |
db ' ',186 |
} |
macro line_space { |
db 186 |
times 78 db 32 |
db 186 |
} |
d80x25_top: |
line_full_top |
space_msg: line_space |
verstr: |
; line_space |
; version string |
db 186,32 |
repeat 78 |
load a byte from version+%-1 |
if a = 13 |
break |
end if |
db a |
end repeat |
repeat 78 - ($-verstr) |
db ' ' |
end repeat |
db 32,186 |
line_half |
d80x25_top_num = 4 |
d80x25_bottom: |
db 186,' 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 |
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " |
db "[3] 1024x768, [4] 1280x1024",13,10 |
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " |
db "[7] 1024x768, [8] 1280x1024",13,10 |
db 186," EGA/CGA 256 ¢¥â®¢: [9] 320x200, " |
db "VGA 16 ¢¥â®¢: [0] 640x480",13,10 |
db 186," ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",0 |
bt24 db "«ã¡¨ 梥â : 24",13,10,0 |
bt32 db "«ã¡¨ 梥â : 32",13,10,0 |
vrrmprint db "ᯮ«ì§®¢ âì VRR? (ç áâ®â ª ¤à®¢ ¢ëè¥ 60 æ" |
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10 |
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-¥â]: ",0 |
;askmouse db "ëèì:" ; 186, " " |
; db " [1] PS/2 (USB), [2] Com1, [3] Com2." |
; db " ë¡¥à¨â¥ ¯®àâ [1-3]: ",0 |
;no_com1 db 13,10,186," No COM1 mouse",0 |
;no_com2 db 13,10,186," No COM2 mouse",0 |
gr_acc db "Vesa 2.0+: ª«îç¨âì MTRR ¤«ï ãáª®à¥¨ï £à 䨪¨? " |
db "[1-¤ /2-¥â]: ",0 |
;gr_direct db 186," ᯮ«ì§®¢ âì «¨¥©ë© ¢¨¤¥®¡ãä¥à? " |
; db "[1-¤ /2-¥â]: ",0 |
;mem_model db 13,10,186," ¡ê+¬ ¯ ¬ï⨠[1-16 Mb / 2-32 Mb / " |
; db "3-64Mb / 4-128 Mb / 5-256 Mb]: ",0 |
;bootlog db 13,10,186," à®á¬®âà¥âì ¦ãà « § £à㧪¨? [1-¥â/2-¤ ]: ",0 |
bdev db " £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\menuet.img (FAT32);" |
db 13,10,186," " |
db "3-¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §]: ",0 |
probetext db 13,10,13,10,186," â ¤ àâë© ¢¨¤¥®à¥¦¨¬? [1-¤ , " |
db "2-¯à®¢¥à¨âì ¤à㣨¥ (Vesa 3.0)]: ",0 |
;memokz256 db 13,10,186," RAM 256 Mb",0 |
;memokz128 db 13,10,186," RAM 128 Mb",0 |
;memokz64 db 13,10,186," RAM 64 Mb",0 |
;memokz32 db 13,10,186," RAM 32 Mb",0 |
;memokz16 db 13,10,186," RAM 16 Mb",0 |
prnotfnd db "訡ª - ¨¤¥®à¥¦¨¬ ¥ ©¤¥.",0 |
;modena db "訡ª - ॡã¥âáï ¯®¤¤¥à¦ª VBE 0x112+.",0 |
not386 db "訡ª - ॡã¥âáï ¯à®æ¥áá®à 386+.",0 |
btns db "訡ª - ¥ ¬®£ã ®¯à¥¤¥«¨âì £«ã¡¨ã 梥â .",0 |
fatalsel db "訡ª - ë¡à ë© ¢¨¤¥®à¥¦¨¬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0 |
badsect db 13,10,186," 訡ª - ¨áª¥â ¯®¢à¥¦¤¥ . ®¯à®¡ã©â¥ ¤àã£ãî.",0 |
memmovefailed db 13,10,186," 訡ª - Int 0x15 move failed.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db " £à㧪 ¤¨áª¥âë: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 |
start_msg db " ¦¬¨â¥ [abcd] ¤«ï ¨§¬¥¥¨ï áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥¨ï § £à㧪¨",13,10,0 |
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ " |
time_str db " 5 ᥪ㭤 " |
db " ¤® ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥¨ï",13,10,0 |
current_cfg_msg db "¥ªã騥 áâனª¨:",13,10,0 |
curvideo_msg db " [a] ¨¤¥®à¥¦¨¬: ",0 |
mode1 db "640x480",0 |
mode2 db "800x600",0 |
mode3 db "1024x768",0 |
mode4 db "1280x1024",0 |
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 |
modevesa20 db " á LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 梥⮢",0 |
mode10 db "640x480, VGA 16 梥⮢",0 |
probeno_msg db " (áâ ¤ àâë© ¢¨¤¥®à¥¦¨¬)",0 |
probeok_msg db " (¯à®¢¥à¨âì ¥áâ ¤ àâë¥ à¥¦¨¬ë)",0 |
mtrr_msg db " [b] ᯮ«ì§®¢ ¨¥ MTRR ¤«ï ãáª®à¥¨ï £à 䨪¨:",0 |
on_msg db " ¢ª«",13,10,0 |
off_msg db " ¢ëª«",13,10,0 |
vrrm_msg db " [c] ᯮ«ì§®¢ ¨¥ VRR:",0 |
preboot_device_msg db " [d] ¡à § ¤¨áª¥âë: ",0 |
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 |
pdm1 db " áâ®ïé ï ¤¨áª¥â ",13,10,0 |
pdm2 db "C:\menuet.img (FAT32)",13,10,0 |
pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §",13,10,0 |
loading_msg db "¤ñâ § £à㧪 KolibriOS...",0 |
save_quest db " ¯®¬¨âì ⥪ã騥 áâனª¨? [y/n]: ",0 |
loader_block_error db "訡ª ¢ ¤ ëå ç «ì®£® § £àã§ç¨ª , ¯à®¤®«¦¥¨¥ ¥¢®§¬®¦®.",0 |
/kernel/branches/gfx_kernel/boot/bootvesa.inc |
---|
0,0 → 1,1080 |
struc VBE_VGAInfo { |
.VESASignature dd ? ; char |
.VESAVersion dw ? ; short |
.OemStringPtr dd ? ; char * |
.Capabilities dd ? ; ulong |
.VideoModePtr dd ? ; ulong |
.TotalMemory dw ? ; short |
; VBE 2.0+ |
.OemSoftwareRev db ? ; short |
.OemVendorNamePtr dw ? ; char * |
.OemProductNamePtr dw ? ; char * |
.OemProductRevPtr dw ? ; char * |
.reserved rb 222 ; char |
.OemData rb 256 ; char |
} |
struc VBE_ModeInfo { |
.ModeAttributes dw ? ; short |
.WinAAttributes db ? ; char |
.WinBAttributes db ? ; char |
.WinGranularity dw ? ; short |
.WinSize dw ? ; short |
.WinASegment dw ? ; ushort |
.WinBSegment dw ? ; ushort |
.WinFuncPtr dd ? ; void * |
.BytesPerScanLine dw ? ; short |
.XRes dw ? ; short |
.YRes dw ? ; short |
.XCharSize db ? ; char |
.YCharSize db ? ; char |
.NumberOfPlanes db ? ; char |
.BitsPerPixel db ? ; char |
.NumberOfBanks db ? ; char |
.MemoryModel db ? ; char |
.BankSize db ? ; char |
.NumberOfImagePages db ? ; char |
.res1 db ? ; char |
.RedMaskSize db ? ; char |
.RedFieldPosition db ? ; char |
.GreenMaskSize db ? ; char |
.GreenFieldPosition db ? ; char |
.BlueMaskSize db ? ; char |
.BlueFieldPosition db ? ; char |
.RsvedMaskSize db ? ; char |
.RsvedFieldPosition db ? ; char |
.DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE |
; VBE 2.0+ |
.PhysBasePtr dd ? ; ulong |
.OffScreenMemOffset dd ? ; ulong |
.OffScreenMemSize dw ? ; short |
; VBE 3.0+ |
.LinbytesPerScanLine dw ? ; short |
.BankNumberOfImagePages db ? ; char |
.LinNumberOfImagePages db ? ; char |
.LinRedMaskSize db ? ; char |
.LinRedFieldPosition db ? ; char |
.LingreenMaskSize db ? ; char |
.LinGreenFieldPosition db ? ; char |
.LinBlueMaskSize db ? ; char |
.LinBlueFieldPosition db ? ; char |
.LinRsvdMaskSize db ? ; char |
.LinRsvdFieldPosition db ? ; char |
.MaxPixelClock dd ? ; ulong |
.res2 rb 190 ; char |
} |
virtual at $A000 |
vi VBE_VGAInfo |
mi VBE_ModeInfo |
modes_table: |
end virtual |
ln_top db 1 |
ln_num db 6 |
ln_cnt db ? |
db ? |
ln_top2 db ? |
ln_num2 db ? |
ln_cnt2 db ? |
db ? |
vm_row db 2 |
vm_col db 2 |
print_vesa_info: |
push 0 |
pop es |
_setcursor 3,2 |
mov [es:vi.VESASignature],'VBE2' |
mov ax,$4F00 |
mov di,vi |
int $10 |
or ah,ah |
jz @f |
mov [es:vi.VESASignature],'VESA' |
mov ax,$4F00 |
mov di,vi |
int $10 |
or ah,ah |
jnz .exit |
@@: |
cmp [es:vi.VESASignature],'VESA' |
jne .exit |
cmp [es:vi.VESAVersion],$0100 |
jb .exit |
jmp .vesaok2 |
.exit: |
;pushad |
push 0 |
pop es |
mov si,novesa-0x10000 |
call printplain |
ret |
;pushw 'bb' |
;jmp enum_modes.modes_ok |
.vesaok2: |
mov ecx,0x00200000 |
mov ax,[es:vi.TotalMemory] |
shr ax,4 |
mov bl,10 |
div bl |
mov ch,ah |
and ax,0x00FF |
div bl |
shl ecx,8 |
mov cx,ax |
add ecx,'000' |
mov ax,[es:vi.VESAVersion] |
add ax,'00' |
push 0x1000 |
pop es |
mov [es:s_vesa.ver-0x10000], ah |
mov [es:s_vesa.ver+2-0x10000], al |
mov dword[es:s_vesa.mem-0x10000],ecx |
mov si,s_vesa-0x10000 |
call printplain |
if 0 ; mm |
_setcursor 5,2 |
mov si,_oem-0x10000 |
call printplain |
end if ; mm |
push 0 |
pop es |
mov si,word[es:vi.OemStringPtr] |
mov di,si |
push word[es:vi.OemStringPtr+2] |
pop es |
if 0 ; mm |
; mov al,0x0A |
pop es |
mov ax,es |
mov ds,ax |
call printplain |
pop es |
end if ; mm |
push 0x1000 |
pop ds |
mov si,s_ven_intel-0x10000 |
call substr |
mov al,1 |
je .vendor_ok |
mov si,s_ven_s3-0x10000 |
call substr |
mov al,2 |
je .vendor_ok |
mov al,3 |
.vendor_ok: |
push 0 0x1000 |
pop ds es |
mov [es:0x9035],al |
ret |
;----------------------------------------------------------------------------- |
calc_vmodes_table: |
push 0 0x1000 |
pop ds es |
;movzx eax,byte [es:preboot_graph-0x10000] |
;cmp eax,0 |
;jne pre_graph |
;_setcursor 9,2 |
;mov si,gr_mode-0x10000 |
;call printplain |
.enum_modes: |
pushad |
push 0x0000 |
pop es |
;mov si,s_mode1-0x10000 |
;call printplain |
mov si,word[es:vi.VideoModePtr] |
push word[es:vi.VideoModePtr+2] |
pop fs |
;pushw 1 |
mov bx,modes_table;-0x10000 |
.next_mode: |
mov cx,[fs:si] ; mode number |
cmp cx,-1 |
je .modes_ok.2 |
mov ax,$4F01 |
mov di,mi |
int $10 |
or ah,ah |
jnz .modes_ok.2;vesa_info.exit |
test [es:mi.ModeAttributes],00000001b |
jz @f |
test [es:mi.ModeAttributes],00010000b |
jz @f |
cmp [es:mi.BitsPerPixel],16 |
jne .l0 |
cmp [es:mi.GreenMaskSize],5 |
jne .l0 |
mov [es:mi.BitsPerPixel],15 |
.l0: |
cmp [es:mi.XRes],640 |
jb @f |
cmp [es:mi.YRes],480 |
jb @f |
cmp [es:mi.BitsPerPixel],15 |
jb @f |
mov ax,[es:mi.XRes] |
mov [es:bx+0],ax ; +0[2] : resolution X |
mov ax,[es:mi.YRes] |
mov [es:bx+2],ax ; +2[2] : resolution Y |
mov ax,[es:mi.ModeAttributes] |
mov [es:bx+4],ax ; +4[2] : attributes |
cmp [s_vesa.ver-0x10000],'2' |
jb .lp1 |
or cx,0x4000 ; use LFB |
.lp1: mov [es:bx+6],cx ; +6[2] : mode number |
mov al,[es:mi.BitsPerPixel] |
mov [es:bx+8],al ; +8[1] : bits per pixel |
add bx,10 |
@@: |
add si,2 |
jmp .next_mode |
.modes_ok.2: |
mov si,modes_table;-0x10000;m_info |
@@: add si,10 |
cmp si,bx |
jae @f |
mov ax,[es:si+0-10] |
cmp ax,[es:si+0] |
ja .xch |
jb @b |
mov ax,[es:si+2-10] |
cmp ax,[es:si+2] |
ja .xch |
jb @b |
mov al,[es:si+8-10] |
cmp al,[es:si+8] |
ja .xch |
jb @b |
pushad |
.del: push dword[es:si+0] dword[es:si+4] word[es:si+8] dword[es:si+0+10] dword[es:si+4+10] word[es:si+8+10] |
pop word[es:si+8] dword[es:si+4] dword[es:si+0] word[es:si+8+10] dword[es:si+4+10] dword[es:si+0+10] |
add si,10 |
cmp si,bx |
jb .del |
popad |
mov si,modes_table |
sub bx,10 |
jmp @b |
.xch: push dword[es:si+0] dword[es:si+4] word[es:si+8] dword[es:si+0-10] dword[es:si+4-10] word[es:si+8-10] |
pop word[es:si+8] dword[es:si+4] dword[es:si+0] word[es:si+8-10] dword[es:si+4-10] dword[es:si+0-10] |
mov si,modes_table;-0x10000;m_info |
jmp @b |
@@: |
push 0 |
pop es |
mov word[es:bx],-1 |
mov si,modes_table |
mov di,0x0AC00 |
pushw [es:si+2] [es:si+0] |
mov bp,sp |
mov [ds:ln_cnt],0 |
mov word[es:si-10],0 |
jmp .wr.2 |
@@: |
cmp word[es:si-10],-1 |
je @f |
mov ax,[es:si+0] |
cmp ax,[ss:bp+0] |
jne .wr |
mov ax,[es:si+2] |
cmp ax,[ss:bp+2] |
jne .wr |
.ww: mov al,[es:si+8] |
mov bx,4 |
cmp al,4 |
je .l1 |
add bx,4 |
cmp al,8 |
je .l1 |
add bx,4 |
cmp al,15 |
je .l1 |
add bx,4 |
cmp al,16 |
je .l1 |
add bx,4 |
cmp al,24 |
je .l1 |
add bx,4 |
.l1: mov eax,[es:si+4] ; mode attributes & number |
mov [es:di+bx],eax |
add si,10 |
jmp @b |
.wr: |
pushw [ss:bp+0] [ss:bp+2] |
popw [es:di+2] [es:di+0] |
add di,4+6*4 |
inc [ds:ln_cnt] |
pushw [es:si+0] [es:si+2] |
popw [ss:bp+2] [ss:bp+0] |
.wr.2: |
mov cx,(4+6*4)/2 |
xor ax,ax |
push di |
cld |
rep stosw |
pop di |
jmp .ww |
@@: add sp,4 |
popad |
ret |
;----------------------------------------------------------------------------- |
vm_bpp db 4,8,15,16,24,32 |
draw_current_vmode: |
push es ds 0 0x1000 |
pop es ds |
movzx ax,[es:vm_row] |
mov dx,4+6*4 |
mul dx |
mov si,ax |
add si,0x0AC00 |
mov di,0x0A000 |
movzx eax,word[si+0] |
mov ecx,10 |
call int2strnz |
mov byte[ds:di],'x' |
inc di |
movzx eax,word[si+2] |
call int2strnz |
mov byte[ds:di],'x' |
inc di |
movzx bx,[es:vm_col] |
movzx eax,[es:bx+vm_bpp] |
call int2strnz |
mov byte[ds:di],0 |
mov si,0x0A000 |
call printplain |
pop ds es |
ret |
;----------------------------------------------------------------------------- |
draw_vmodes_table: |
_setcursor 9,2 |
mov si,gr_mode-0x10000 |
call printplain |
;mov ah,9 |
;mov dx,_tl |
;int $21 |
mov si,_tl-0x10000 |
call printplain |
push 0 |
pop es |
movzx ax,[ds:ln_top] |
mov dx,4+6*4 |
mul dx |
mov si,ax |
add si,0x0AC00 |
mov eax,dword[ds:ln_top] |
mov dword[ds:ln_top2],eax ; top+num+cnt |
movzx cx,[ds:ln_num2] |
@@: push cx |
movzx eax,word[es:si+0] |
mov di,_rs-0x10000+2+14 |
mov ecx,10 |
mov bl,4 |
call int2str |
movzx eax,word[es:si+2] |
inc di |
mov bl,4 |
call int2str |
add si,4 |
add di,4 |
mov cx,6 |
.lp0: mov al,' ' |
cmp word[es:si],0 |
je .lp1 |
mov al,0xFB ; check |
.lp1: mov [ds:di],al |
add si,4 |
add di,6 |
loop .lp0 |
push si |
mov si,_rs-0x10000 |
call printplain |
pop si |
pop cx |
loop @b |
mov si,_bt-0x10000 |
call printplain |
ret |
;----------------------------------------------------------------------------- |
draw_vmodes_table_cursor: ; 9+5 |
mov al,[vm_row] |
sub al,[ln_top] |
add al,13 |
mov dh,al |
mov al,[vm_col] |
mov dl,6 |
mul dl |
add al,28 |
mov dl,al |
call setcursor |
mov si,_sel1-0x10000 |
mov [si],ch |
call printplain |
add dl,2 |
call setcursor |
mov si,_sel2-0x10000 |
mov [si],cl |
call printplain |
dec dl |
call setcursor |
ret |
;----------------------------------------------------------------------------- |
macro qwe |
{ |
pushad |
pushfd |
push es ds 0 0x1000 |
pop ds es |
mov si,badsect-2-0x10000 |
call printplain |
pop ds es |
popfd |
popad |
} |
set_vmode: |
push 0 0x1000 |
pop ds es |
movzx ax,[ds:vm_row] |
mov dx,4+6*4 |
mul dx |
add ax,0x0AC00 |
mov si,ax |
mov cx,[es:si+0] ; resolution X |
mov dx,[es:si+2] ; resolution Y |
movzx bx,[ds:vm_col] |
shl bx,2 |
mov bx,[es:si+4+bx+2] ; mode number |
; mov bx,0x4118 |
; mov cx,1024 |
; mov dx,768 |
; mov byte[es:0x9000],24 |
cmp bx,0x12 |
je .gml00 |
cmp bx,0x13 |
je .sgml1 |
movzx bp,[ds:vm_col] |
mov al,[ds:bp+vm_bpp] |
mov [es:0x9000],al |
jmp .gml10 |
.sgml1: |
mov [es:0x9000],byte 32 |
jmp .gml10 |
.gml00: |
mov [es:0x9000],byte 4 |
.gml10: |
mov [es:0x9008],bx |
mov [es:0x900A],cx |
mov [es:0x900C],dx |
mov al,[s_vesa.ver-0x10000] |
mov [es:0x9034],al |
; push 0x1000 |
; pop es |
mov [s_bpp.bpp-0x10000],'8 ' |
cmp bx,0x13 |
je .bppl;nov |
mov [s_bpp.bpp-0x10000],'4 ' |
cmp bx,0x12 |
je .bppl;nov |
; bx - mode : cx - x size : dx - y size |
; FIND VESA 2.0 LFB & BPP |
mov ax,0x4f01 |
mov cx,bx |
and cx,0xfff |
push 0x0000 |
pop es |
mov di,mi;0xa000 |
int 0x10 |
; LFB |
mov eax,[es:mi.PhysBasePtr];di+0x28] |
mov [es:0x9018],eax |
; BPP |
; cmp [es:mi.BitsPerPixel],16 |
; jne .l0 |
; cmp [es:mi.GreenMaskSize],5 |
; jne .l0 |
; mov [es:mi.BitsPerPixel],15 |
; .l0: mov al,[es:mi.BitsPerPixel];di+0x19] |
; mov [es:0x9000],al |
; ---- vbe voodoo |
BytesPerScanLine equ 0x10 |
push ax |
mov ax, [es:mi.BytesPerScanLine];di+BytesPerScanLine] |
mov [es:0x9001],ax |
pop ax |
; ----- |
.nov: |
mov al,[es:0x9000] |
cmp al,15 |
jnz .nbpp15 |
mov [s_bpp.bpp-0x10000],'15' |
jmp .bppl |
.nbpp15: |
cmp al,16 |
jnz .nbpp16 |
mov [s_bpp.bpp-0x10000],'16' |
jmp .bppl |
.nbpp16: |
cmp al,24 |
jnz .nbpp24 |
mov [s_bpp.bpp-0x10000],'24' |
jmp .bppl |
.nbpp24: |
cmp al,32 |
jnz .nbpp32 |
mov [s_bpp.bpp-0x10000],'32' |
jmp .bppl |
.nbpp32: |
mov [s_bpp.bpp-0x10000],'??' |
mov si,s_bpp-0x10000 |
call printplain |
jmp $ |
.bppl: |
mov si,s_bpp-0x10000 |
call printplain |
; FIND VESA 1.2 PM BANK SWITCH ADDRESS |
cmp [s_vesa.ver-0x10000],'2' |
jb @f |
mov ax,0x4f0A |
mov bx,0x0 |
int 0x10 |
xor eax,eax |
xor ebx,ebx |
mov ax,es |
shl eax,4 |
mov bx,di |
add eax,ebx |
movzx ebx,word[es:di] |
add eax,ebx |
push 0x0000 |
pop es |
mov [es:0x9014],eax |
jmp .lp1 |
@@: |
mov dword[es:0x9018],0x000A0000 |
.lp1: |
ret |
;============================================================================= |
;============================================================================= |
;============================================================================= |
; DISPLAY VESA INFORMATION |
vesa_info: |
macro sdfawgsgwaew { |
push 0 |
pop es |
mov [es:vi.VESASignature],'VBE2' |
mov ax,$4F00 |
mov di,vi |
int $10 |
or ah,ah |
jz @f |
mov [es:vi.VESASignature],'VESA' |
mov ax,$4F00 |
mov di,vi |
int $10 |
or ah,ah |
jnz .exit |
@@: |
cmp [es:vi.VESASignature],'VESA' |
jne .exit |
cmp [es:vi.VESAVersion],$0100 |
jb .exit |
jmp vesaok2 |
.exit: |
pushad |
push 0 |
pop es |
mov si,s_mode1-0x10000 |
call printplain |
; mov si,word[es:vi.VideoModePtr] |
; push word[es:vi.VideoModePtr+2] |
; pop fs |
pushw 'bb' |
jmp enum_modes.modes_ok |
; push 0x1000 |
; pop es |
; mov si,novesa-0x10000 |
; call print |
; mov ax,16 |
; jmp $;novesafound |
vesaok2: |
mov ecx,0x00200000 |
mov ax,[es:vi.TotalMemory] |
shr ax,4 |
mov bl,10 |
div bl |
mov ch,ah |
and ax,0x00FF |
div bl |
shl ecx,8 |
mov cx,ax |
add ecx,'000' |
mov ax,[es:vi.VESAVersion] |
add ax,'00' |
push 0x1000 |
pop es |
mov [es:s_vesa.ver-0x10000], ah |
mov [es:s_vesa.ver+2-0x10000], al |
mov dword[es:s_vesa.mem-0x10000],ecx |
mov si,s_vesa-0x10000 |
call print |
;// mike.dld, 2005-08-20 [ |
mov si,_oem-0x10000 |
call print |
push 0 |
pop es |
mov si,word[es:vi.OemStringPtr] |
mov di,si |
push word[es:vi.OemStringPtr+2] |
pop es |
mov al,0x0A |
push es |
call draw_text |
pop es |
push 0x1000 |
pop ds |
mov si,s_ven_intel-0x10000 |
call substr |
mov al,1 |
je vendor_ok |
mov si,s_ven_s3-0x10000 |
call substr |
mov al,2 |
je vendor_ok |
mov al,3 |
vendor_ok: |
push 0 0x1000 |
pop ds es |
mov [es:0x9035],al |
;// mike.dld, 2005-08-20 ] |
novesafound: |
;!! call setbase1000 |
; ASK GRAPHICS MODE |
movzx eax,byte [es:preboot_graph-0x10000] |
cmp eax,0 |
jne pre_graph |
mov si,gr_mode-0x10000 |
call printplain |
enum_modes: |
pushad |
push 0x0000 |
pop es |
mov si,s_mode1-0x10000 |
call printplain |
mov si,word[es:vi.VideoModePtr] |
push word[es:vi.VideoModePtr+2] |
pop fs |
pushw 1 |
mov bx,modes_table;-0x10000 |
.next_mode: |
mov cx,[fs:si] ; mode number |
cmp cx,-1 |
je .modes_ok.2 |
mov ax,$4F01 |
mov di,mi |
int $10 |
or ah,ah |
jnz .modes_ok.2;vesa_info.exit |
test [es:mi.ModeAttributes],00000001b |
jz @f |
test [es:mi.ModeAttributes],00010000b |
jz @f |
cmp [es:mi.BitsPerPixel],16 |
jne .l0 |
cmp [es:mi.GreenMaskSize],5 |
jne .l0 |
mov [es:mi.BitsPerPixel],15 |
.l0: |
cmp [es:mi.XRes],640 |
jb @f |
cmp [es:mi.YRes],480 |
jb @f |
cmp [es:mi.BitsPerPixel],15 |
jb @f |
mov ax,[es:mi.XRes] |
mov [es:bx+0],ax |
mov ax,[es:mi.YRes] |
mov [es:bx+2],ax |
mov ax,[es:mi.ModeAttributes] |
mov [es:bx+4],ax |
cmp [s_vesa.ver-0x10000],'2' |
jb .lp1 |
or cx,0x4000 ; use LFB |
.lp1: mov [es:bx+6],cx |
mov al,[es:mi.BitsPerPixel] |
mov [es:bx+8],al |
add bx,10 |
@@: |
add si,2 |
jmp .next_mode |
.modes_ok.2: |
mov si,modes_table;-0x10000;m_info |
@@: add si,10 |
cmp si,bx |
jae @f |
mov ax,[es:si+0-10] |
cmp ax,[es:si+0] |
ja .xch |
jb @b |
mov ax,[es:si+2-10] |
cmp ax,[es:si+2] |
ja .xch |
jb @b |
mov al,[es:si+8-10] |
cmp al,[es:si+8] |
ja .xch |
jb @b |
pushad |
.del: push dword[es:si+0] dword[es:si+4] word[es:si+8] dword[es:si+0+10] dword[es:si+4+10] word[es:si+8+10] |
pop word[es:si+8] dword[es:si+4] dword[es:si+0] word[es:si+8+10] dword[es:si+4+10] dword[es:si+0+10] |
add si,10 |
cmp si,bx |
jb .del |
popad |
mov si,modes_table |
sub bx,10 |
jmp @b |
.xch: push dword[es:si+0] dword[es:si+4] word[es:si+8] dword[es:si+0-10] dword[es:si+4-10] word[es:si+8-10] |
pop word[es:si+8] dword[es:si+4] dword[es:si+0] word[es:si+8-10] dword[es:si+4-10] dword[es:si+0-10] |
mov si,modes_table;-0x10000;m_info |
jmp @b |
@@: ;mov ah,9 |
;mov dx,_tl |
;int $21 |
mov si,_tl-0x10000 |
push bx |
call printplain |
pop bx |
push 0 |
pop es |
mov word[es:bx],-1 |
mov si,modes_table;-0x10000;m_info |
pushw [es:si+0] [es:si+2] 'c' |
mov bp,sp |
@@: |
cmp word[es:si-10],-1 |
je @f |
; cmp si,bx |
; jae @f |
mov ax,[es:si+0] |
cmp ax,[ss:bp+4] |
jne .wr |
mov ax,[es:si+2] |
cmp ax,[ss:bp+2] |
jne .wr |
.ww: push bx |
movzx eax,word[es:si+0] |
mov di,_rs-0x10000+2 |
mov ecx,10 |
mov bl,4 |
call int2str |
movzx eax,word[es:si+2] |
inc di |
mov bl,4 |
call int2str |
mov al,[es:si+8] |
mov di,_rs-0x10000+16 |
cmp al,4 |
je .l1 |
add di,5 |
cmp al,8 |
je .l1 |
add di,5 |
cmp al,15 |
je .l1 |
add di,5 |
cmp al,16 |
je .l1 |
add di,5 |
cmp al,24 |
je .l1 |
add di,5 |
.l1: mov al,[ss:bp] |
cmp byte[ds:di],'-' |
jne .lp0 |
mov [ds:di],al |
inc byte[ss:bp] |
jmp .lp2 |
.lp0: |
.lp2: |
pop bx |
add si,10 |
jmp @b;.sk |
.wr: ;mov ah,9 |
;mov dx,_rs |
;int $21 |
push bx si |
mov si,_rs-0x10000 |
call printplain |
pop si bx |
mov byte[ds:_rs-0x10000+16+5*0],'-' |
mov byte[ds:_rs-0x10000+16+5*1],'-' |
mov byte[ds:_rs-0x10000+16+5*2],'-' |
mov byte[ds:_rs-0x10000+16+5*3],'-' |
mov byte[ds:_rs-0x10000+16+5*4],'-' |
mov byte[ds:_rs-0x10000+16+5*5],'-' |
pushw [es:si+0] [es:si+2] |
popw [ss:bp+2] [ss:bp+4] |
.sk: |
jmp .ww;@b |
@@: ;add sp,6 |
pop bx |
add sp,6 |
sub bl,2 |
shl bx,8 |
push bx |
; mov ah,9 |
; mov dx,_bt |
; int $21 |
mov si,_bt-0x10000 |
call printplain |
.modes_ok: |
pop bx |
mov bp,sp |
mov [ss:bp+4*4],bx |
popad |
gml0: |
mov bl,'a' |
call getkey ; !! getchar |
pre_graph: |
or al,al |
jz gml00 |
cmp al,1 |
je sgml1 |
;shl ax,4 |
sub ax,2 |
mov si,10 |
mul si |
add ax,modes_table;-0x10000 |
mov si,ax |
mov bx,[es:si+6] |
mov cx,[es:si+0] |
mov dx,[es:si+2] |
jmp gml10 |
sgml1: |
; cmp al,9 |
; jnz gml00 |
mov bx,0x13 |
mov cx,640 |
mov dx,480 |
push 0x0 |
pop es |
mov [es:0x9000],byte 32 |
; push 0x1000 |
; pop es |
jmp gml10 |
gml00: |
; cmp al,0xa |
; jnz gml02 |
mov bx,0x12 |
mov cx,640 |
mov dx,480 |
push 0x0 |
pop es |
mov [es:0x9000],byte 4;32 |
gml10: |
push 0x0000 |
pop es |
mov [es:0x9008],bx |
mov [es:0x900A],cx |
mov [es:0x900C],dx |
mov al,[s_vesa.ver-0x10000] |
mov [es:0x9034],al |
push 0x1000 |
pop es |
mov [s_bpp.bpp-0x10000],'8 ' |
cmp bx,0x13 |
je .bppl;nov |
mov [s_bpp.bpp-0x10000],'4 ' |
cmp bx,0x12 |
je .bppl;nov |
; bx - mode : cx - x size : dx - y size |
; FIND VESA 2.0 LFB & BPP |
mov ax,0x4f01 |
mov cx,bx |
and cx,0xfff |
push 0x0000 |
pop es |
mov di,mi;0xa000 |
int 0x10 |
; LFB |
mov eax,[es:mi.PhysBasePtr];di+0x28] |
mov [es:0x9018],eax |
; BPP |
cmp [es:mi.BitsPerPixel],16 |
jne .l0 |
cmp [es:mi.GreenMaskSize],5 |
jne .l0 |
mov [es:mi.BitsPerPixel],15 |
.l0: mov al,[es:mi.BitsPerPixel];di+0x19] |
mov [es:0x9000],al |
; ---- vbe voodoo |
BytesPerScanLine equ 0x10 |
push ax |
mov ax, [es:mi.BytesPerScanLine];di+BytesPerScanLine] |
mov [es:0x9001],ax |
pop ax |
; ----- |
.nov: |
cmp al,15 |
jnz .nbpp15 |
mov [s_bpp.bpp-0x10000],'15' |
jmp .bppl |
.nbpp15: |
cmp al,16 |
jnz .nbpp16 |
mov [s_bpp.bpp-0x10000],'16' |
jmp .bppl |
.nbpp16: |
cmp al,24 |
jnz .nbpp24 |
mov [s_bpp.bpp-0x10000],'24' |
jmp .bppl |
.nbpp24: |
cmp al,32 |
jnz .nbpp32 |
mov [s_bpp.bpp-0x10000],'32' |
jmp .bppl |
.nbpp32: |
mov [s_bpp.bpp-0x10000],'??' |
call print |
jmp $ |
.bppl: |
mov si,s_bpp-0x10000 |
call printplain |
; FIND VESA 1.2 PM BANK SWITCH ADDRESS |
cmp [s_vesa.ver-0x10000],'2' |
jb @f |
mov ax,0x4f0A |
mov bx,0x0 |
int 0x10 |
xor eax,eax |
xor ebx,ebx |
mov ax,es |
shl eax,4 |
mov bx,di |
add eax,ebx |
movzx ebx,word[es:di] |
add eax,ebx |
push 0x0000 |
pop es |
mov [es:0x9014],eax |
jmp .lp1 |
@@: |
mov dword[es:0x9018],0x000A0000 |
.lp1: |
push 0x1000 |
pop es |
} |
/kernel/branches/gfx_kernel/boot/drawtext.inc |
---|
0,0 → 1,44 |
substr: |
push si di cx |
movzx cx,byte[ds:si-1] |
@@: mov al,[ds:si] |
cmp al,[es:di] |
jne @f |
inc si |
inc di |
dec cx |
jnz @b |
; cld |
; repe cmps byte[ds:si],[es:di] |
@@: pop cx di si |
ret |
int2str: |
dec bl |
jz @f |
xor edx,edx |
div ecx |
push edx |
call int2str |
pop eax |
@@: cmp al,10 |
sbb al,$69 |
das |
mov [ds:di],al |
inc di |
ret |
int2strnz: |
cmp eax,ecx |
jb @f |
xor edx,edx |
div ecx |
push edx |
call int2strnz |
pop eax |
@@: cmp al,10 |
sbb al,$69 |
das |
mov [ds:di],al |
inc di |
ret |
/kernel/branches/gfx_kernel/boot/preboot.inc |
---|
0,0 → 1,26 |
display_modechg db 0 ; display mode change for text, yes/no (0 or 2) |
; |
; !! Important note !! |
; |
; Must be set to 2, to avoid two screenmode |
; changes within a very short period of time. |
display_atboot db 0 ; show boot screen messages ( 2-no ) |
preboot_graph db 0 ; graph mode |
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes) |
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no) |
;;preboot_mouse db 0 ; mouse port (1-PS2, 2-COM1, 3-COM2) |
preboot_mtrr db 0 ; mtrr acceleration (1-yes, 2-no) |
preboot_device db 0 ; boot device |
; (1-floppy 2-harddisk 3-kernel restart) |
;;preboot_memory db 0 ; amount of memory |
; (1-16Mb;2-32Mb;3-64Mb;4-128Mb;5-256Mb) |
; !!!! 0 - autodetect !!!! |
preboot_blogesc db 1 ; start immediately after bootlog |
if $>10200h |
ERROR: prebooting parameters must fit in first sector!!! |
end if |
hdsysimage db 'MENUET IMG' ; load from |
image_save db 'MENUET IMG' ; save to |
/kernel/branches/gfx_kernel/boot/rdload.inc |
---|
0,0 → 1,95 |
; READ RAMDISK IMAGE FROM HD |
cmp [boot_dev],1 |
jne no_sys_on_hd |
test [0x40001],byte 0x40 |
jz position_2 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
mov [fat32part],0 |
position_1_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [0x40002] |
cmp [fat32part],eax |
jle position_1_1 |
position_2: |
test [0x40001],byte 0x10 |
jz position_3 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
mov [fat32part],0 |
position_2_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [0x40003] |
cmp eax,[fat32part] |
jle position_2_1 |
position_3: |
test [0x40001],byte 0x4 |
jz position_4 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
mov [fat32part],0 |
position_3_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [0x40004] |
cmp eax,[fat32part] |
jle position_3_1 |
position_4: |
test [0x40001],byte 0x1 |
jz no_sys_on_hd |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
mov [fat32part],0 |
position_4_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [0x40005] |
cmp eax,[fat32part] |
jle position_4_1 |
jmp yes_sys_on_hd |
search_and_read_image: |
; mov [0xfe10],dword 0 ; entries in hd cache |
call set_FAT32_variables |
mov edx, bootpath |
call read_image |
test eax, eax |
jz image_present |
mov edx, bootpath2 |
call read_image |
test eax, eax |
jz image_present |
ret |
image_present: |
mov [image_retrieved],1 |
ret |
read_image: |
mov eax, hdsysimage |
mov ebx, 1474560/512 |
mov ecx, 0x100000 |
mov esi, 0 |
mov edi, 12 |
call file_read |
ret |
image_retrieved db 0 |
counter_of_partitions db 0 |
no_sys_on_hd: |
yes_sys_on_hd: |
/kernel/branches/gfx_kernel/boot/ru.inc |
---|
0,0 → 1,92 |
; Generated by RUFNT.EXE |
; By BadBugsKiller (C) |
; Modifyed by BadBugsKiller 12.01.2004 17:45 |
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé, |
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà. |
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòàíèöà 866. |
RU_FNT1: |
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
RU_FNT2: |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 |
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 |
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
/kernel/branches/gfx_kernel/boot/shutdown.inc |
---|
0,0 → 1,521 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Shutdown for Menuet |
;; |
;; Distributed under General Public License |
;; See file COPYING for details. |
;; Copyright 2003 Ville Turjanmaa |
;; |
system_shutdown: ; shut down the system |
push 3 ; stop playing cd |
pop eax |
call sys_cd_audio |
cld |
mov al,[0x2f0000+0x9030] |
cmp al,1 |
jl no_shutdown_parameter |
cmp al,4 |
jle yes_shutdown_param |
no_shutdown_parameter: |
; movzx ecx,word [0x2f0000+0x900A] |
; movzx esi,word [0x2f0000+0x900C] |
; imul ecx,esi ;[0xfe04] |
;; mov ecx,0x500000/4 ;3fff00/4 ; darken screen |
; push ecx |
; mov esi,[0xfe80] |
; cmp esi,32*0x100000 |
; jbe no_darken_screen |
; mov edi,16*0x100000 |
; push esi edi |
; sdnewpix: |
; lodsd |
; shr eax,1 |
; and eax,0x7f7f7f7f |
; stosd |
; loop sdnewpix |
; pop ecx |
; pop esi edi |
; rep movsd |
; no_darken_screen: |
; read shutdown code: |
; 1) display shutdown "window" |
mov eax,[0xfe00] |
shr eax,1 |
lea esi,[eax+220] ; x end |
sub eax,220 ; x start |
mov ebx,[0xfe04] |
shr ebx,1 |
mov [shutdownpos],ebx |
lea ebp,[ebx+105] ; y end |
sub ebx,120 ; y start |
xor edi,edi |
inc edi ; force putpixel & dtext |
mov ecx,0x0000ff |
; vertical loop begin |
sdnewpix1: |
push eax ; save x start |
; horizontal loop begin |
sdnewpix2: |
call [putpixel] |
inc eax |
cmp eax,esi |
jnz sdnewpix2 |
; horizontal loop end |
dec ecx ; color |
pop eax ; restore x start |
inc ebx ; advance y pos |
cmp ebx,ebp |
jnz sdnewpix1 |
; vertical loop end |
; 2) display text strings |
; a) version |
mov eax,[0xfe00] |
shr eax,1 |
shl eax,16 |
mov ax,word [shutdownpos] |
push eax |
sub eax,(220-27)*10000h + 105 |
mov ebx,0xffff00 |
mov ecx,version |
push 34 |
pop edx |
call dtext |
; b) variants |
add eax,105+33 |
push 6 |
pop esi |
; mov ebx,0xffffff |
mov bl,0xFF |
mov ecx,shutdowntext |
mov dl,40 |
newsdt: |
call dtext |
add eax,10 |
add ecx,edx |
dec esi |
jnz newsdt |
; 3) load & display rose.txt |
mov eax,rosef ; load rose.txt |
xor ebx,ebx |
push 2 |
pop ecx |
mov edx,0x90000 |
push edx |
push 12 |
pop esi |
push edi ; may be destroyed |
call fileread |
pop edi |
pop ecx |
inc ecx ; do not display stars from rose.txt |
pop eax |
add eax,20*10000h - 110 |
mov ebx,0x00ff00 |
push 27 |
pop edx |
nrl: |
call dtext |
sub ebx,0x050000 |
add eax,8 |
add ecx,31 |
cmp cx,word 0x0001+25*31 |
jnz nrl |
call checkVga_N13 |
yes_shutdown_param: |
cli |
mov eax,kernel ; load kernel.mnt to 0x8000:0 |
push 12 |
pop esi |
xor ebx,ebx |
or ecx,-1 |
mov edx,0x80000 |
call fileread |
mov esi,restart_kernel_4000+0x10000 ; move kernel re-starter to 0x4000:0 |
mov edi,0x40000 |
mov ecx,1000 |
rep movsb |
mov eax,0x2F0000 ; restore 0x0 - 0xffff |
xor ebx,ebx |
mov ecx,0x10000 |
call memmove |
call restorefatchain |
mov word [0x467+0],pr_mode_exit-0x10000 |
mov word [0x467+2],0x1000 |
mov al,0x0F |
out 0x70,al |
mov al,0x05 |
out 0x71,al |
mov al,0xFE |
out 0x64,al |
hlt |
use16 |
pr_mode_exit: |
org $-0x10000 |
; setup stack |
mov ax, 3000h |
mov ss, ax |
mov esp, 0EC00h |
; setup ds |
push cs |
pop ds |
lidt [old_ints_h-0x10000] |
;remap IRQs |
mov al,0x11 |
out 0x20,al |
call rdelay |
out 0xA0,al |
call rdelay |
mov al,0x08 |
out 0x21,al |
call rdelay |
mov al,0x70 |
out 0xA1,al |
call rdelay |
mov al,0x04 |
out 0x21,al |
call rdelay |
mov al,0x02 |
out 0xA1,al |
call rdelay |
mov al,0x01 |
out 0x21,al |
call rdelay |
out 0xA1,al |
call rdelay |
mov al,0 |
out 0x21,al |
call rdelay |
out 0xA1,al |
sti |
temp_3456: |
xor ax,ax |
mov es,ax |
mov al,byte [es:0x9030] |
cmp al,1 |
jl nbw |
cmp al,4 |
jle nbw32 |
nbw: |
in al,0x60 |
call pause_key |
cmp al,6 |
jae nbw |
mov bl,al |
nbw2: |
in al,0x60 |
call pause_key |
cmp al,bl |
je nbw2 |
cmp al,240 ;ax,240 |
jne nbw31 |
mov al,bl |
dec ax |
jmp nbw32 |
nbw31: |
add bl,128 |
cmp al,bl |
jne nbw |
sub al,129 |
nbw32: |
dec ax ; 1 = write floppy |
js nbw |
jnz no_floppy_write |
call floppy_write |
jmp temp_3456 ;nbw |
no_floppy_write: |
dec ax ; 2 = power off |
jnz no_apm_off |
call APM_PowerOff |
jmp $ |
no_apm_off: |
dec ax ; 3 = reboot |
jnz restart_kernel ; 4 = restart kernel |
push 0x40 |
pop ds |
mov word[0x0072],0x1234 |
jmp 0xF000:0xFFF0 |
pause_key: |
mov cx,100 |
pause_key_1: |
loop pause_key_1 |
ret |
org $+0x10000 |
old_ints_h: |
dw 0x400 |
dd 0 |
dw 0 |
org $-0x10000 |
rdelay: |
ret |
iglobal |
kernel db 'KERNEL MNT' |
; shutdown_parameter db 0 |
endg |
restart_kernel: |
mov ax,0x0003 ; set text mode for screen |
int 0x10 |
jmp 0x4000:0000 |
restart_kernel_4000: |
cli |
; mov di,0x1000 ; load kernel image from 0x8000:0 -> 0x1000:0 |
; |
; new_kernel_block_move: |
; |
; mov ebx,0 |
; |
; new_kernel_byte_move: |
; |
; mov ax,di |
; add ax,0x7000 |
; mov es,ax |
; mov dl,[es:bx] |
; mov es,di |
; mov [es:bx],dl |
; |
; inc ebx |
; cmp ebx,65536 |
; jbe new_kernel_byte_move |
; |
; add di,0x1000 |
; cmp di,0x2000 |
; jbe new_kernel_block_move |
push ds |
pop es |
mov cx, 0x8000 |
push cx |
mov ds, cx |
xor si, si |
xor di, di |
rep movsw |
push 0x9000 |
pop ds |
push 0x2000 |
pop es |
pop cx |
rep movsw |
wbinvd ; write and invalidate cache |
; mov ax,0x1000 |
; mov es,ax |
; mov ax,0x3000 |
; mov ss,ax |
; mov sp,0xec00 |
; restore timer |
mov al, 00110100b |
out 43h, al |
jcxz $+2 |
mov al, 0xFF |
out 40h, al |
jcxz $+2 |
out 40h, al |
jcxz $+2 |
sti |
; bootloader interface |
push 0x1000 |
pop ds |
mov si, .bootloader_block;-0x10000 |
mov ax, 'KL' |
jmp 0x1000:0000 |
.bootloader_block: |
db 1 ; version |
dw 1 ; floppy image is in memory |
dd 0 ; cannot save parameters |
APM_PowerOff: |
mov ax, 5304h |
xor bx, bx |
int 15h |
;!!!!!!!!!!!!!!!!!!!!!!!! |
mov ax,0x5300 |
xor bx,bx |
int 0x15 |
push ax |
mov ax,0x5301 |
xor bx,bx |
int 0x15 |
mov ax,0x5308 |
mov bx,1 |
mov cx,bx |
int 0x15 |
mov ax,0x530E |
xor bx,bx |
pop cx |
int 0x15 |
mov ax,0x530D |
mov bx,1 |
mov cx,bx |
int 0x15 |
mov ax,0x530F |
mov bx,1 |
mov cx,bx |
int 0x15 |
mov ax,0x5307 |
mov bx,1 |
mov cx,3 |
int 0x15 |
;!!!!!!!!!!!!!!!!!!!!!!!! |
fwwritedone: |
ret |
org $+0x10000 |
flm db 0 |
org $-0x10000 |
floppy_write: ; write diskette image to physical floppy |
cmp [flm-0x10000],byte 1 |
je fwwritedone |
mov [flm-0x10000],byte 1 |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov cx,0x0001 ; startcyl,startsector |
; mov dx,0x0000 ; starthead,drive |
xor dx, dx |
mov ax, 80*2 ; read no of sect |
fwwrites: |
push ax |
; move 1mb+ -> 0:a000 |
pusha |
mov si,fwmovedesc -0x10000 |
mov cx,256*18 |
mov ah,0x87 |
push ds |
pop es |
int 0x15 |
add dword [fwmovedesc-0x10000+0x12], 512*18 |
popa |
xor si,si |
mov es,si |
fwnewwrite: |
mov bx,0xa000 ; es:bx -> data area |
mov ax,0x0300+18 ; read, no of sectors to read |
int 0x13 |
test ah, ah |
jz fwgoodwrite |
inc si |
cmp si,10 |
jnz fwnewwrite |
; can't access diskette - return |
pop ax |
ret |
fwgoodwrite: |
inc dh |
cmp dh,2 |
jnz fwbb2 |
mov dh,0 |
inc ch |
fwbb2: |
pop ax |
dec ax |
jnz fwwrites |
ret |
org $+0x10000 |
fwmovedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
org $-0x10000 |
use32 |
org $+0x10000 |
uglobal |
shutdownpos dd 0x0 |
endg |
iglobal |
if lang eq en |
shutdowntext: |
db "IT'S SAFE TO POWER OFF COMPUTER OR " |
db ' ' |
db '1) SAVE RAMDISK TO FLOPPY ' |
db '2) APM - POWEROFF ' |
db '3) REBOOT ' |
db '4) RESTART KERNEL ' |
else |
shutdowntext: |
db "¥§®¯ ᮥ ¢ëª«î票¥ ª®¬¯ìîâ¥à ¨«¨ " |
db ' ' |
db '1) ®åà ¨âì à ¬¤¨áª ¤¨áª¥âã ' |
db '2) APM - ¢ëª«î票¥ ¯¨â ¨ï ' |
db '3) ¥à¥§ £à㧪 á¨á⥬ë ' |
db '4) ¥áâ àâ ï¤à ¨§ ' |
end if |
rosef: |
db 'ROSE TXT' |
endg |
/kernel/branches/gfx_kernel/build_en.bat |
---|
0,0 → 1,4 |
@erase lang.inc |
@echo lang fix en >lang.inc |
@fasm kernel.asm kernel.mnt |
@pause |
/kernel/branches/gfx_kernel/build_ru.bat |
---|
0,0 → 1,4 |
@erase lang.inc |
@echo lang fix ru >lang.inc |
@fasm kernel.asm kernel.mnt |
@pause |
/kernel/branches/gfx_kernel/bus/pci/pci16.inc |
---|
0,0 → 1,46 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; PCI16.INC ;; |
;; ;; |
;; 16 bit PCI driver code ;; |
;; ;; |
;; Version 0.2 December 21st, 2002 ;; |
;; ;; |
;; Author: Victor Prodan, victorprodan@yahoo.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
init_pci_16: |
pushad |
xor ax,ax |
mov es,ax |
mov byte [es:0x9020],1 ;default mechanism:1 |
mov ax,0xb101 |
int 0x1a |
or ah,ah |
jnz pci16skip |
mov [es:0x9021],cl ;last PCI bus in system |
mov [es:0x9022],bx |
mov [es:0x9024],edi |
; we have a PCI BIOS, so check which configuration mechanism(s) |
; it supports |
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2) |
test al,1 |
jnz pci16skip |
test al,2 |
jz pci16skip |
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2 |
pci16skip: |
mov ax,0x1000 |
mov es,ax |
popad |
/kernel/branches/gfx_kernel/bus/pci/pci32.inc |
---|
0,0 → 1,358 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; PCI32.INC ;; |
;; ;; |
;; 32 bit PCI driver code ;; |
;; ;; |
;; Version 0.2 December 21st, 2002 ;; |
;; ;; |
;; Author: Victor Prodan, victorprodan@yahoo.com ;; |
;; Credits: ;; |
;; Ralf Brown ;; |
;; Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;*************************************************************************** |
; Function |
; pci_api: |
; |
; Description |
; entry point for system PCI calls |
;*************************************************************************** |
align 4 |
pci_api: |
cmp [pci_access_enabled],1 |
jne no_pci_access_for_applications |
or al,al |
jnz pci_fn_1 |
; PCI function 0: get pci version (AH.AL) |
movzx eax,word [0x2F0000+0x9022] |
ret |
pci_fn_1: |
cmp al,1 |
jnz pci_fn_2 |
; PCI function 1: get last bus in AL |
mov al,[0x2F0000+0x9021] |
ret |
pci_fn_2: |
cmp al,2 |
jne pci_fn_3 |
; PCI function 2: get pci access mechanism |
mov al,[0x2F0000+0x9020] |
ret |
pci_fn_3: |
cmp al,4 |
jz pci_read_reg ;byte |
cmp al,5 |
jz pci_read_reg ;word |
cmp al,6 |
jz pci_read_reg ;dword |
cmp al,8 |
jz pci_write_reg ;byte |
cmp al,9 |
jz pci_write_reg ;word |
cmp al,10 |
jz pci_write_reg ;dword |
no_pci_access_for_applications: |
mov eax,-1 |
ret |
;*************************************************************************** |
; Function |
; pci_make_config_cmd |
; |
; Description |
; creates a command dword for use with the PCI bus |
; bus # in ah |
; device+func in bh (dddddfff) |
; register in bl |
; |
; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 ) |
;*************************************************************************** |
align 4 |
pci_make_config_cmd: |
shl eax,8 ; move bus to bits 16-23 |
mov ax,bx ; combine all |
and eax,0xffffff |
or eax,0x80000000 |
ret |
;*************************************************************************** |
; Function |
; pci_read_reg: |
; |
; Description |
; read a register from the PCI config space into EAX/AX/AL |
; IN: ah=bus,device+func=bh,register address=bl |
; number of bytes to read (1,2,4) coded into AL, bits 0-1 |
;*************************************************************************** |
align 4 |
pci_read_reg: |
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use? |
je pci_read_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; get requested DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl ; add to port address first 2 bits of register address |
or esi,esi |
jz pci_read_byte1 |
cmp esi,1 |
jz pci_read_word1 |
cmp esi,2 |
jz pci_read_dword1 |
jmp pci_fin_read1 |
pci_read_byte1: |
in al,dx |
jmp pci_fin_read1 |
pci_read_word1: |
in ax,dx |
jmp pci_fin_read1 |
pci_read_dword1: |
in eax,dx |
jmp pci_fin_read1 |
pci_fin_read1: |
; restore configuration control |
xchg eax,[esp] |
mov dx,0xcf8 |
out dx,eax |
pop eax |
pop esi |
ret |
pci_read_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_read_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
or esi,esi |
jz pci_read_byte2 |
cmp esi,1 |
jz pci_read_word2 |
cmp esi,2 |
jz pci_read_dword2 |
jmp pci_fin_read2 |
pci_read_byte2: |
in al,dx |
jmp pci_fin_read2 |
pci_read_word2: |
in ax,dx |
jmp pci_fin_read2 |
pci_read_dword2: |
in eax,dx |
; jmp pci_fin_read2 |
pci_fin_read2: |
; restore configuration space |
xchg eax,[esp] |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
pop eax |
pop esi |
ret |
pci_read_reg_err: |
xor eax,eax |
dec eax |
ret |
;*************************************************************************** |
; Function |
; pci_write_reg: |
; |
; Description |
; write a register from ECX/CX/CL into the PCI config space |
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, |
; value to write in ecx |
; number of bytes to write (1,2,4) coded into AL, bits 0-1 |
;*************************************************************************** |
align 4 |
pci_write_reg: |
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use? |
je pci_write_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state into ecx |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; write DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl |
mov eax,ecx |
or esi,esi |
jz pci_write_byte1 |
cmp esi,1 |
jz pci_write_word1 |
cmp esi,2 |
jz pci_write_dword1 |
jmp pci_fin_write1 |
pci_write_byte1: |
out dx,al |
jmp pci_fin_write1 |
pci_write_word1: |
out dx,ax |
jmp pci_fin_write1 |
pci_write_dword1: |
out dx,eax |
jmp pci_fin_write1 |
pci_fin_write1: |
; restore configuration control |
pop eax |
mov dl,0xf8 |
out dx,eax |
xor eax,eax |
pop esi |
ret |
pci_write_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_write_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
; write register |
mov eax,ecx |
or esi,esi |
jz pci_write_byte2 |
cmp esi,1 |
jz pci_write_word2 |
cmp esi,2 |
jz pci_write_dword2 |
jmp pci_fin_write2 |
pci_write_byte2: |
out dx,al |
jmp pci_fin_write2 |
pci_write_word2: |
out dx,ax |
jmp pci_fin_write2 |
pci_write_dword2: |
out dx,eax |
jmp pci_fin_write2 |
pci_fin_write2: |
; restore configuration space |
pop eax |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
xor eax,eax |
pop esi |
ret |
pci_write_reg_err: |
xor eax,eax |
dec eax |
ret |
/kernel/branches/gfx_kernel/core/debug.inc |
---|
0,0 → 1,499 |
; diamond, 2006 |
sys_debug_services: |
cmp eax, 9 |
ja @f |
jmp dword [sys_debug_services_table+eax*4] |
@@: ret |
sys_debug_services_table: |
dd debug_set_event_data |
dd debug_getcontext |
dd debug_setcontext |
dd debug_detach |
dd debug_suspend |
dd debug_resume |
dd debug_read_process_memory |
dd debug_write_process_memory |
dd debug_terminate |
dd debug_set_drx |
debug_set_event_data: |
; in: ebx = pointer |
; destroys eax |
mov eax, [0x3000] |
shl eax, 8 |
mov [eax+0x80000+APPDATA.dbg_event_mem], ebx |
ret |
get_debuggee_slot: |
; in: ebx=PID |
; out: CF=1 if error |
; CF=0 and eax=slot*0x20 if ok |
; out: interrupts disabled |
cli |
mov eax, ebx |
call pid_to_slot |
test eax, eax |
jz .ret_bad |
shl eax, 5 |
push ebx |
mov ebx, [0x3000] |
cmp [0x80000+eax*8+APPDATA.debugger_slot], ebx |
pop ebx |
jnz .ret_bad |
; clc ; automatically |
ret |
.ret_bad: |
stc |
ret |
debug_detach: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
and dword [eax*8+0x80000+APPDATA.debugger_slot], 0 |
call do_resume |
.ret: |
sti |
ret |
debug_terminate: |
; in: ebx=pid |
call get_debuggee_slot |
jc debug_detach.ret |
mov ebx, eax |
shr ebx, 5 |
push 2 |
pop eax |
jmp sys_system |
debug_suspend: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
mov bl, [0x3000+eax+TASKDATA.state] ; process state |
test bl, bl |
jz .1 |
cmp bl, 5 |
jnz .ret |
mov bl, 2 |
.2: mov [0x3000+eax+TASKDATA.state], bl |
.ret: |
sti |
ret |
.1: |
inc ebx |
jmp .2 |
do_resume: |
mov bl, [0x3000+eax+TASKDATA.state] |
cmp bl, 1 |
jz .1 |
cmp bl, 2 |
jnz .ret |
mov bl, 5 |
.2: mov [0x3000+eax+TASKDATA.state], bl |
.ret: ret |
.1: dec ebx |
jmp .2 |
debug_resume: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
call do_resume |
.ret: sti |
ret |
debug_getcontext: |
; in: |
; ebx=pid |
; ecx=sizeof(CONTEXT) |
; edx->CONTEXT |
; destroys eax,ecx,edx,esi,edi |
cmp ecx, 28h |
jnz .ret |
add edx, std_application_base_address |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .ret |
imul eax, tss_step/32 |
add eax, tss_data |
mov edi, edx |
cmp [l.cs - tss_sceleton + eax], app_code |
jnz .ring0 |
lea esi, [l.eip - tss_sceleton + eax] |
shr ecx, 2 |
rep movsd |
jmp .ret |
.ring0: |
; note that following code assumes that all interrupt/exception handlers |
; saves ring-3 context by push ds es, pushad in this order |
mov esi, [l.esp0 - tss_sceleton + eax] |
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad |
sub esi, 8+12+8+20h |
lodsd |
mov [edi+24h], eax |
lodsd |
mov [edi+20h], eax |
lodsd |
mov [edi+1Ch], eax |
lodsd |
lodsd |
mov [edi+14h], eax |
lodsd |
mov [edi+10h], eax |
lodsd |
mov [edi+0Ch], eax |
lodsd |
mov [edi+8], eax |
add esi, 8 |
lodsd |
mov [edi], eax |
lodsd |
lodsd |
mov [edi+4], eax |
lodsd |
mov [edi+18h], eax |
.ret: |
sti |
ret |
debug_setcontext: |
; in: |
; ebx=pid |
; ecx=sizeof(CONTEXT) |
; edx->CONTEXT |
; destroys eax,ecx,edx,esi,edi |
cmp ecx, 28h |
jnz .ret |
add edx, std_application_base_address |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .stiret |
imul eax, tss_step/32 |
add eax, tss_data |
mov esi, edx |
cmp [l.cs - tss_sceleton + eax], app_code |
jnz .ring0 |
lea edi, [l.eip - tss_sceleton + eax] |
shr ecx, 2 |
rep movsd |
jmp .stiret |
.ring0: |
mov edi, [l.esp0 - tss_sceleton + eax] |
sub edi, 8+12+8+20h |
mov eax, [esi+24h] |
stosd |
mov eax, [esi+20h] |
stosd |
mov eax, [esi+1Ch] |
stosd |
scasd |
mov eax, [esi+14h] |
stosd |
mov eax, [esi+10h] |
stosd |
mov eax, [esi+0Ch] |
stosd |
mov eax, [esi+8] |
stosd |
add edi, 8 |
mov eax, [esi] |
stosd |
scasd |
mov eax, [esi+4] |
stosd |
mov eax, [esi+18h] |
stosd |
.stiret: |
sti |
.ret: |
ret |
debug_set_drx: |
call get_debuggee_slot |
jc .errret |
mov ebp, eax |
lea eax, [eax*8+0x80000+APPDATA.dbg_regs] |
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 |
; [eax+10]=dr7 |
add edx, std_application_base_address |
jc .errret |
cmp cl, 3 |
ja .errret |
mov ebx, dr7 |
shr ebx, cl |
shr ebx, cl |
test ebx, 2 ; bit 1+2*index = G0..G3, global break enable |
jnz .errret2 |
test ch, ch |
jns .new |
; clear breakpoint |
movzx ecx, cl |
add ecx, ecx |
and dword [eax+ecx*2], 0 ; clear DR<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 + l.trap - tss_sceleton], not 1 |
.okret: |
and dword [esp+36], 0 |
sti |
ret |
.errret: |
sti |
mov dword [esp+36], 1 |
ret |
.errret2: |
sti |
mov dword [esp+36], 2 |
ret |
.new: |
; add new breakpoint |
; cl=index; ch=flags; edx=address |
test ch, 0xF0 |
jnz .errret |
mov bl, ch |
and bl, 3 |
cmp bl, 2 |
jz .errret |
mov bl, ch |
shr bl, 2 |
cmp bl, 2 |
jz .errret |
test dl, bl |
jnz .errret |
or byte [eax+10h+1], 3 ; set GE and LE flags |
movzx ebx, ch |
movzx ecx, cl |
add ecx, ecx |
bts dword [eax+10h], ecx ; set L<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 + l.trap - tss_sceleton], 1 |
jmp .okret |
debug_read_process_memory: |
; in: |
; ebx=pid |
; ecx=length |
; esi->buffer in debugger |
; edx=address in debuggee |
; out: [esp+36]=sizeof(read) |
; destroys all |
add esi, std_application_base_address |
push ebx |
mov ebx, esi |
call check_region |
pop ebx |
dec eax |
jnz .err |
call get_debuggee_slot |
jc .err |
shr eax, 5 |
mov ebx, esi |
call read_process_memory |
sti |
mov dword [esp+36], eax |
ret |
.err: |
or dword [esp+36], -1 |
ret |
debug_write_process_memory: |
; in: |
; ebx=pid |
; ecx=length |
; esi->buffer in debugger |
; edx=address in debuggee |
; out: [esp+36]=sizeof(write) |
; destroys all |
add esi, std_application_base_address |
push ebx |
mov ebx, esi |
call check_region |
pop ebx |
dec eax |
jnz debug_read_process_memory.err |
call get_debuggee_slot |
jc debug_read_process_memory.err |
shr eax, 5 |
mov ebx, esi |
call write_process_memory |
sti |
mov [esp+36], eax |
ret |
debugger_notify: |
; in: eax=debugger slot |
; ecx=size of debug message |
; [esp+4]..[esp+4+ecx]=message |
; interrupts must be disabled! |
; destroys all general registers |
; interrupts remain disabled |
xchg ebp, eax |
mov edi, [timer_ticks] |
add edi, 500 ; 5 sec timeout |
.1: |
mov eax, ebp |
shl eax, 8 |
mov edx, [0x80000+eax+APPDATA.dbg_event_mem] |
test edx, edx |
jz .ret |
; read buffer header |
push ecx |
push eax |
push eax |
mov eax, ebp |
mov ebx, esp |
mov ecx, 8 |
call read_process_memory |
cmp eax, ecx |
jz @f |
add esp, 12 |
jmp .ret |
@@: |
cmp dword [ebx], 0 |
jg @f |
.2: |
pop ecx |
pop ecx |
pop ecx |
cmp dword [0x3000], 1 |
jnz .notos |
cmp [timer_ticks], edi |
jae .ret |
.notos: |
sti |
call change_task |
cli |
jmp .1 |
@@: |
mov ecx, [ebx+8] |
add ecx, [ebx+4] |
cmp ecx, [ebx] |
ja .2 |
; advance buffer position |
push ecx |
mov ecx, 4 |
sub ebx, ecx |
mov eax, ebp |
add edx, ecx |
call write_process_memory |
pop eax |
; write message |
mov eax, ebp |
add edx, ecx |
add edx, [ebx+8] |
add ebx, 20 |
pop ecx |
pop ecx |
pop ecx |
call write_process_memory |
; new debug event |
mov eax, ebp |
shl eax, 8 |
or byte [0x80000+eax+APPDATA.event_mask+1], 1 ; set flag 100h |
.ret: |
ret |
debug_exc: |
; int 1 = #DB |
save_ring3_context |
cld |
mov ax, os_data |
mov ds, ax |
mov es, ax |
mov eax, dr6 |
test ax, ax |
jns @f |
; this is exception from task switch |
; set DRx registers for task and continue |
mov eax, [0x3000] |
shl eax, 8 |
add eax, 0x80000+APPDATA.dbg_regs |
mov ecx, [eax+0] |
mov dr0, ecx |
mov ecx, [eax+4] |
mov dr1, ecx |
mov ecx, [eax+8] |
mov dr2, ecx |
mov ecx, [eax+0Ch] |
mov dr3, ecx |
xor ecx, ecx |
mov dr6, ecx |
mov ecx, [eax+10h] |
mov dr7, ecx |
restore_ring3_context |
iretd |
@@: |
push eax |
xor eax, eax |
mov dr6, eax |
; test if debugging |
cli |
mov eax, [0x3000] |
shl eax, 8 |
mov eax, [0x80000+eax+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
sti |
; not debuggee => say error and terminate |
add esp, 28h+4 |
mov [error_interrupt], 1 |
call show_error_parameters |
mov edx, [0x3010] |
mov byte [edx+TASKDATA.state], 4 |
jmp change_task |
.debug: |
; we are debugged process, notify debugger and suspend ourself |
; eax=debugger PID |
pop edx |
mov ebx, dr7 |
mov cl, not 1 |
.l1: |
test bl, 1 |
jnz @f |
and dl, cl |
@@: |
shr ebx, 2 |
add cl, cl |
inc ecx |
cmp cl, not 10h |
jnz .l1 |
push edx ; DR6 image |
mov ecx, [0x3010] |
push dword [ecx+TASKDATA.pid] ; PID |
push 12 |
pop ecx |
push 3 ; 3 = debug exception |
call debugger_notify |
pop ecx |
pop ecx |
pop ecx |
mov edx, [0x3010] |
mov byte [edx+TASKDATA.state], 1 ; suspended |
call change_task |
restore_ring3_context |
iretd |
/kernel/branches/gfx_kernel/core/mem.inc |
---|
0,0 → 1,469 |
if ~defined mem_inc |
mem_inc_fix: |
mem_inc fix mem_inc_fix |
;include "memmanag.inc" |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;High-level memory management in MenuetOS. |
;;It uses memory manager in memmanager.inc |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
second_base_address=0xC0000000 |
std_application_base_address=0x10000000 |
general_page_table_ dd 0 |
general_page_table=general_page_table_+second_base_address |
;----------------------------------------------------------------------------- |
create_general_page_table: |
;input |
; none |
;output |
; none |
;Procedure create general page directory and write |
;it address to [general_page_table]. |
pushad |
mov eax,1 ;alloc 1 page |
mov ebx,general_page_table ;write address to [general_page_table] |
call MEM_Alloc_Pages ;allocate page directory |
mov eax,[general_page_table] |
call MEM_Get_Linear_Address ;eax - linear address of page directory |
mov edi,eax |
mov ebx,eax ;copy address of page directory to safe place |
xor eax,eax |
mov ecx,4096/4 |
cld |
rep stosd ;clear page directory |
mov eax,4 |
mov edx,eax |
call MEM_Alloc_Pages ;alloc page tables for 0x0-0x1000000 region |
cmp eax,edx |
jnz $ ;hang if not enough memory |
;fill page tables |
xor esi,esi |
mov ebp,7 |
.loop: |
;esi - number of page in page directory |
;ebp - current page address |
;ebx - linear address of page directory |
mov eax,[ebx+4*esi] |
add dword [ebx+4*esi],7 ;add flags to address of page table |
call MEM_Get_Linear_Address |
;eax - linear address of page table |
mov ecx,4096/4 |
;ecx (counter) - number of pages in page table |
;current address=4Mb*esi |
.loop1: |
mov [eax],ebp ;write page address (with flags) in page table |
add eax,4 |
add ebp,4096 ;size of page=4096 bytes |
loop .loop1 |
inc esi ;next page directory entry |
cmp esi,edx |
jnz .loop |
;map region 0x80000000-0x807fffff to LFB |
mov eax,2 ;size of the region is 4Mb so only 1 page table needed |
mov edx,ebx ;ebx still contains linear address of the page directory |
add ebx,0x800 |
call MEM_Alloc_Pages ;alloc page table for the region |
mov eax,[ebx] |
add dword [ebx],7 ;add flags |
call MEM_Get_Linear_Address ;get linear address of the page table |
mov ecx,4096/4 ;number of pages in page table |
mov edi,[0xfe80] |
add edi,7 |
.loop3: |
;eax - linear address of page table |
;edi - current linear address with flags |
mov [eax],edi |
add eax,4 |
add edi,4096 |
loop .loop3 |
mov eax,[ebx+4] |
call MEM_Get_Linear_Address |
add dword [ebx+4],7 |
mov ecx,4096/4 |
.loop31: |
mov [eax],edi |
add eax,4 |
add edi,4096 |
loop .loop31 |
;map region 0xC0000000-* to 0x0-* |
mov esi,edx ;esi=linear address of the page directory |
lea edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00) |
mov ecx,4 |
rep movsd ;first 16Mb of the region mapped as 0x0-0x1000000 block |
mov eax,[0xfe8c] ;eax=memory size |
add eax,0x3fffff |
shr eax,22 |
mov esi,eax ;calculate number of entries in page directory |
sub esi,4 ;subtract entries for first 16Mb. |
mov ebp,0x1000000+7 ;start physical address with flags |
;mapping memory higher than 16Mb |
.loop4: |
;esi (counter) - number of entries in page directory |
;edi - address of entry |
test esi,esi |
jle .loop4end |
call MEM_Alloc_Page ;alloc page table for entry in page directory |
mov [edi],eax |
add dword [edi],7 ;write physical address of page table in page directory |
add edi,4 ;move entry pointer |
call MEM_Get_Linear_Address |
mov ecx,eax |
xor edx,edx |
.loop5: |
;ecx - linear address of page table |
;edx - index of page in page table |
;ebp - current mapped physical address with flags |
mov [ecx+4*edx],ebp ;write address of page in page table |
add ebp,0x1000 ;move to next page |
inc edx |
cmp edx,4096/4 |
jl .loop5 |
dec esi |
jmp .loop4 |
.loop4end: |
.set_cr3: |
;set value of cr3 register to the address of page directory |
mov eax,[general_page_table] |
add eax,8+16 ;add flags |
mov cr3,eax ;now we have full access paging |
popad |
ret |
;----------------------------------------------------------------------------- |
simple_clone_cr3_table: |
;Parameters: |
; eax - physical address of cr3 table (page directory) |
;result: |
; eax - physical address of clone of cr3 table. |
;Function copy only page directory. |
push ecx |
push edx |
push esi |
push edi |
call MEM_Get_Linear_Address |
;eax - linear address of cr3 table |
mov esi,eax |
call MEM_Alloc_Page |
test eax,eax |
jz .failed |
;eax - physical address of new page diretory |
mov edx,eax |
call MEM_Get_Linear_Address |
mov edi,eax |
mov ecx,4096/4 |
cld |
;esi - address of old page directory |
;edi - address of new page directory |
rep movsd ;copy page directory |
mov eax,edx |
.failed: |
pop edi |
pop esi |
pop edx |
pop ecx |
ret |
;----------------------------------------------------------------------------- |
create_app_cr3_table: |
;Parameters: |
; eax - slot of process (index in 0x3000 table) |
;result: |
; eax - physical address of table. |
;This function create page directory for new process and |
;write it physical address to offset 0xB8 of extended |
;process information. |
push ebx |
mov ebx,eax |
mov eax,[general_page_table] |
call simple_clone_cr3_table ;clone general page table |
shl ebx,8 |
mov [second_base_address+0x80000+ebx+APPDATA.dir_table],eax ;save address of page directory |
pop ebx |
ret |
;----------------------------------------------------------------------------- |
get_cr3_table: |
;Input: |
; eax - slot of process |
;result: |
; eax - physical address of page directory |
shl eax,8 ;size of process extended information=256 bytes |
mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table] |
ret |
;----------------------------------------------------------------------------- |
dispose_app_cr3_table: |
;Input: |
; eax - slot of process |
;result: |
; none |
;This procedure frees page directory, |
;page tables and all memory of process. |
pushad |
mov ebp,eax |
;ebp = process slot in the procedure. |
shl eax,8 |
mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table] |
mov ebx,eax |
;ebx = physical address of page directory |
call MEM_Get_Linear_Address |
mov edi,eax |
;edi = linear address of page directory |
mov eax,[edi+(std_application_base_address shr 20)] |
and eax,not (4096-1) |
call MEM_Get_Linear_Address |
mov esi,eax |
;esi = linear address of first page table |
;search threads |
; mov ecx,0x200 |
xor edx,edx |
mov eax,0x2 |
.loop: |
;eax = current slot of process |
mov ecx,eax |
shl ecx,5 |
cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 ;if process running? |
jz .next ;skip empty slots |
shl ecx,3 |
cmp [second_base_address+0x80000+ecx+APPDATA.dir_table],ebx ;compare page directory addresses |
jnz .next |
inc edx ;thread found |
.next: |
inc eax |
cmp eax,[0x3004] ;exit loop if we look through all processes |
jle .loop |
;edx = number of threads |
;our process is zombi so it isn't counted |
cmp edx,1 |
jg .threadsexists |
;if there isn't threads then clear memory. |
add edi,std_application_base_address shr 20 |
.loop1: |
;edi = linear address of current directory entry |
;esi = linear address of current page table |
test esi,esi |
jz .loop1end |
xor ecx,ecx |
.loop2: |
;ecx = index of page |
mov eax,[esi+4*ecx] |
test eax,eax |
jz .loopend ;skip empty entries |
and eax,not (4096-1) ;clear flags |
push ecx |
call MEM_Free_Page ;free page |
pop ecx |
.loopend: |
inc ecx |
cmp ecx,1024 ;there are 1024 pages in page table |
jl .loop2 |
mov eax,esi |
call MEM_Free_Page_Linear ;free page table |
.loop1end: |
add edi,4 ;move to next directory entry |
mov eax,[edi] |
and eax,not (4096-1) |
call MEM_Get_Linear_Address |
mov esi,eax ;calculate linear address of new page table |
test edi,0x800 |
jz .loop1 ;test if we at 0x80000000 address? |
and edi,not (4096-1) ;clear offset of page directory entry |
mov eax,edi |
call MEM_Free_Page_Linear ;free page directory |
popad |
ret |
.threadsexists: ;do nothing |
popad ;last thread will free memory |
ret |
;----------------------------------------------------------------------------- |
mem_alloc_specified_region: |
;eax - linear directory address |
;ebx - start address (aligned to 4096 bytes) |
;ecx - size in pages |
;result: |
; eax=1 - ok |
; eax=0 - failed |
;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval. |
pushad |
mov ebp,ebx ;save start address for recoil |
mov esi,eax |
.gen_loop: |
;esi = linear directory address |
;ebx = current address |
;ecx = remaining size in pages |
mov edx,ebx |
shr edx,22 |
mov edi,[esi+4*edx] ;find directory entry for current address |
test edi,edi |
jnz .table_exists ;check if page table allocated |
call MEM_Alloc_Page ;alloc page table |
test eax,eax |
jz .failed |
mov [esi+4*edx],eax |
add dword [esi+4*edx],7 ;write it address with flags |
call MEM_Get_Linear_Address |
call mem_fill_page ;clear page table |
jmp .table_linear |
.table_exists: |
;calculate linear address of page table |
mov eax,edi |
and eax,not (4096-1) ;clear flags |
call MEM_Get_Linear_Address |
.table_linear: |
;eax = linear address of page table |
mov edx,ebx |
shr edx,12 |
and edx,(1024-1) ;calculate index in page table |
mov edi,eax |
.loop: |
;edi = linear address of page table |
;edx = current page table index |
;ecx = remaining size in pages |
;ebx = current address |
test ecx,ecx |
jle .endloop1 ;all requested pages allocated |
call MEM_Alloc_Page ;alloc new page |
test eax,eax |
jz .failed |
mov [edi+4*edx],eax |
add dword [edi+4*edx],7 ;write it address with flags |
call MEM_Get_Linear_Address |
call mem_fill_page ;clear new page |
;go to next page table entry |
dec ecx |
add ebx,4096 |
inc edx |
test edx,(1024-1) |
jnz .loop |
jmp .gen_loop |
.endloop1: |
popad |
mov eax,1 ;ok |
ret |
.failed: |
;calculate data for recoil |
sub ebx,ebp |
shr ebx,12 |
mov ecx,ebx ;calculate number of allocated pages |
mov eax,esi ;restore linear address of page directory |
mov ebx,ebp ;restore initial address |
call mem_free_specified_region ;free all allocated pages |
popad |
xor eax,eax ;fail |
ret |
;----------------------------------------------------------------------------- |
mem_fill_page: |
;Input: |
; eax - address |
;result: |
; none |
;set to zero 4096 bytes at eax address. |
push ecx |
push edi |
mov edi,eax |
mov ecx,4096/4 |
xor eax,eax |
rep stosd |
lea eax,[edi-4096] |
pop edi |
pop ecx |
ret |
;----------------------------------------------------------------------------- |
mem_free_specified_region: |
;eax - linear page directory address |
;ebx - start address (aligned to 4096 bytes) |
;ecx - size in pages |
;result - none |
;Free pages in [ebx;ebx+4096*ecx) region. |
pushad |
mov esi,eax |
xor ebp,ebp |
.gen_loop: |
;esi = linear page directory address |
;ebx = current address |
;ecx = remaining pages |
;ebp = 0 for first page table |
; 1 otherwise |
mov edx,ebx |
shr edx,22 |
mov eax,[esi+4*edx] ;find directory entry for current address |
and eax,not (4096-1) |
test eax,eax |
jnz .table_exists |
;skip absent page tables |
mov edx,ebx |
shr edx,12 |
and edx,(1024-1) ;edx - index of current page |
add ebx,1 shl 22 |
add ecx,edx |
and ebx,not ((1 shl 22)-1) |
mov ebp,1 ;set flag |
sub ecx,1024 ;ecx=ecx-(1024-edx) |
jg .gen_loop |
popad |
ret |
.table_exists: |
call MEM_Get_Linear_Address |
;eax - linear address of table |
mov edx,ebx |
shr edx,12 |
and edx,(1024-1) ;edx - index of current page |
mov edi,eax |
.loop: |
;edi = linear address of page table entry |
;edx = index of page table entry |
;ecx = remaining pages |
test ecx,ecx |
jle .endloop1 |
mov eax,[edi+4*edx] |
and eax,not (4096-1) |
call MEM_Free_Page ;free page |
mov dword [edi+4*edx],0 ;and clear page table entry |
dec ecx |
inc edx |
cmp edx,1024 |
jl .loop |
test ebp,ebp |
jz .first_page |
mov eax,edi |
call MEM_Free_Page_Linear ;free page table |
mov edx,ebx |
shr edx,22 |
mov dword [esi+4*edx],0 ;and clear page directory entry |
.first_page: |
add ebx,1 shl 22 |
and ebx,not ((1 shl 22)-1) ;calculate new current address |
mov ebp,1 ;set flag |
jmp .gen_loop |
.endloop1: |
popad |
ret |
end if |
/kernel/branches/gfx_kernel/core/memmanag.inc |
---|
0,0 → 1,833 |
if ~defined memmanager_inc |
memmanager_inc_fix: |
memmanager_inc fix memmanager_inc_fix |
;for testing in applications |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; Memory allocator for MenuetOS kernel |
;; Andrey Halyavin, halyavin@land.ru 2005 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap block structure - |
;; you can handle several ranges of |
;; pages simultaneosly. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
.heap_linear_address equ 0 |
.heap_block_size equ 4 |
.heap_physical_address equ 8 |
.heap_reserved equ 12 |
.heap_block_info equ 16 |
max_heaps equ 8 |
.range_info equ 36 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; memory manager data |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
uglobal |
MEM_heap_block rd .heap_block_info*max_heaps/4 |
MEM_heap_count rd 1 |
MEM_cli_count rd 1 |
MEM_cli_prev rd 1 |
MEM_FreeSpace rd 1 |
; MEM_AllSpace rd 1 |
endg |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Init |
;;Initialize memory manager structures. |
;;Must be called first. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Init: |
push eax |
xor eax,eax |
mov [MEM_cli_prev],eax ;init value = 0 |
dec eax |
mov [MEM_cli_count],eax ;init value = -1 |
pop eax |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Heap_Lock |
;;Wait until all operations with heap will be finished. |
;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations |
;;with heap are forbidden. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Heap_Lock: |
pushfd |
cli |
inc dword [MEM_cli_count] |
jz MEM_Heap_First_Lock |
add esp,4 |
ret |
MEM_Heap_First_Lock: ;save interrupt flag |
shr dword [esp],9 |
and dword [esp],1 |
pop dword [MEM_cli_prev] |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Heap_UnLock |
;;After this routine operations with heap are allowed. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Heap_UnLock: |
dec dword [MEM_cli_count] |
js MEM_Heap_UnLock_last |
ret |
MEM_Heap_UnLock_last: |
cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag |
jz MEM_Heap_UnLock_No_sti |
sti |
MEM_Heap_UnLock_No_sti: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Add_Heap |
;;Add new range to memory manager. |
;;eax - linear address |
;;ebx - size in pages |
;;ecx - physical address |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Add_Heap: |
push edx |
call MEM_Heap_Lock |
mov edx,[MEM_heap_count] |
cmp edx,max_heaps |
jz MEM_Add_Heap_Error |
inc dword [MEM_heap_count] |
shl edx,4 |
mov [MEM_heap_block+edx+.heap_linear_address],eax |
mov [MEM_heap_block+edx+.heap_block_size],ebx |
shl dword [MEM_heap_block+edx+.heap_block_size],12 |
mov [MEM_heap_block+edx+.heap_physical_address],ecx |
lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table |
and edx,0xFFFFF000 |
push edi |
mov edi,edx |
shr edi,12 |
sub edi,ebx ;edi=-free space |
sub [MEM_FreeSpace],edi |
; sub [MEM_AllSpace],edi |
mov [eax],eax |
add [eax],edx ;first 4 bytes - pointer to first free page |
;clean page info area |
lea edi,[eax+4] |
mov ecx,edx |
shr ecx,2 |
push eax |
xor eax,eax |
rep stosd |
pop eax |
pop edi |
;create free pages list. |
mov ecx,[eax] |
shl ebx,12 |
add eax,ebx ;eax - address after block |
MEM_Add_Heap_loop: |
add ecx,4096 |
mov [ecx-4096],ecx ;set forward pointer |
cmp ecx,eax |
jnz MEM_Add_Heap_loop |
mov dword [ecx-4096],0 ;set end of list |
MEM_Add_Heap_ret: |
call MEM_Heap_UnLock |
pop edx |
ret |
MEM_Add_Heap_Error: |
xor eax,eax |
jmp MEM_Add_Heap_ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Physical_Address |
;;Translate linear address to physical address |
;;Parameters: |
;; eax - linear address |
;;Result: |
;; eax - physical address |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Physical_Address |
MEM_Get_Physical_Address: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Physical_Address_loop: |
sub eax,[MEM_heap_block+ecx+.heap_linear_address] |
jl MEM_Get_Physical_Address_next |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jge MEM_Get_Physical_Address_next |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
jmp MEM_Get_Physical_Address_loopend |
MEM_Get_Physical_Address_next: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
sub ecx,16 |
jns MEM_Get_Physical_Address_loop |
xor eax,eax ;address not found |
MEM_Get_Physical_Address_loopend: |
call MEM_Heap_UnLock |
pop ecx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Linear_Address |
;;Translate physical address to linear address. |
;;Parameters: |
;; eax - physical address |
;;Result: |
;; eax - linear address |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Linear_Address |
MEM_Get_Linear_Address: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Linear_Address_loop: |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
jl MEM_Get_Linear_Address_Next |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jge MEM_Get_Linear_Address_Next |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
call MEM_Heap_UnLock |
pop ecx |
ret |
MEM_Get_Linear_Address_Next: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
sub ecx,16 |
jns MEM_Get_Linear_Address_loop |
call MEM_Heap_UnLock |
pop ecx |
xor eax,eax ;address not found |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Page |
;;Allocate and add reference to page |
;;Result: |
;; eax<>0 - physical address of page |
;; eax=0 - not enough memory |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Page |
MEM_Alloc_Page: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Alloc_Page_loop: |
push ecx |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
cmp dword [ecx],0 |
jz MEM_Alloc_Page_loopend |
mov eax,[ecx] |
push dword [eax] |
pop dword [ecx] |
sub eax,ecx |
push eax |
shr eax,10 |
mov word [ecx+.range_info+eax],1 |
pop eax |
pop ecx |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
dec [MEM_FreeSpace] |
jmp MEM_Alloc_Page_ret |
MEM_Alloc_Page_loopend: |
pop ecx |
sub ecx,16 |
jns MEM_Alloc_Page_loop |
xor eax,eax |
MEM_Alloc_Page_ret: |
call MEM_Heap_UnLock |
pop ecx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Page_Linear |
;;Allocate and add reference to page |
;;Result: |
;; eax<>0 - linear address of page |
;; eax=0 - not enough memory |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Page_Linear |
MEM_Alloc_Page_Linear: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Alloc_Page_Linear_loop: |
push ecx |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
cmp dword [ecx],0 |
jz MEM_Alloc_Page_Linear_loopend |
mov eax,[ecx] |
push dword [eax] |
pop dword [ecx] |
push eax |
sub eax,ecx |
shr eax,10 |
mov word [ecx+.range_info+eax],1 |
pop eax |
pop ecx |
dec [MEM_FreeSpace] |
jmp MEM_Alloc_Page_Linear_ret |
MEM_Alloc_Page_Linear_loopend: |
pop ecx |
sub ecx,16 |
jns MEM_Alloc_Page_Linear_loop |
xor eax,eax |
MEM_Alloc_Page_Linear_ret: |
call MEM_Heap_UnLock |
pop ecx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Page |
;;Remove reference and free page if number of |
;;references is equal to 0 |
;;Parameters: |
;; eax - physical address of page |
;;Result: |
;; eax - 1 success |
;; eax - 0 failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if (used MEM_Free_Page) | (used MEM_Free_Page_Linear) |
MEM_Free_Page: |
test eax,eax |
jz MEM_Free_Page_Zero |
test eax,0xFFF |
jnz MEM_Free_Page_Not_Aligned |
push ebx |
push ecx |
push edx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Free_Page_Heap_loop: |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
js MEM_Free_Page_Heap_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Free_Page_Heap_loopend |
MEM_Free_Page_Heap_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
sub ecx,16 |
jns MEM_Free_Page_Heap_loop |
xor eax,eax |
inc eax |
jmp MEM_Free_Page_ret |
MEM_Free_Page_Heap_loopend: |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
mov ebx,eax |
add eax,ecx |
shr ebx,10 |
mov edx,[ecx+.range_info+ebx] |
test edx,0x80000000 |
jnz MEM_Free_Page_Bucket |
test dx,dx |
jz MEM_Free_Page_Error |
dec word [ecx+.range_info+ebx] |
jnz MEM_Free_Page_OK |
MEM_Free_Page_Bucket: |
push dword [ecx] |
mov [ecx],eax |
pop dword [eax] |
mov dword [ecx+.range_info+ebx],0 |
inc [MEM_FreeSpace] |
MEM_Free_Page_OK: |
mov eax,1 |
MEM_Free_Page_ret: |
call MEM_Heap_UnLock |
pop edx |
pop ecx |
pop ebx |
ret |
MEM_Free_Page_Error: |
xor eax,eax |
jmp MEM_Free_Page_ret |
MEM_Free_Page_Zero: |
inc eax |
ret |
MEM_Free_Page_Not_Aligned: |
xor eax,eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Page_Linear |
;;Remove reference and free page if number of |
;;references is equal to 0 |
;;Parameters: |
;; eax - linear address of page |
;;Result: |
;; eax - 1 success |
;; eax - 0 failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free_Page_Linear |
MEM_Free_Page_Linear: |
test eax,eax |
jz MEM_Free_Page_Zero |
test eax,0xFFF |
jnz MEM_Free_Page_Not_Aligned |
push ebx |
push ecx |
push edx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Free_Page_Linear_Heap_loop: |
sub eax,[MEM_heap_block+ecx+.heap_linear_address] |
js MEM_Free_Page_Linear_Heap_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Free_Page_Heap_loopend |
MEM_Free_Page_Linear_Heap_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
sub ecx,16 |
jns MEM_Free_Page_Linear_Heap_loop |
xor eax,eax |
inc eax |
jmp MEM_Free_Page_ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Pages |
;;Allocates set of pages. |
;;Parameters: |
;; eax - number of pages |
;; ebx - buffer for physical addresses |
;;Result: |
;; eax - number of allocated pages |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Pages |
MEM_Alloc_Pages: |
push eax |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Alloc_Pages_ret |
MEM_Alloc_Pages_loop: |
call MEM_Alloc_Page |
test eax,eax |
jz MEM_Alloc_Pages_ret |
mov [ebx],eax |
add ebx,4 |
dec ecx |
jnz MEM_Alloc_Pages_loop |
MEM_Alloc_Pages_ret: |
sub [esp+8],ecx |
pop ecx |
pop ebx |
pop eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Pages_Linear |
;;Allocates set of pages. |
;;Parameters: |
;; eax - number of pages |
;; ebx - buffer for linear addresses |
;;Result: |
;; eax - number of allocated pages |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Pages_Linear |
MEM_Alloc_Pages_Linear: |
push eax |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Alloc_Pages_Linear_ret |
MEM_Alloc_Pages_Linear_loop: |
call MEM_Alloc_Page_Linear |
test eax,eax |
jz MEM_Alloc_Pages_Linear_ret |
mov [ebx],eax |
add ebx,4 |
dec ecx |
jnz MEM_Alloc_Pages_Linear_loop |
MEM_Alloc_Pages_Linear_ret: |
sub [esp+8],ecx |
pop ecx |
pop ebx |
pop eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Pages |
;;Parameters: |
;; eax - number of pages |
;; ebx - array of addresses |
;;Result: |
;; eax=1 - succcess |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free_Pages |
MEM_Free_Pages: |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Free_Pages_ret |
MEM_Free_Pages_loop: |
mov eax,[ebx] |
call MEM_Free_Page |
add ebx,4 |
test eax,eax |
jz MEM_Free_Pages_ret |
dec ecx |
jnz MEM_Free_Pages_loop |
MEM_Free_Pages_ret: |
pop ecx |
pop ebx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Pages_Linear |
;;Parameters: |
;; eax - number of pages |
;; ebx - array of addresses |
;;Result: |
;; eax=1 - succcess |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free_Pages_Linear |
MEM_Free_Pages_Linear: |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Free_Pages_Linear_ret |
MEM_Free_Pages_Linear_loop: |
mov eax,[ebx] |
call MEM_Free_Page_Linear |
add ebx,4 |
test eax,eax |
jz MEM_Free_Pages_Linear_ret |
dec ecx |
jnz MEM_Free_Pages_Linear_loop |
MEM_Free_Pages_Linear_ret: |
pop ecx |
pop ebx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Heap_Number |
;;Calculate number of heap which pointer belongs to. |
;;Parameter: |
;; eax - address |
;;Result: |
;; ecx - number of heap*16. |
;; eax=0 if address not found. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Heap_Number |
MEM_Get_Heap_Number: |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Heap_loop: |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
jl MEM_Get_Heap_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Get_Heap_loopend |
MEM_Get_Heap_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
sub ecx,16 |
jns MEM_Get_Heap_loop |
call MEM_Heap_UnLock |
xor eax,eax |
ret |
MEM_Get_Heap_loopend: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
call MEM_Heap_UnLock |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Heap_Number_Linear |
;;Calculate number of heap which pointer belongs to. |
;;Parameter: |
;; eax - address |
;;Result: |
;; ecx - number of heap*16. |
;; eax=0 if address not found. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Heap_Number_Linear |
MEM_Get_Heap_Number_Linear: |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Heap_Linear_loop: |
sub eax,[MEM_heap_block+ecx+.heap_linear_address] |
jl MEM_Get_Heap_Linear_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Get_Heap_Linear_loopend |
MEM_Get_Heap_Linear_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
sub ecx,16 |
jns MEM_Get_Heap_Linear_loop |
call MEM_Heap_UnLock |
xor eax,eax |
ret |
MEM_Get_Heap_Linear_loopend: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
call MEM_Heap_UnLock |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc |
;;Allocate small region. |
;;Parameters: |
;; eax - size (0<eax<=4096) |
;;Result: |
;; eax - linear address |
;; eax=0 - not enough memory |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc |
MEM_Alloc: |
;find chain |
test eax,eax |
jng MEM_Alloc_Wrong_Size |
cmp eax,4096 |
jg MEM_Alloc_Wrong_Size |
push ebx |
push ecx |
push edx |
push esi |
dec eax |
shr eax,4 |
xor edx,edx |
MEM_Alloc_Find_Size: |
add edx,4 |
shr eax,1 |
jnz MEM_Alloc_Find_Size |
MEM_Alloc_Size_Found: |
mov ecx,edx |
shr ecx,2 |
add ecx,4 |
mov eax,1 |
shl eax,cl |
mov esi,eax |
;esi - block size |
;edx - offset |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Alloc_Find_Heap: |
mov eax,[MEM_heap_block+ecx+.heap_linear_address] |
cmp dword [eax+edx],0 |
jnz MEM_Alloc_Use_Existing |
sub ecx,16 |
jns MEM_Alloc_Find_Heap |
;create new bucket page |
call MEM_Alloc_Page_Linear |
call MEM_Get_Heap_Number_Linear |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
mov [ecx+edx],eax |
lea ebx,[eax+4096] |
MEM_Alloc_List_loop: |
mov [eax],eax |
mov [eax+4],eax |
add [eax],esi |
sub [eax+4],esi |
add eax,esi |
cmp eax,ebx |
jnz MEM_Alloc_List_loop |
sub ebx,esi |
mov dword [ebx],0 |
sub eax,4096 |
mov dword [eax+4],0 |
mov eax,ecx |
MEM_Alloc_Use_Existing: |
mov ebx,eax |
mov eax,[eax+edx] |
mov ecx,[eax] |
mov [ebx+edx],ecx |
test ecx,ecx |
jz MEM_Alloc_Became_Empty |
mov dword [ecx+4],0 |
MEM_Alloc_Became_Empty: |
mov ecx,eax |
sub ecx,ebx |
shr ecx,10 |
and ecx,0xFFFFFFFC |
inc byte [ebx+.range_info+ecx+2] |
shr edx,2 |
add edx,128 |
dec edx |
mov [ebx+.range_info+ecx+3],dl |
MEM_Alloc_ret: |
call MEM_Heap_UnLock |
pop esi |
pop edx |
pop ecx |
pop ebx |
ret |
MEM_Alloc_Wrong_Size: |
xor eax,eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free |
;;Parameters: |
;; eax - linear address |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free |
MEM_Free: |
test eax,eax |
jz MEM_Free_Zero |
push ebx |
push ecx |
push edx |
push esi |
push edi |
push ebp |
call MEM_Heap_Lock |
call MEM_Get_Heap_Number_Linear |
test eax,eax |
jz MEM_Free_ret |
mov edx,eax |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
sub edx,ecx |
shr edx,10 |
and edx,0xFFFFFFFC |
mov ebx,[ecx+.range_info+edx] |
mov esi,ebx |
shr esi,24 |
sub esi,128 |
mov edi,[ecx+4+4*esi] |
mov [eax],edi |
mov dword [eax+4],0 |
test edi,edi |
jz MEM_Free_Empty_List |
mov [edi+4],eax |
MEM_Free_Empty_List: |
mov [ecx+4+4*esi],eax |
sub ebx,0x10000 |
mov [ecx+.range_info+edx],ebx |
test ebx,0xFF0000 |
jnz MEM_Free_ret |
;delete empty blocks on the page |
lea edx,[esi+5] |
and eax,0xFFFFF000 |
mov edi,eax |
mov eax,1 |
xchg ecx,edx |
shl eax,cl |
mov ecx,edx |
mov edx,eax |
;edx - size of block |
;edi - start of page |
mov eax,edi |
lea ebx,[eax+4096] |
MEM_Free_Block_loop: |
cmp dword [eax+4],0 |
jnz MEM_Free_Block_Not_First |
mov ebp,dword [eax] |
mov [ecx+4+4*esi],ebp |
test ebp,ebp |
jz MEM_Free_Block_Last |
mov dword [ebp+4],0 |
MEM_Free_Block_Last: |
jmp MEM_Free_Block_loop_end |
MEM_Free_Block_Not_First: |
mov ebp,dword [eax] |
push ebp |
mov ebp,dword [eax+4] |
pop dword [ebp] |
mov ebp,dword [eax] |
test ebp,ebp |
jz MEM_Free_Block_loop_end |
push dword [eax+4] |
pop dword [ebp+4] |
; jmp MEM_Free_Block_loop_end |
MEM_Free_Block_loop_end: |
add eax,edx |
cmp eax,ebx |
jnz MEM_Free_Block_loop |
mov eax,edi |
call MEM_Free_Page_Linear |
MEM_Free_ret: |
call MEM_Heap_UnLock |
pop ebp |
pop edi |
pop esi |
pop edx |
pop ecx |
pop ebx |
ret |
MEM_Free_Zero: |
inc eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Add_Reference |
;; eax - physical address of page |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Add_Reference |
MEM_Add_Reference: |
push ebx |
push ecx |
call MEM_Heap_Lock |
call MEM_Get_Heap_Number |
test eax,eax |
jz MEM_Add_Reference_ret |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
shr eax,10 |
and eax,0xFFFFFFFC |
test dword [ecx+eax+.range_info],0x80000000 |
jnz MEM_Add_Reference_failed |
inc dword [ecx+eax+.range_info] |
MEM_Add_Reference_ret: |
call MEM_Heap_UnLock |
pop ecx |
pop ebx |
ret |
MEM_Add_Reference_failed: |
xor eax,eax |
jmp MEM_Add_Reference_ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Add_Reference_Linear |
;; eax - linear address of page |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Add_Reference_Linear |
MEM_Add_Reference_Linear: |
push ebx |
push ecx |
call MEM_Heap_Lock |
call MEM_Get_Heap_Number_Linear |
test eax,eax |
jz MEM_Add_Reference_Linear_ret |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
sub eax,ecx |
shr eax,10 |
and eax,0xFFFFFFFC |
test dword [ecx+eax+.range_info],0x80000000 |
jnz MEM_Add_Reference_Linear_failed |
inc dword [ecx+eax+.range_info] |
mov eax,1 |
MEM_Add_Reference_Linear_ret: |
call MEM_Heap_UnLock |
pop ecx |
pop ebx |
ret |
MEM_Add_Reference_Linear_failed: |
xor eax,eax |
jmp MEM_Add_Reference_Linear_ret |
end if |
end if ;memmanager.inc |
/kernel/branches/gfx_kernel/core/newproce.inc |
---|
0,0 → 1,1615 |
if ~defined newprocess_inc |
newprocess_inc_fix: |
newprocess_inc fix newprocess_inc_fix |
include "mem.inc" |
include "memmanag.inc" |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;Working with new types of processes. |
;;Author: Khalyavin Andrey halyavin@land.ru |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
new_process_loading db 'K : New Process - loading',13,10,0 |
new_process_running db 'K : New Process - done',13,10,0 |
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 |
endg |
;----------------------------------------------------------------------------- |
find_new_process_place: |
;input: |
; none |
;result: |
; eax=[new_process_place]<>0 - ok |
; 0 - failed. |
;This function find least empty slot. |
;It doesn't increase [0x3004]! |
mov eax,0x3000+second_base_address |
push ebx |
mov ebx,[0x3004] |
inc ebx |
shl ebx,5 |
add ebx,eax ;ebx - address of process information for (last+1) slot |
.newprocessplace: |
;eax = address of process information for current slot |
cmp eax,ebx |
jz .endnewprocessplace ;empty slot after high boundary |
add eax,0x20 |
cmp word [eax+TASKDATA.state],9 ;check process state, 9 means that process slot is empty |
jnz .newprocessplace |
.endnewprocessplace: |
mov ebx,eax |
sub eax,0x3000+second_base_address |
shr eax,5 ;calculate slot index |
cmp eax,256 |
jge .failed ;it should be <256 |
mov word [ebx+TASKDATA.state],9 ;set process state to 9 (for slot after hight boundary) |
mov [new_process_place],eax ;save process slot |
pop ebx |
ret |
.failed: |
xor eax,eax |
pop ebx |
ret |
;----------------------------------------------------------------------------- |
safe_sti: |
cmp byte [0xe000], 1 |
jne @f |
sti |
@@:ret |
new_start_application_floppy: |
;input: |
; eax - pointer to filename |
; ebx - parameters to pass |
; edx - flags |
;result: |
; eax - pid of new process |
; or 0 if call fails. |
mov [appl_path],edi |
pushad |
mov esi,new_process_loading |
call sys_msg_board_str ;write to debug board |
;wait application_table_status mutex |
.table_status: |
cli |
cmp [application_table_status],0 |
jz .stf |
sti |
call change_task |
jmp .table_status |
.stf: |
call set_application_table_status |
;we can change system tables now |
push edi |
push ebx |
push eax |
call find_new_process_place ;find empty process slot |
sti |
test eax,eax |
mov ecx, -0x20 ; too many processes |
jz .failed |
mov edi,eax |
shl edi,8 |
add edi,0x80000 |
mov ecx,256/4 |
xor eax,eax |
cld |
rep stosd ;clean extended information about process |
;set new process name |
mov [appl_path_size],eax |
pop eax |
push eax |
.find_last_byte: |
cmp byte [eax],0 |
jz .find_last_byte_end |
inc eax |
inc [appl_path_size] |
jmp .find_last_byte |
.find_last_byte_end: |
add [appl_path_size],24 |
sub eax,11 ;last 11 bytes = application name |
; mov eax,[esp] ;eax - pointer to file name |
mov ebx,[new_process_place] |
shl ebx,8 |
add ebx,0x80000 + APPDATA.app_name |
mov ecx,11 |
call memmove |
;read header of file |
mov eax,[esp] |
mov ebx,1 ;index of first block |
mov ecx,2 ;number of blocks |
mov edx,0x90000 ;temp area |
mov esi,12 ;file name length |
mov edi,[esp+8] |
; cli |
call floppy_fileread ;read file from FD |
; sti |
mov ecx, eax |
neg ecx |
jnz .cleanfailed |
;check MENUET signature |
mov ecx, -0x1F ; not Menuet/Kolibri executable |
cmp [0x90000],dword 'MENU' |
jnz .cleanfailed |
cmp [0x90004],word 'ET' |
jnz .cleanfailed |
call get_app_params ;parse header fields |
test esi, esi |
jz .cleanfailed |
mov eax,[new_process_place] |
inc ecx ; -0x1E = no memory |
call create_app_cr3_table ;create page directory for new process |
test eax,eax |
jz .cleanfailed_mem |
call MEM_Get_Linear_Address ;calculate linear address of it |
mov ebx,std_application_base_address |
mov ecx,[app_mem] |
add ecx,4095 |
shr ecx,12 |
mov edx,eax |
call mem_alloc_specified_region ;allocate memory for application |
test eax,eax |
mov ecx, -0x1E |
jz .cleanfailed_mem1 |
mov eax,[edx+(std_application_base_address shr 20)] |
and eax,not (4096-1) ;eax - physical address of first (for application memory) page table |
call MEM_Get_Linear_Address |
mov edx,eax |
;read file |
mov ebx,1 |
mov esi,12 ;length of file name |
.loop1: |
;edx = linear address of current page table entry |
;ebx = index of current block in file |
push edx |
mov eax,[edx] |
and eax,not (4096-1) |
call MEM_Get_Linear_Address |
mov edx,eax ;read file block to current page |
mov eax,[esp+4] ;restore pointer to file name |
mov ecx,8 ;number of blocks read |
push ebx |
mov edi,[esp+16] |
; cli |
call floppy_fileread |
;ebx=file size |
; sti |
pop ecx |
shr ebx,9 |
cmp ecx,ebx |
jg .endloop1 ;if end of file? |
mov ebx,ecx |
test eax,eax |
jnz .endloop1 ;check io errors |
pop edx |
add ebx,8 ;go to next page |
add edx,4 |
jmp .loop1 |
.endloop1: |
add esp,8+4 ;pop linear address of page table entry and pointer to file name |
call new_start_application_fl.add_app_parameters |
mov [esp+28],eax |
popad |
ret |
.cleanfailed_mem1: |
;there is mem for directory entry, but there is no mem for pages |
;so free directory entry |
mov eax,[new_process_place] |
shl eax,8 |
mov eax,[0x80000+eax+APPDATA.dir_table] |
call MEM_Free_Page |
.cleanfailed_mem: |
;there is no mem for directory entry, display message. |
mov esi,start_not_enough_memory |
call sys_msg_board_str |
.cleanfailed: ;clean process name |
push ecx ; save error code |
;can't read file, clean process name. |
;this avoid problems with panel application. |
mov edi,[new_process_place] |
shl edi,8 |
add edi,0x80000 + APPDATA.app_name |
mov ecx,11 |
mov eax,' ' |
cld |
rep stosb |
pop eax |
.failed: |
;no more slots |
add esp,8+4 |
mov [application_table_status],0 |
mov [esp+1Ch], eax |
popad |
sti |
ret |
;----------------------------------------------------------------------------- |
new_start_application_fl: |
;input: |
; eax - pointer to filename |
; ebx - parameters to pass |
; edx - flags |
;result: |
; eax - pid of new process |
; or 0 if call fails. |
mov [appl_path],edi |
mov [appl_path_size],36 |
pushad |
mov esi,new_process_loading |
call sys_msg_board_str ;write to debug board |
;wait application_table_status mutex |
.table_status: |
cli |
cmp [application_table_status],0 |
jz .stf |
sti |
call change_task |
jmp .table_status |
.stf: |
call set_application_table_status |
;we can change system tables now |
push ebx |
push eax |
call find_new_process_place ;find empty process slot |
call safe_sti |
test eax,eax |
mov ecx, -0x20 ; too many processes |
jz .failed |
mov edi,eax |
shl edi,8 |
add edi,0x80000 |
mov ecx,256/4 |
xor eax,eax |
cld |
rep stosd ;clean extended information about process |
;set new process name |
mov eax,[esp] ;eax - pointer to file name |
mov ebx,[new_process_place] |
shl ebx,8 |
add ebx,0x80000 + APPDATA.app_name |
mov ecx,11 |
call memmove |
;read header of file |
mov ebx,1 ;index of first block |
mov ecx,2 ;number of blocks |
mov edx,0x90000 ;temp area |
mov esi,12 ;file name length |
cli |
call fileread ;read file from RD |
call safe_sti |
mov ecx, eax |
neg ecx |
jnz .cleanfailed |
;check MENUET signature |
mov ecx, -0x1F ; not Menuet/Kolibri executable |
cmp [0x90000],dword 'MENU' |
jnz .cleanfailed |
cmp [0x90004],word 'ET' |
jnz .cleanfailed |
call get_app_params ;parse header fields |
test esi,esi |
jz .cleanfailed |
mov eax,[new_process_place] |
inc ecx ; -0x1E = no memory |
call create_app_cr3_table ;create page directory for new process |
test eax,eax |
jz .cleanfailed_mem |
call MEM_Get_Linear_Address ;calculate linear address of it |
mov ebx,std_application_base_address |
mov ecx,[app_mem] |
add ecx,4095 |
shr ecx,12 |
mov edx,eax |
call mem_alloc_specified_region ;allocate memory for application |
test eax,eax |
mov ecx, -0x1E |
jz .cleanfailed_mem1 |
mov eax,[edx+(std_application_base_address shr 20)] |
and eax,not (4096-1) ;eax - physical address of first (for application memory) page table |
call MEM_Get_Linear_Address |
mov edx,eax |
;read file |
mov ebx,1 |
mov esi,12 ;length of file name |
.loop1: |
;edx = linear address of current page table entry |
;ebx = index of current block in file |
push edx |
mov eax,[edx] |
and eax,not (4096-1) |
call MEM_Get_Linear_Address |
mov edx,eax ;read file block to current page |
mov eax,[esp+4] ;restore pointer to file name |
mov ecx,8 ;number of blocks read |
push ebx |
cli |
call fileread |
;ebx=file size |
call safe_sti |
pop ecx |
shr ebx,9 |
cmp ecx,ebx |
jg .endloop1 ;if end of file? |
mov ebx,ecx |
test eax,eax |
jnz .endloop1 ;check io errors |
pop edx |
add ebx,8 ;go to next page |
add edx,4 |
jmp .loop1 |
.endloop1: |
add esp,8 ;pop linear address of page table entry and pointer to file name |
call .add_app_parameters |
mov [esp+28],eax |
popad |
ret |
.cleanfailed_mem1: |
;there is mem for directory entry, but there is no mem for pages |
;so free directory entry |
mov eax,[new_process_place] |
shl eax,8 |
mov eax,[0x80000+eax+APPDATA.dir_table] |
call MEM_Free_Page |
.cleanfailed_mem: |
;there is no mem for directory entry, display message. |
mov esi,start_not_enough_memory |
call sys_msg_board_str |
.cleanfailed: ;clean process name |
push ecx ; save error code |
;can't read file, clean process name. |
;this avoid problems with panel application. |
mov edi,[new_process_place] |
shl edi,8 |
add edi,0x80000+APPDATA.app_name |
mov ecx,11 |
mov eax,' ' |
cld |
rep stosb |
pop eax |
.failed: |
;no more slots |
add esp,8 |
mov [application_table_status],0 |
mov [esp+1Ch], eax |
popad |
call safe_sti |
ret |
.add_app_parameters: |
;input: |
; [esp] - pointer to parameters |
; [esp+4]-[esp+36] pushad registers. |
;result |
; eax - pid of new process |
; or zero if failed |
cli |
mov ebx,[new_process_place] |
cmp ebx,[0x3004] |
jle .noinc |
inc dword [0x3004] ;update number of processes |
.noinc: |
; mov ebx,[new_process_place] |
;set 0x8c field of extended information about process |
;(size of application memory) |
shl ebx,8 |
mov eax,[app_mem] |
mov [second_base_address+0x80000+APPDATA.mem_size+ebx],eax |
;set 0x10 field of information about process |
;(application base address) |
; mov ebx,[new_process_place] |
; shl ebx,5 |
shr ebx,3 |
mov dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address |
;add command line parameters |
.add_command_line: |
mov edx,[app_i_param] |
test edx,edx |
jz .no_command_line ;application don't need parameters |
mov eax,[esp+4] |
test eax,eax |
jz .no_command_line ;no parameters specified |
;calculate parameter length |
mov esi,eax |
xor ecx,ecx |
.command_line_len: |
cmp byte [esi],0 |
jz .command_line_len_end |
inc esi |
inc ecx |
cmp ecx,256 |
jl .command_line_len |
.command_line_len_end: |
;ecx - parameter length |
;edx - address of parameters in new process address space |
mov ebx,eax ;ebx - address of parameters in our address space |
mov eax,[new_process_place] |
call write_process_memory ;copy parameters to new process address space |
.no_command_line: |
;****************************************************************** |
mov edx,[app_i_icon] |
test edx,edx |
jz .no_command_line_1 ;application don't need path of file |
mov ebx,[appl_path] |
mov ecx,[appl_path_size] |
mov eax,[new_process_place] |
call write_process_memory ;copy path of file to new process address space |
.no_command_line_1: |
;****************************************************************** |
mov ebx,[new_process_place] |
mov eax,ebx |
shl ebx,5 |
add ebx,0x3000 ;ebx - pointer to information about process |
mov [ebx+TASKDATA.wnd_number],al ;set window number on screen = process slot |
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function) |
inc dword [process_number] |
mov eax,[process_number] |
mov [ebx+TASKDATA.pid],eax ;set PID |
mov ecx,ebx |
add ecx,draw_data-0x3000 ;ecx - pointer to draw data |
;set draw data to full screen |
mov [ecx+RECT.left],dword 0 |
mov [ecx+RECT.top],dword 0 |
mov eax,[0xfe00] |
mov [ecx+RECT.right],eax |
mov eax,[0xfe04] |
mov [ecx+RECT.bottom],eax |
;set window state to 'normal' (non-minimized/maximized/rolled-up) state |
mov [ecx+WDATA.fl_wstate],WSTATE_NORMAL |
;set cr3 register in TSS of application |
mov ecx,[new_process_place] |
shl ecx,8 |
mov eax,[0x80000+APPDATA.dir_table+ecx] |
add eax,8+16 ;add flags |
mov [l.cr3],eax |
mov eax,[app_start] |
mov [l.eip],eax ;set eip in TSS |
mov eax,[app_esp] |
mov [l.esp],eax ;set stack in TSS |
;gdt |
;mov ebx,[new_process_place] |
;shl ebx,3 |
mov ax,app_code ;ax - selector of code segment |
;add ax,bx |
mov [l.cs],ax |
mov ax,app_data |
;add ax,bx ;ax - selector of data segment |
mov [l.ss],ax |
mov [l.ds],ax |
mov [l.es],ax |
mov [l.fs],ax |
mov ax,graph_data ;ax - selector of graphic segment |
mov [l.gs],ax |
mov [l.io],word 128 |
mov [l.eflags],dword 0x11202 |
mov [l.ss0],os_data |
mov ebx,[new_process_place] |
shl ebx,12 |
add ebx,sysint_stack_data+4096 |
mov [l.esp0],ebx |
;copy tss to it place |
mov eax,tss_sceleton |
mov ebx,[new_process_place] |
imul ebx,tss_step |
add ebx,tss_data ;ebx - address of application TSS |
mov ecx,120 |
call memmove |
;Add IO access table - bit array of permitted ports |
or eax,-1 |
mov edi,[new_process_place] |
imul edi,tss_step |
add edi,tss_data+128 |
mov ecx,2048 |
cld |
rep stosd ;full access to 2048*8=16384 ports |
mov ecx,ebx ;ecx - address of application TSS |
mov edi,[new_process_place] |
shl edi,3 |
;set TSS descriptor |
mov [edi+gdts+tss0+0],word tss_step ;limit (size) |
mov [edi+gdts+tss0+2],cx ;part of offset |
mov eax,ecx |
shr eax,16 |
mov [edi+gdts+tss0+4],al ;part of offset |
mov [edi+gdts+tss0+7],ah ;part of offset |
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags |
;flush keyboard and buttons queue |
mov [0xf400],byte 0 |
mov [0xf500],byte 0 |
mov edi,[new_process_place] |
shl edi,5 |
add edi,window_data |
mov ebx,[new_process_place] |
movzx esi,word [0xC000+ebx*2] |
lea esi,[0xC400+esi*2] |
call windowactivate ;gui initialization |
mov ebx,[new_process_place] |
shl ebx,5 |
; set if debuggee |
test byte [esp+28], 1 |
jz .no_debug |
mov [0x3000+ebx+TASKDATA.state], 1 ; set process state - suspended |
mov eax, [0x3000] |
mov [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current |
jmp .debug |
.no_debug: |
mov [0x3000+ebx+TASKDATA.state], 0 ; set process state - running |
.debug: |
mov esi,new_process_running |
call sys_msg_board_str ;output information about succefull startup |
; add esp,4 ;pop pointer to parameters |
; popad |
mov eax,[process_number] ;set result |
mov [application_table_status],0 ;unlock application_table_status mutex |
call safe_sti |
ret 4 |
;----------------------------------------------------------------------------- |
new_sys_threads: |
;eax=1 - create thread |
; ebx=thread start |
; ecx=thread stack value |
;result: |
; eax=pid |
xor edx,edx ; flags=0 |
pushad |
cmp eax,1 |
jnz .ret ;other subfunctions |
mov esi,new_process_loading |
call sys_msg_board_str |
;lock application_table_status mutex |
.table_status: |
cli |
cmp [application_table_status],0 |
je .stf |
sti |
call change_task |
jmp .table_status |
.stf: |
call set_application_table_status |
;find free process slot |
call find_new_process_place |
test eax,eax |
jz .failed |
;set parameters for thread |
xor eax,eax |
mov [app_i_param],eax |
mov [app_i_icon],eax |
mov [app_start],ebx |
mov [app_esp],ecx |
mov esi,[0x3000] |
shl esi,8 |
add esi,0x80000+APPDATA.app_name |
mov ebx,esi ;ebx=esi - pointer to extended information about current thread |
mov edi,[new_process_place] |
shl edi,8 |
add edi,0x80000 |
lea edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread |
mov ecx,256/4 |
rep stosd ;clean extended information about new thread |
mov edi,edx |
mov ecx,11 |
rep movsb ;copy process name |
mov eax,[ebx+APPDATA.mem_size] |
mov [app_mem],eax ;set memory size |
mov eax,[ebx+APPDATA.dir_table] |
mov dword [edx-APPDATA.app_name+APPDATA.dir_table],eax ;copy page directory |
; mov eax,[new_process_place] |
; mov ebx,[0x3000] |
; call addreference_app_cr3_table |
push 0 ;no parameters |
call new_start_application_fl.add_app_parameters ;start thread |
mov [esp+28],eax |
popad |
ret |
.failed: |
sti |
popad |
mov eax,-1 |
ret |
.ret: |
popad |
ret |
;----------------------------------------------------------------------------- |
new_mem_resize: |
;input: |
; ebx - new size |
;result: |
; [esp+36]:=0 - normal |
; [esp+36]:=1 - error |
;This function set new application memory size. |
mov esi,ebx ;save new size |
add ebx,4095 |
and ebx,not (4096-1) ;round up size |
mov ecx,[0x3000] |
shl ecx,8 |
mov edx,[0x80000 + APPDATA.mem_size +ecx] |
add edx,4095 |
and edx,not (4096-1) ;old size |
mov eax,[0x80000 + APPDATA.dir_table+ecx] |
call MEM_Get_Linear_Address |
;eax - linear address of page directory |
call MEM_Heap_Lock ;guarantee that two threads willn't |
;change memory size simultaneously |
cmp ebx,edx |
; mov esi,ebx ;save new size |
jg .expand |
.free: |
sub edx,ebx |
jz .unlock ;do nothing |
mov ecx,edx |
shr ecx,12 |
add ebx,std_application_base_address |
call mem_free_specified_region ;free unnecessary pages |
jmp .unlock |
.expand: |
sub ebx,edx |
mov ecx,ebx |
shr ecx,12 |
mov ebx,edx |
add ebx,std_application_base_address |
call mem_alloc_specified_region ;alloc necessary pages |
test eax,eax |
jz .failed ;not enough memory |
.unlock: |
mov ebx,esi |
mov eax,[0x3000] |
shl eax,8 |
mov [eax+0x80000 + APPDATA.mem_size],ebx ;write new memory size |
;search threads and update |
;application memory size infomation |
mov ecx,[eax+0x80000 + APPDATA.dir_table] |
mov eax,2 |
.search_threads: |
;eax = current slot |
;ebx = new memory size |
;ecx = page directory |
cmp eax,[0x3004] |
jg .search_threads_end |
mov edx,eax |
shl edx,5 |
cmp word [0x3000+edx+TASKDATA.state],9 ;if slot empty? |
jz .search_threads_next |
shl edx,3 |
cmp [edx+0x80000+APPDATA.dir_table],ecx ;if it is our thread? |
jnz .search_threads_next |
mov [edx+0x80000+APPDATA.mem_size],ebx ;update memory size |
.search_threads_next: |
inc eax |
jmp .search_threads |
.search_threads_end: |
call MEM_Heap_UnLock |
mov dword [esp+36],0 |
ret |
.failed: |
call MEM_Heap_UnLock |
mov dword [esp+36],1 |
ret |
;----------------------------------------------------------------------------- |
pid_to_slot: |
;Input: |
; eax - pid of process |
;Output: |
; eax - slot of process or 0 if process don't exists |
;Search process by PID. |
push ebx |
push ecx |
mov ebx,[0x3004] |
shl ebx,5 |
mov ecx,2*32 |
.loop: |
;ecx=offset of current process info entry |
;ebx=maximum permitted offset |
cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 |
jz .endloop ;skip empty slots |
cmp [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID |
jz .pid_found |
.endloop: |
add ecx,32 |
cmp ecx,ebx |
jle .loop |
pop ecx |
pop ebx |
xor eax,eax |
ret |
.pid_found: |
shr ecx,5 |
mov eax,ecx ;convert offset to index of slot |
pop ecx |
pop ebx |
ret |
;----------------------------------------------------------------------------- |
is_new_process: |
;Input: |
; eax - process slot |
;Output: |
; eax=1 - it is new process |
; eax=0 - it is old process |
; shl eax,5 |
; mov eax,[second_base_address+0x3000+eax+0x10] |
; cmp eax,std_application_base_address ;check base address of application |
; jz .new_process |
; xor eax,eax |
; ret |
;.new_process: |
mov eax,1 |
ret |
;----------------------------------------------------------------------------- |
write_process_memory: |
;Input: |
; eax - process slot |
; ebx - buffer address |
; ecx - buffer size |
; edx - start address in other process |
;Output: |
; eax - number of bytes written |
pushad |
shl eax,8 |
mov eax,[0x80000+eax+APPDATA.dir_table] |
call MEM_Get_Linear_Address |
mov ebp,eax |
;ebp=linear address of page directory of other process. |
add edx,std_application_base_address ;convert to linear address |
test ecx,ecx |
jle .ret |
.write_loop: |
;ebx = current buffer address |
;ecx>0 = current size |
;edx = current address in other process |
;ebp = linear address of page directory |
call MEM_Heap_Lock ;cli |
mov esi,edx |
shr esi,22 |
mov eax,[ebp+4*esi] ;find page directory entry |
and eax,not (4096-1) ;clear flags |
test eax,eax |
jz .page_not_found |
call MEM_Get_Linear_Address ;calculate linear address of page table |
test eax,eax |
jz .page_not_found |
mov esi,edx |
shr esi,12 |
and esi,1023 |
mov eax,[eax+4*esi] ;find page table entry |
and eax,not (4096-1) |
test eax,eax |
jz .page_not_found |
call MEM_Get_Linear_Address ;calculate linear address of page |
test eax,eax |
jz .page_not_found |
mov edi,eax |
call MEM_Add_Reference_Linear;guarantee that page willn't disappear |
call MEM_Heap_UnLock ;sti |
mov esi,edx |
and esi,4095 |
add edi,esi ;add offset in page |
;edi = linear address corresponding edx in other process |
sub esi,4096 |
neg esi ;esi - number of remaining bytes in page |
cmp esi,ecx |
jl .min_ecx |
mov esi,ecx |
.min_ecx: ;esi=min(ecx,esi) - number of bytes to write |
sub ecx,esi |
push ecx |
mov ecx,esi ;ecx - number of bytes to write |
mov esi,ebx ;esi - source, edi - destination |
add edx,ecx ;move pointer in address space of other process |
push edi |
;move ecx bytes |
test ecx,3 |
jnz .not_aligned |
shr ecx,2 |
rep movsd |
jmp .next_iter |
.not_aligned: |
rep movsb |
.next_iter: |
pop eax |
and eax,not (4096-1) ;eax - linear address of current page |
call MEM_Free_Page_Linear ;free reference |
mov ebx,esi ;new pointer to buffer - movsb automaticaly advance it. |
pop ecx ;restore number of remaining bytes |
test ecx,ecx |
jnz .write_loop |
.ret: |
popad |
mov eax,ecx |
ret |
.page_not_found: |
call MEM_Heap_UnLock ;error has appeared in critical region |
sub ecx,[esp+24] ;[esp+24]<-->ecx |
neg ecx ;ecx=number_of_written_bytes |
mov [esp+28],ecx ;[esp+28]<-->eax |
popad |
ret |
;----------------------------------------------------------------------------- |
syscall_test: |
;for testing memory manager from applications. |
mov edx,ecx |
mov ecx,ebx |
call trans_address |
mov ebx,eax |
mov eax,[0x3000] |
call read_process_memory |
ret |
;----------------------------------------------------------------------------- |
read_process_memory: |
;Input: |
; eax - process slot |
; ebx - buffer address |
; ecx - buffer size |
; edx - start address in other process |
;Output: |
; eax - number of bytes read. |
pushad |
shl eax,8 |
mov eax,[0x80000+eax+APPDATA.dir_table] |
call MEM_Get_Linear_Address |
mov ebp,eax |
add edx,std_application_base_address |
.read_loop: |
;ebx = current buffer address |
;ecx>0 = current size |
;edx = current address in other process |
;ebp = linear address of page directory |
call MEM_Heap_Lock ;cli |
mov esi,edx |
shr esi,22 |
mov eax,[ebp+4*esi] ;find page directory entry |
and eax,not (4096-1) |
test eax,eax |
jz .page_not_found |
call MEM_Get_Linear_Address |
test eax,eax |
jz .page_not_found |
mov esi,edx |
shr esi,12 |
and esi,1023 |
mov eax,[eax+4*esi] ;find page table entry |
and eax,not (4096-1) |
test eax,eax |
jz .page_not_found |
call MEM_Get_Linear_Address ;calculate linear address of page |
test eax,eax |
jz .page_not_found |
mov esi,eax |
call MEM_Add_Reference_Linear;guarantee that page willn't disappear |
call MEM_Heap_UnLock ;sti |
mov edi,edx |
and edi,4095 |
add esi,edi ;add offset in page |
;esi = linear address corresponding edx in other process |
sub edi,4096 |
neg edi |
;edi=min(edi,ecx) - number of bytes to copy |
cmp edi,ecx |
jl .min_ecx |
mov edi,ecx |
.min_ecx: |
sub ecx,edi ;update size of remaining bytes |
add edx,edi ;update current pointer in other address space. |
push ecx |
mov ecx,edi ;ecx - number of bytes to read |
mov edi,ebx ;esi - source, edi - destination |
push esi |
;move ecx bytes |
test ecx,3 |
jnz .not_aligned |
shr ecx,2 |
rep movsd |
jmp .next_iter |
.not_aligned: |
rep movsb |
.next_iter: |
pop eax |
and eax,not (4096-1) ;eax - linear address of current page |
call MEM_Free_Page_Linear ;free reference |
mov ebx,edi ;new pointer to buffer - movsb automaticaly advance it. |
pop ecx ;restore number of remaining bytes |
test ecx,ecx |
jnz .read_loop |
popad |
mov eax,ecx |
ret |
.page_not_found: |
call MEM_Heap_UnLock ;error has appeared in critical region |
sub ecx,[esp+24] ;[esp+24]<-->ecx |
neg ecx ;ecx=number_of_read_bytes |
mov [esp+28],ecx ;[esp+28]<-->eax |
popad |
ret |
;----------------------------------------------------------------------------- |
check_region: |
;input: |
; ebx - start of buffer |
; ecx - size of buffer |
;result: |
; eax = 1 region lays in app memory |
; eax = 0 region don't lays in app memory |
mov eax,[0x3000] |
jmp check_process_region |
;----------------------------------------------------------------------------- |
check_process_region: |
;input: |
; eax - slot |
; ebx - start of buffer |
; ecx - size of buffer |
;result: |
; eax = 1 region lays in app memory |
; eax = 0 region don't lays in app memory |
test ecx,ecx |
jle .ok |
shl eax,5 |
cmp word [0x3000+eax+TASKDATA.state],0 |
jnz .failed |
shl eax,3 |
mov eax,[0x80000+eax+APPDATA.dir_table] |
test eax,eax |
jz .failed |
call MEM_Get_Linear_Address |
push ebx |
push ecx |
push edx |
mov edx,ebx |
and edx,not (4096-1) |
sub ebx,edx |
add ecx,ebx |
mov ebx,edx |
add ecx,(4096-1) |
and ecx,not (4096-1) |
.loop: |
;eax - linear address of page directory |
;ebx - current page |
;ecx - current size |
mov edx,ebx |
shr edx,22 |
mov edx,[eax+4*edx] |
and edx,not (4096-1) |
test edx,edx |
jz .failed1 |
push eax |
mov eax,edx |
call MEM_Get_Linear_Address |
mov edx,ebx |
shr edx,12 |
and edx,(1024-1) |
mov eax,[eax+4*edx] |
and eax,not (4096-1) |
test eax,eax |
pop eax |
jz .failed1 |
add ebx,4096 |
sub ecx,4096 |
jg .loop |
pop edx |
pop ecx |
pop ebx |
.ok: |
mov eax,1 |
ret |
.failed1: |
pop edx |
pop ecx |
pop ebx |
.failed: |
xor eax,eax |
ret |
;----------------------------------------------------------------------------- |
new_sys_ipc: |
;input: |
; eax=1 - set ipc buffer area |
; ebx=address of buffer |
; ecx=size of buffer |
; eax=2 - send message |
; ebx=PID |
; ecx=address of message |
; edx=size of message |
cmp eax,1 |
jnz .no_ipc_def |
;set ipc buffer area |
mov edi,[0x3000] |
shl edi,8 |
add edi,0x80000 |
cli |
mov [edi+APPDATA.ipc_start],ebx ;set fields in extended information area |
mov [edi+APPDATA.ipc_size],ecx |
sti |
mov [esp+36],dword 0 ;success |
ret |
.no_ipc_def: |
cmp eax,2 |
jnz .no_ipc_send |
;send message |
cli |
;obtain slot from PID |
mov eax,ebx |
call pid_to_slot |
test eax,eax |
jz .no_pid |
mov ebp,eax |
;ebp = slot of other process |
shl eax,8 |
mov edi,[eax+0x80000+APPDATA.ipc_start] ;is ipc area defined? |
test edi,edi |
jz .no_ipc_area |
mov esi,[eax+0x80000+APPDATA.ipc_size] ;esi - size of buffer |
push dword -1 ;temp variable for read_process_memory |
mov ebx,esp |
push ecx |
push edx |
mov ecx,4 ;read 4 bytes |
mov eax,ebp |
mov edx,edi ;from beginning of buffer. |
call read_process_memory |
mov eax,[esp+8] |
test eax,eax |
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now |
add edx,4 ;move to next 4 bytes |
mov eax,ebp |
call read_process_memory ;read size of occupied space in buffer |
sub esi,8 |
sub esi,[esp] |
sub esi,[esp+8] ;esi=(buffer size)-(occupied size)-(message size)-(header of message size) |
js .buffer_overflow ;esi<0 - not enough memory in buffer |
mov esi,[esp+8] ;previous offset |
add dword [esp+8],8 |
mov edi,[esp] |
add [esp+8],edi ;add (size of message)+(size of header of message) to [buffer+4] |
mov eax,ebp |
call write_process_memory |
add edx,esi |
sub edx,4 ;move to beginning of place for our message |
mov eax,[second_base_address+0x3010] |
mov eax,[eax+TASKDATA.pid] ;eax - our PID |
mov [esp+8],eax |
mov eax,ebp |
call write_process_memory ;write PID |
mov ebx,esp ;address of size of message |
mov eax,ebp |
add edx,4 |
call write_process_memory ;write size of message |
add edx,4 |
pop ecx ;ecx - size of message |
pop eax |
call trans_address |
mov ebx,eax ;ebx - linear address of message |
add esp,4 ;pop temporary variable |
mov eax,ebp |
call write_process_memory ;write message |
sti |
;awake other process |
shl ebp,8 |
mov eax,ebp |
or [eax+0x80000+APPDATA.event_mask],dword 0x40 |
cmp dword [check_idle_semaphore],20 |
jge .ipc_no_cis |
mov dword [check_idle_semaphore],5 |
.ipc_no_cis: |
mov dword [esp+36],0 |
ret |
.no_ipc_send: |
mov dword [esp+36],-1 |
ret |
.no_pid: |
sti |
mov dword [esp+36],4 |
ret |
.no_ipc_area: |
sti |
mov dword [esp+36],1 |
ret |
.ipc_blocked: |
sti |
add esp,12 |
mov dword [esp+36],2 |
ret |
.buffer_overflow: |
sti |
add esp,12 |
mov dword [esp+36],3 |
ret |
;----------------------------------------------------------------------------- |
trans_address: |
;Input |
; eax - application address |
;Output |
; eax - linear address for kernel |
add eax,std_application_base_address |
ret |
;----------------------------------------------------------------------------- |
new_start_application_hd: |
;eax - file name (kernel address) |
;ebx - file name length |
;ecx - work area (kernel address) |
;edx - flags |
;ebp - parameters |
mov [appl_path],edi |
pushad |
mov esi,new_process_loading |
call sys_msg_board_str ;write message to message board |
;lock application_table_status mutex |
.table_status: |
cli |
cmp [application_table_status],0 |
jz .stf |
sti |
call change_task |
jmp .table_status |
.stf: |
call set_application_table_status |
push ebp |
push ebx |
push eax |
push ecx |
call find_new_process_place ;find new process slot |
sti |
test eax,eax |
mov ecx, -0x20 ; too many processes |
jz .failed |
;write application name |
xor eax,eax |
mov [appl_path_size],eax |
mov eax,[esp+4] |
.find_last_byte: |
cmp byte [eax],0 |
jz .find_last_byte_end |
inc eax |
inc [appl_path_size] |
jmp .find_last_byte |
.find_last_byte_end: |
add [appl_path_size],24 |
lea esi,[eax-11] ;last 11 bytes = application name |
mov edi,[new_process_place] |
shl edi,8 |
add edi,0x80000+APPDATA.app_name |
mov ecx,11 |
cld |
rep movsb ;copy name to extended information about process |
;read header |
mov eax,[esp+4] ;file name |
mov esi,[esp] ;work area |
mov ecx,1 ;read from first block |
mov edx,1 ;read 1 block |
call read_hd_file |
mov ecx, eax |
neg ecx |
jnz .cleanfailed |
pop esi |
push esi |
;check menuet signature |
mov ecx, -0x1F ; not Menuet/Kolibri executable |
cmp [esi+1024+0],dword 'MENU' ;read_hd_file function write file to +1024 offset |
jnz .cleanfailed |
cmp [esi+1024+4],word 'ET' |
jnz .cleanfailed |
add esi,1024 |
mov edi,0x90000 |
mov ecx,512/4 |
cld |
rep movsd ;copy first block to 0x90000 address for get_app_params function |
call get_app_params |
mov ecx, -0x1F ; not Menuet/Kolibri executable |
test esi,esi |
jz .cleanfailed |
mov eax,[new_process_place] |
inc ecx ; -0x1E = no memory |
call create_app_cr3_table ;create page directory |
test eax,eax |
jz .cleanfailed_mem |
call MEM_Get_Linear_Address |
mov ebx,std_application_base_address |
mov ecx,[app_mem] |
add ecx,4096-1 |
shr ecx,12 |
mov edx,eax ;edx - linear address of page directory |
call mem_alloc_specified_region ;allocate memory for application |
mov ecx, -0x1E ; no memory |
test eax,eax |
jz .cleanfailed_mem1 |
add edx,(std_application_base_address shr 20) |
mov eax,[edx] |
and eax,not (4096-1) |
call MEM_Get_Linear_Address |
push edx ;save pointer to first page table |
mov edx,eax |
;read file |
mov ecx,1 |
xor ebp,ebp |
.loop1: |
;[esp] - pointer to current page directory entry |
;edx - pointer to current page table |
;ebp - offset in page |
;ecx - current cluster |
push edx |
mov eax,[esp+12] ;file name |
mov ebx,[esp+16] ;file name length |
mov esi,[esp+8] ;work area |
mov edx,1 ;number of blocks to read |
push ecx |
push ebp |
cli |
call read_hd_file |
sti |
pop ebp |
test eax,eax |
jnz .endloop1 ;check io errors |
mov esi,[esp+8+4] ;work area |
add esi,1024 |
mov eax,[esp+4] ;current page table |
mov eax,[eax] |
and eax,not (4096-1) |
call MEM_Get_Linear_Address;calculate linear page address |
lea edi,[eax+ebp] ;add page offset |
mov ecx,512/4 |
cld |
rep movsd ;copy data |
pop ecx |
inc ecx ;next block |
mov eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096 |
add eax,512-1 |
shr eax,9 ;calculate application image size |
cmp ecx,eax |
jg .endloop11 |
pop edx |
add ebp,512 ;new offset |
test ebp,4096 |
jz .loop1 |
xor ebp,ebp |
add edx,4 ;go to next page |
test edx,(4096-1) |
jnz .loop1 |
add dword [esp],4 ;go to next directory entry |
mov eax,[esp] |
mov eax,[eax] |
and eax,not (4096-1) |
call MEM_Get_Linear_Address |
mov edx,eax |
jmp .loop1 |
.endloop1: |
add esp,4 ;pop ecx |
.endloop11: |
add esp,4+4 ;pop edx, pop edx |
;add_app_parameters |
add esp,12 ;now pointer to parameters is on the top of the stack |
call new_start_application_fl.add_app_parameters ;start process |
mov [esp+28],eax |
popad |
ret |
.cleanfailed_mem1: |
;there is mem for directory entry, but there is no mem for pages |
;so free directory entry |
mov eax,[new_process_place] |
shl eax,8 |
mov eax,[0x80000+eax+APPDATA.dir_table] |
call MEM_Free_Page |
.cleanfailed_mem: |
;there is no mem for directory entry, display message. |
mov esi,start_not_enough_memory |
call sys_msg_board_str |
.cleanfailed: ;clean process name |
push ecx |
;can't read file, clean process name. |
;this avoid problems with panel application. |
mov edi,[new_process_place] |
shl edi,8 |
add edi,0x80000+APPDATA.app_name |
mov ecx,11 |
mov eax,' ' |
cld |
rep stosb |
pop eax |
.failed: |
;no more slots |
add esp,16 |
mov [esp+1Ch], eax |
popad |
mov [application_table_status],0 |
sti |
ret |
end if |
; \begin{diamond} |
include 'debug.inc' |
fs_execute: |
; ebx - cmdline |
; edx - flags |
; ebp - full filename |
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it |
pushad |
; check filename length - with terminating NULL must be no more than 1024 symbols |
mov edi, ebp |
mov ecx, 1024 |
xor eax, eax |
repnz scasb |
jz @f |
popad |
mov eax, -ERROR_FILE_NOT_FOUND |
ret |
@@: |
mov esi, new_process_loading |
call sys_msg_board_str ; write message to message board |
; lock application_table_status mutex |
.table_status: |
cli |
cmp [application_table_status], 0 |
jz .stf |
sti |
call change_task |
jmp .table_status |
.stf: |
call set_application_table_status |
push ebx ; save command line pointer for add_app_parameters |
call find_new_process_place ; find new process slot |
call safe_sti |
test eax, eax |
mov ecx, -0x20 ; too many processes |
jz .failed |
; write application name |
push edi |
mov ecx, edi |
sub ecx, ebp |
mov [appl_path], ebp |
mov [appl_path_size], ecx |
dec edi |
std |
mov al, '/' |
repnz scasb |
cld |
jnz @f |
inc edi |
@@: |
inc edi |
; now edi points to name without path |
mov esi, edi |
mov ecx, 8 ; 8 chars for name |
mov edi, [new_process_place] |
shl edi, cl |
add edi, 0x80000+APPDATA.app_name |
.copy_process_name_loop: |
lodsb |
cmp al, '.' |
jz .copy_process_name_done |
test al, al |
jz .copy_process_name_done |
stosb |
loop .copy_process_name_loop |
.copy_process_name_done: |
mov al, ' ' |
rep stosb |
pop eax |
mov cl, 3 ; 3 chars for extension |
dec esi |
@@: |
dec eax |
cmp eax, esi |
jbe .copy_process_ext_done |
cmp byte [eax], '.' |
jnz @b |
lea esi, [eax+1] |
.copy_process_ext_loop: |
lodsb |
test al, al |
jz .copy_process_ext_done |
stosb |
loop .copy_process_ext_loop |
.copy_process_ext_done: |
mov al, ' ' |
rep stosb |
; read header |
lea eax, [esp+8+36] |
mov edi, 0x90000 |
call dword [eax-4] |
mov ecx, eax |
neg ecx |
jnz .cleanfailed |
; check menuet signature |
mov ecx, -0x1F |
cmp dword [0x90000], 'MENU' |
jnz .cleanfailed |
cmp word [0x90004], 'ET' |
jnz .cleanfailed |
call get_app_params |
mov ecx, -0x1F |
test esi, esi |
jz .cleanfailed |
mov eax, [new_process_place] |
inc ecx ; -0x1E = no memory |
call create_app_cr3_table |
test eax, eax |
jz .cleanfailed_mem |
call MEM_Get_Linear_Address |
mov ebx, std_application_base_address |
mov ecx, [app_mem] |
add ecx, 4095 |
shr ecx, 12 |
mov edx, eax ; edx - linear address of page directory |
call mem_alloc_specified_region |
mov ecx, -0x1E ; no memory |
test eax, eax |
jz .cleanfailed_mem1 |
add edx, std_application_base_address shr 20 |
mov eax, [edx] |
and eax, not 4095 |
call MEM_Get_Linear_Address |
push edx ; save pointer to first page table |
mov edx, eax |
; read file |
; first block is already read to 0x90000 |
mov eax, [edx] |
and eax, not 0xFFF |
call MEM_Get_Linear_Address |
mov esi, 0x90000 |
mov edi, eax |
mov ecx, 512/4 |
rep movsd |
sub edi, eax |
.loop1: |
; [esp] = pointer to current page directory entry |
; edx = pointer to current page table |
; edi = offset in page |
mov eax, [edx] |
and eax, not 0xFFF |
call MEM_Get_Linear_Address |
push edi |
add edi, eax |
lea eax, [esp+8+36+8] |
call dword [eax-4] |
pop edi |
test eax, eax |
jnz .endloop1 |
add edi, 512 ; new offset |
cmp edi, 4096 |
jb .loop1 |
xor edi, edi |
add edx, 4 ; go to next page |
test edx, 4096-1 |
jnz .loop1 |
pop eax |
add eax, 4 ; go to next directory entry |
push eax |
mov eax, [eax] |
and eax, not 0xFFF |
call MEM_Get_Linear_Address |
mov edx, eax |
jmp .loop1 |
.endloop1: |
pop edx |
cmp eax, 6 |
jnz .cleanfailed_mem2 |
call new_start_application_fl.add_app_parameters |
mov [esp+28], eax |
popad |
ret |
.cleanfailed_mem2: |
; file read error; free all allocated mem |
mov ecx, eax |
neg ecx |
mov eax, [new_process_place] |
call dispose_app_cr3_table |
jmp .cleanfailed |
.cleanfailed_mem1: |
; there is mem for directory entry, but there is no mem for pages |
; so free directory entry |
mov eax, [new_process_place] |
shl eax, 8 |
mov eax, [0x80000+eax+0xB8] |
call MEM_Free_Page |
.cleanfailed_mem: |
; there is no mem for directory entry, display message |
mov esi, start_not_enough_memory |
call sys_msg_board_str |
.cleanfailed: |
push ecx |
; clean process name, this avoid problems with @panel |
mov edi, [new_process_place] |
shl edi, 8 |
add edi, 0x80000+APPDATA.app_name |
mov ecx, 11 |
mov al, ' ' |
rep stosb |
pop eax |
.failed: |
pop ebx |
mov [esp+28], eax |
popad |
mov [application_table_status], 0 |
call safe_sti |
ret |
; \end{diamond} |
/kernel/branches/gfx_kernel/core/physmem.inc |
---|
0,0 → 1,220 |
virtual at 0 |
physical_mem_block: |
.start rd 1 |
.size rd 1 |
.flags rd 1 ;0-free, pid-used. |
.sizeof: |
end virtual |
max_physical_mem_blocks = 24 |
uglobal |
num_physical_mem_blocks rd 1 |
physical_mem_blocks rd 3*max_physical_mem_blocks |
endg |
Init_Physical_Memory_Manager: |
pushad |
mov edi,physical_mem_blocks |
mov ecx,3*max_physical_mem_blocks |
xor eax,eax |
cld |
rep stosd |
mov dword [num_physical_mem_blocks],2 |
mov [physical_mem_blocks+physical_mem_block.start],0x60000 |
mov [physical_mem_blocks+physical_mem_block.size],0x20000 ;128Kb |
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.start],0x780000 |
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.size],0x80000 ;512Kb |
popad |
ret |
Insert_Block: |
;input: |
; eax - handle |
;output: |
; none |
push eax ecx esi edi |
sub eax,[num_physical_mem_blocks] |
neg eax |
mov edi,physical_mem_block.sizeof |
imul eax,edi |
shr eax,2 |
mov ecx,eax |
mov esi,[num_physical_mem_blocks] |
imul esi,edi |
add esi,physical_mem_blocks |
lea edi,[esi+physical_mem_block.sizeof] |
std |
rep movsd |
pop edi esi ecx eax |
ret |
Delete_Block: |
;input: |
; eax - handle |
;output: |
; none |
pushad |
mov edi,eax |
sub eax,[num_physical_mem_blocks] |
neg eax |
dec eax |
mov esi,physical_mem_block.sizeof |
imul eax,esi |
imul edi,esi |
add edi,physical_mem_blocks |
lea esi,[edi+physical_mem_block.sizeof] |
mov ecx,eax |
shr ecx,2 |
cld |
rep movsd |
popad |
ret |
Allocate_Physical_Block: |
;input: |
; eax - size |
;output: |
; eax - address or 0 if not enough memory. |
pushad |
cmp [num_physical_mem_blocks],max_physical_mem_blocks |
jge .error |
mov ebx,eax |
xor eax,eax |
mov esi,physical_mem_blocks |
.loop: |
cmp dword [esi+physical_mem_block.flags],0 |
jnz .next |
cmp [esi+physical_mem_block.size],ebx |
jg .addblock |
jz .noaddblock |
.next: |
inc eax |
add esi,physical_mem_block.sizeof |
cmp eax,[num_physical_mem_blocks] |
jl .loop |
.error: |
popad |
xor eax,eax |
ret |
.noaddblock: |
mov eax,[esi+physical_mem_block.start] |
mov [esp+28],eax |
mov eax,[0x3010] |
mov eax,[eax+TASKDATA.pid] |
mov [esi+physical_mem_block.flags],eax |
popad |
ret |
.addblock: |
call Insert_Block |
inc dword [num_physical_mem_blocks] |
mov eax,[esi+physical_mem_block.start] |
mov [esp+28],eax |
mov ecx,[0x3010] |
mov ecx,[ecx+TASKDATA.pid] |
mov [esi+physical_mem_block.flags],ecx |
mov ecx,[esi+physical_mem_block.size] |
mov [esi+physical_mem_block.size],ebx |
sub ecx,ebx |
mov [esi+physical_mem_block.sizeof+physical_mem_block.size],ecx |
add ebx,[esi+physical_mem_block.start] |
mov [esi+physical_mem_block.sizeof+physical_mem_block.start],ebx |
mov dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0 |
popad |
ret |
Free_Physical_Block: |
;input: |
; eax - address |
;output: |
; none |
pushad |
test eax,eax |
jz .ret |
mov ebx,eax |
xor eax,eax |
mov esi,physical_mem_blocks |
.loop: |
cmp ebx,[esi+physical_mem_block.start] |
jz .endloop |
inc eax |
add esi,physical_mem_block.sizeof |
cmp eax,[num_physical_mem_blocks] |
jl .loop |
jmp .ret |
.endloop: |
mov dword [esi+physical_mem_block.flags],0 |
test eax,eax |
jz .no_union_previous |
cmp dword [esi-physical_mem_block.sizeof+physical_mem_block.flags],0 |
jnz .no_union_previous |
mov ebx,[esi-physical_mem_block.sizeof+physical_mem_block.start] |
add ebx,[esi-physical_mem_block.sizeof+physical_mem_block.size] |
cmp ebx,[esi+physical_mem_block.start] |
jnz .no_union_previous |
mov ebx,[esi+physical_mem_block.size] |
add [esi-physical_mem_block.sizeof+physical_mem_block.size],ebx |
call Delete_Block |
dec eax |
dec [num_physical_mem_blocks] |
.no_union_previous: |
inc eax |
cmp eax,[num_physical_mem_blocks] |
jge .no_union_next |
cmp dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0 |
jnz .no_union_next |
mov ebx,[esi+physical_mem_block.start] |
add ebx,[esi+physical_mem_block.size] |
cmp ebx,[esi+physical_mem_block.sizeof+physical_mem_block.start] |
jnz .no_union_next |
mov ebx,[esi+physical_mem_block.sizeof+physical_mem_block.size] |
add [esi+physical_mem_block.size],ebx |
call Delete_Block |
dec [num_physical_mem_blocks] |
.no_union_next: |
.ret: |
popad |
ret |
sys_allocate_physical_block: |
;eax - subfunction number |
mov eax,ebx |
call Allocate_Physical_Block |
mov [esp+36],eax |
ret |
sys_free_physical_block: |
;eax - subfunction number |
mov eax,ebx |
call Free_Physical_Block |
ret |
sys_set_buffer: |
add ecx,std_application_base_address |
isys_set_buffer: ;for using in kernel |
;eax - subfunction number |
;ebx - physical address |
;ecx - buffer start |
;edx - buffer size |
lea edi,[ebx+second_base_address] |
mov esi,ecx |
mov ecx,edx |
cld |
rep movsb |
ret |
sys_get_buffer: |
add ecx,std_application_base_address |
isys_get_buffer: ;for using in kernel |
;eax - subfunction number |
;ebx - physical address |
;ecx - buffer start |
;edx - buffer size |
mov edi,ecx |
lea esi,[ebx+second_base_address] |
mov ecx,edx |
cld |
rep movsb |
ret |
sys_internal_services: |
cmp eax,4 |
jle sys_sheduler |
cmp eax,5 |
jz sys_allocate_physical_block |
cmp eax,6 |
jz sys_free_physical_block |
cmp eax,7 |
jz sys_set_buffer |
cmp eax,8 |
jz sys_get_buffer |
ret |
/kernel/branches/gfx_kernel/core/sched.inc |
---|
0,0 → 1,191 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; IRQ0 HANDLER (TIMER INTERRUPT) ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
irq0: |
save_ring3_context |
mov ax, os_data |
mov ds, ax |
mov es, ax |
inc dword [timer_ticks] |
mov eax, [timer_ticks] |
call playNote ; <<<--- Speaker driver |
cmp eax,[next_usage_update] |
jb .nocounter |
add eax,100 |
mov [next_usage_update],eax |
call updatecputimes |
.nocounter: |
cmp [0xffff], byte 1 |
jne .change_task |
mov al,0x20 ; send End Of Interrupt signal |
mov dx,0x20 |
out dx,al |
mov [0xffff], byte 0 |
restore_ring3_context |
iret |
.change_task: |
call update_counters |
call find_next_task |
mov ecx, eax |
mov al,0x20 ; send End Of Interrupt signal |
mov dx,0x20 |
out dx,al |
test ecx, ecx ; if there is only one running process |
jnz .return |
call do_change_task |
.return: |
restore_ring3_context |
iret |
align 4 |
change_task: |
pushfd |
cli |
pushad |
call update_counters |
call find_next_task |
test eax, eax ; the same task -> skip switch |
jnz .return |
mov [0xffff],byte 1 |
call do_change_task |
.return: |
popad |
popfd |
ret |
uglobal |
align 4 |
far_jump: |
.offs dd ? |
.sel dw ? |
context_counter dd ? ;noname & halyavin |
next_usage_update dd ? |
timer_ticks dd ? |
prev_slot dd ? |
event_sched dd ? |
endg |
update_counters: |
mov edi, [0x3010] |
mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add |
call _rdtsc |
sub eax, ebx |
add eax, [edi+TASKDATA.counter_sum] ; counter sum |
mov [edi+TASKDATA.counter_sum], eax |
ret |
; Find next task to execute |
; result: ebx = number of the selected task |
; eax = 1 if the task is the same |
; edi = address of the data for the task in ebx |
; [0x3000] = ebx and [0x3010] = edi |
; corrupts other regs |
find_next_task: |
mov ebx, [0x3000] |
mov edi, [0x3010] |
mov [prev_slot], ebx |
.waiting_for_termination: |
.waiting_for_reuse: |
.waiting_for_event: |
.suspended: |
cmp ebx, [0x3004] |
jb @f |
mov edi, 0x3000 |
xor ebx, ebx |
@@: |
add edi,0x20 |
inc ebx |
mov al, byte [edi+TASKDATA.state] |
test al, al |
jz .found |
cmp al, 1 |
jz .suspended |
cmp al, 2 |
jz .suspended |
cmp al, 3 |
je .waiting_for_termination |
cmp al, 4 |
je .waiting_for_termination |
cmp al, 9 |
je .waiting_for_reuse |
mov [0x3000],ebx |
mov [0x3010],edi |
cmp al, 5 |
jne .noevents |
call get_event_for_app |
test eax, eax |
jz .waiting_for_event |
mov [event_sched], eax |
mov [edi+TASKDATA.state], byte 0 |
.noevents: |
.found: |
mov [0x3000],ebx |
mov [0x3010],edi |
call _rdtsc |
mov [edi+TASKDATA.counter_add],eax |
xor eax, eax |
cmp ebx, [prev_slot] |
sete al |
ret |
; in: ebx = TSS selector index |
do_change_task: |
shl ebx, 3 |
xor eax, eax |
add ebx, tss0 |
mov [far_jump.sel], bx ; selector |
mov [far_jump.offs], eax ; offset |
jmp pword [far_jump] |
inc [context_counter] ;noname & halyavin |
ret |
align 4 |
updatecputimes: |
mov eax,[idleuse] |
mov [idleusesec],eax |
mov [idleuse],dword 0 |
mov ecx, [0x3004] |
mov edi, 0x3020 |
.newupdate: |
mov ebx,[edi+TASKDATA.counter_sum] |
mov [edi+TASKDATA.cpu_usage],ebx |
mov [edi+TASKDATA.counter_sum],dword 0 |
add edi,0x20 |
dec ecx |
jnz .newupdate |
ret |
/kernel/branches/gfx_kernel/core/sync.inc |
---|
0,0 → 1,111 |
if ~defined sync_inc |
sync_inc_fix: |
sync_inc fix sync_inc_fix |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;Synhronization for MenuetOS. ;; |
;;Author: Halyavin Andrey, halyavin@land.ru ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;simplest mutex. |
macro SimpleMutex name |
{ |
; iglobal |
name dd 0 |
name#.type = 1 |
; endg |
} |
macro WaitSimpleMutex name |
{ |
local start_wait,ok |
start_wait=$ |
cli |
cmp [name],dword 0 |
jz ok |
sti |
call change_task |
jmp start_wait |
ok=$ |
push eax |
mov eax,dword [0x3010+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
mov [name],eax |
pop eax |
sti |
} |
macro ReleaseSimpleMutex name |
{ |
mov [name],dword 0 |
} |
macro TryWaitSimpleMutex name ;result in eax and in flags |
{ |
local ok,try_end |
cmp [name],dword 0 |
jz ok |
xor eax,eax |
jmp try_end |
ok=$ |
xor eax,eax |
inc eax |
try_end=$ |
} |
macro SimpleCriticalSection name |
{ |
; iglobal |
name dd 0 |
dd 0 |
name#.type=2 |
; endg |
} |
macro WaitSimpleCriticalSection name |
{ |
local start_wait,first_wait,inc_counter,end_wait |
push eax |
mov eax,[0x3010+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
start_wait=$ |
cli |
cmp [name],dword 0 |
jz first_wait |
cmp [name],eax |
jz inc_counter |
sti |
call change_task |
jmp start_wait |
first_wait=$ |
mov [name],eax |
mov [name+4],dword 1 |
jmp end_wait |
inc_counter=$ |
inc dword [name+4] |
end_wait=$ |
sti |
pop eax |
} |
macro ReleaseSimpleCriticalSection name |
{ |
local release_end |
dec dword [name+4] |
jnz release_end |
mov [name],dword 0 |
release_end=$ |
} |
macro TryWaitSimpleCriticalSection name ;result in eax and in flags |
{ |
local ok,try_end |
mov eax,[0x3000+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
cmp [name],eax |
jz ok |
cmp [name],0 |
jz ok |
xor eax,eax |
jmp try_end |
ok=$ |
xor eax,eax |
inc eax |
try_end=$ |
} |
_cli equ call MEM_HeapLock |
_sti equ call MEM_HeapUnLock |
end if |
/kernel/branches/gfx_kernel/core/sys32.inc |
---|
0,0 → 1,1017 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; MenuetOS process management, protected ring3 ;; |
;; ;; |
;; Distributed under GPL. See file COPYING for details. ;; |
;; Copyright 2003 Ville Turjanmaa ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
; GDT TABLE |
gdts: |
dw gdte-$-1 |
dd gdts |
dw 0 |
int_code_l: |
os_code_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10011010b |
db 0x00 |
int_data_l: |
os_data_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10010010b |
db 0x00 |
; --------------- APM --------------------- |
apm_code_32: |
dw 0x10 ; limit 64kb |
db 0, 0, 0 |
dw 11011111b *256 +10011010b |
db 0x00 |
apm_code_16: |
dw 0x10 |
db 0, 0, 0 |
dw 10011111b *256 +10011010b |
db 0x00 |
apm_data_16: |
dw 0x10 |
db 0, 0, 0 |
dw 10011111b *256 +10010010b |
db 0x00 |
; ----------------------------------------- |
app_code_l: |
dw ((0x80000000-std_application_base_address) shr 12) and 0xffff |
dw 0 |
db 0 |
dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28) |
db std_application_base_address shr 24 |
app_data_l: |
dw (0x80000000-std_application_base_address) shr 12 and 0xffff |
dw 0 |
db 0 |
dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28) |
db std_application_base_address shr 24 |
graph_data_l: |
dw 0x3ff |
dw 0x0000 |
db 0x00 |
dw 11010000b *256 +11110010b |
db 0x00 |
tss0_l: |
times (max_processes+10) dd 0,0 |
gdte: |
idtreg: |
dw 8*0x41-1 |
dd idts+8 |
label idts at 0xB100-8 |
uglobal |
tss_sceleton: |
l.back dw 0,0 |
l.esp0 dd 0 |
l.ss0 dw 0,0 |
l.esp1 dd 0 |
l.ss1 dw 0,0 |
l.esp2 dd 0 |
l.ss2 dw 0,0 |
l.cr3 dd 0 |
l.eip dd 0 |
l.eflags dd 0 |
l.eax dd 0 |
l.ecx dd 0 |
l.edx dd 0 |
l.ebx dd 0 |
l.esp dd 0 |
l.ebp dd 0 |
l.esi dd 0 |
l.edi dd 0 |
l.es dw 0,0 |
l.cs dw 0,0 |
l.ss dw 0,0 |
l.ds dw 0,0 |
l.fs dw 0,0 |
l.gs dw 0,0 |
l.ldt dw 0,0 |
l.trap dw 0 |
l.io dw 0 |
endg |
build_process_gdt_tss_pointer: |
mov ecx,tss_data |
mov edi,0 |
setgdtl2: |
mov [edi+gdts+ tss0 +0], word tss_step |
mov [edi+gdts+ tss0 +2], cx |
mov eax,ecx |
shr eax,16 |
mov [edi+gdts+ tss0 +4], al |
mov [edi+gdts+ tss0 +7], ah |
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b |
add ecx,tss_step |
add edi,8 |
cmp edi,8*(max_processes+5) |
jbe setgdtl2 |
ret |
build_interrupt_table: |
mov edi, idts+8 |
mov esi, sys_int |
mov ecx, 0x40 |
@@: |
mov eax, [esi] |
mov [edi], ax ; lower part of offset |
mov [edi+2], word os_code ; segment selector |
shr eax, 16 |
mov [edi+4], word 10001110b shl 8 ; interrupt descriptor |
mov [edi+6], ax |
add esi, 4 |
add edi, 8 |
dec ecx |
jnz @b |
;mov edi,8*0x40+idts+8 |
mov [edi + 0], word (i40 and ((1 shl 16)-1)) |
mov [edi + 2], word os_code |
mov [edi + 4], word 11101110b*256 |
mov [edi + 6], word (i40 shr 16) |
ret |
iglobal |
sys_int: |
dd e0,debug_exc,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15 |
dd e16,e17 |
times 14 dd unknown_interrupt |
dd irq0 ,irq1 ,p_irq2 ,p_irq3 ,p_irq4 ,p_irq5,p_irq6 ,p_irq7 |
dd p_irq8,p_irq9,p_irq10,p_irq11,p_irq12,irqD ,p_irq14,p_irq15 |
times 16 dd unknown_interrupt |
dd i40 |
endg |
macro save_ring3_context |
{ |
push ds es |
pushad |
} |
macro restore_ring3_context |
{ |
popad |
pop es ds |
} |
; simply return control to interrupted process |
unknown_interrupt: |
iret |
macro exc_wo_code [num] |
{ |
forward |
e#num : |
save_ring3_context |
mov bl, num |
jmp exc_c |
} |
macro exc_w_code [num] |
{ |
forward |
e#num : |
add esp, 4 |
save_ring3_context |
mov bl, num |
jmp exc_c |
} |
exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 16 ; 18, 19 |
exc_w_code 8, 10, 11, 12, 13, 14, 17 |
exc_c: |
mov ax, os_data |
mov ds, ax |
mov es, ax |
; test if debugging |
cli |
mov eax, [0x3000] |
shl eax, 8 |
mov eax, [0x80000+eax+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
sti |
; not debuggee => say error and terminate |
add esp, 28h |
movzx eax, bl |
mov [error_interrupt], eax |
call show_error_parameters |
mov edx, [0x3010] |
mov [edx + TASKDATA.state], byte 4 |
jmp change_task |
.debug: |
; we are debugged process, notify debugger and suspend ourself |
; eax=debugger PID |
cld |
movzx ecx, bl |
push ecx |
mov ecx, [0x3010] |
push dword [ecx+TASKDATA.pid] ; PID of current process |
push 12 |
pop ecx |
push 1 ; 1=exception |
call debugger_notify |
pop ecx |
pop ecx |
pop ecx |
mov edx, [0x3010] |
mov byte [edx+TASKDATA.state], 1 ; suspended |
call change_task |
restore_ring3_context |
iretd |
;;;;;;;;;;;;;;;;;;;;;;; |
;; FPU ERROR HANDLER ;; |
;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
e7: |
save_ring3_context |
clts |
mov ax, os_data |
mov ds, ax |
mov es, ax |
mov eax, [prev_user_of_fpu] |
shl eax, 8 |
add eax, 0x80000 + APPDATA.fpu_save_area |
fsave [eax] |
mov eax, [0x3000] |
mov [prev_user_of_fpu], eax |
shl eax, 8 |
add eax, 0x80000 |
cmp [eax + APPDATA.is_fpu_saved], 0 |
je @f |
frstor [eax+APPDATA.fpu_save_area] |
@@: |
mov [eax + APPDATA.is_fpu_saved], 1 |
restore_ring3_context |
iret |
iglobal |
prev_user_of_fpu dd 1 |
endg |
writehex: |
pusha |
mov edi, [write_error_to] |
mov esi, 8 |
@@: |
mov ecx, eax |
and ecx, 0xf |
mov cl,[ecx+hexletters] |
mov [edi],cl |
dec edi |
shr eax,4 |
dec esi |
jnz @b |
popa |
ret |
iglobal |
hexletters db '0123456789ABCDEF' |
error_interrupt dd -1 |
process_error db 'K : Process - forced terminate INT: 00000000',13,10,0 |
process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0 |
process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0 |
system_error db 'K : Kernel error',13,10,0 |
endg |
uglobal |
write_error_to dd 0x0 |
endg |
show_error_parameters: |
mov [write_error_to],process_pid+43 |
mov eax,[0x3000] |
shl eax, 5 |
mov eax,[0x3000+TASKDATA.pid+eax] |
call writehex |
mov [write_error_to],process_error+43 |
mov eax,[error_interrupt] |
call writehex |
cmp dword [esp+4+4], os_code ; CS |
jnz @f |
mov esi,system_error |
call sys_msg_board_str |
@@: |
mov eax, [esp+4] ; EIP |
mov [write_error_to],process_eip+43 |
call writehex |
mov esi,process_error |
call sys_msg_board_str |
mov esi,process_pid |
call sys_msg_board_str |
mov esi,process_eip |
call sys_msg_board_str |
ret |
; irq1 -> hid/keyboard.inc |
macro irqh [num] |
{ |
forward |
p_irq#num : |
save_ring3_context |
mov edi, num |
jmp irq_c |
} |
irqh 2,5,7,8,9,10,11,14,15 |
irq_c: |
mov ax, os_data |
mov ds, ax |
mov es, ax |
call irqhandler |
restore_ring3_context |
iret |
p_irq6: |
save_ring3_context |
mov ax, os_data |
mov ds, ax |
mov es, ax |
call fdc_irq |
call ready_for_next_irq |
restore_ring3_context |
iret |
p_irq3: |
save_ring3_context |
mov ax, os_data |
mov ds, ax |
mov es, ax |
cmp [com2_mouse_detected],0 |
je old_irq3_handler |
call check_mouse_data_com2 |
jmp p_irq3_1 |
old_irq3_handler: |
mov edi,3 |
call irqhandler |
p_irq3_1: |
restore_ring3_context |
iret |
p_irq4: |
save_ring3_context |
mov ax, os_data |
mov ds, ax |
mov es, ax |
cmp [com1_mouse_detected],0 |
je old_irq4_handler |
call check_mouse_data_com1 |
jmp p_irq4_1 |
old_irq4_handler: |
mov edi,4 |
call irqhandler |
p_irq4_1: |
restore_ring3_context |
iret |
p_irq12: |
save_ring3_context |
mov ax, os_data |
mov ds, ax |
mov es, ax |
call check_mouse_data_ps2 |
restore_ring3_context |
iret |
ready_for_next_irq: |
mov [check_idle_semaphore],5 |
mov al, 0x20 |
out 0x20, al |
ret |
ready_for_next_irq_1: |
mov [check_idle_semaphore],5 |
mov al, 0x20 |
out 0xa0,al |
out 0x20, al |
ret |
irqD: |
save_ring3_context |
mov ax, os_data |
mov ds, ax |
mov es, ax |
mov dx,0xf0 |
mov al,0 |
out dx,al |
mov dx,0xa0 |
mov al,0x20 |
out dx,al |
mov dx,0x20 |
out dx,al |
restore_ring3_context |
iret |
irqhandler: |
push edi |
mov esi,edi ; 1 |
shl esi,6 ; 1 |
add esi,irq00read ; 1 |
shl edi,12 ; 1 |
add edi,0x2E0000 |
mov ecx,16 |
mov [check_idle_semaphore],5 |
irqnewread: |
dec ecx |
js irqover |
mov dx,[esi] ; 2+ |
cmp dx,0 ; 1 |
jz irqover |
cmp [esi+3],byte 1 ; 2 ; byte read |
jne noirqbyte ; 4-11 |
in al,dx |
mov edx,[edi] |
cmp edx,4000 |
je irqfull |
mov ebx,edi |
add ebx,0x10 |
add ebx,edx |
mov [ebx],al |
inc edx |
mov [edi],edx |
add esi,4 |
jmp irqnewread |
noirqbyte: |
cmp [esi+3],byte 2 ; word read |
jne noirqword |
in ax,dx |
mov edx,[edi] |
cmp edx,4000 |
je irqfull |
mov ebx,edi |
add ebx,0x10 |
add ebx,edx |
mov [ebx],ax |
add edx,2 |
mov [edi],edx |
add esi,4 |
jmp irqnewread |
noirqword: |
irqfull: |
irqover: |
mov al,0x20 ; ready for next irq |
out 0x20,al |
pop ebx |
cmp ebx,7 |
jbe noa0 |
out 0xa0,al |
noa0: |
ret |
set_application_table_status: |
push eax |
mov eax,[0x3000] |
shl eax, 5 |
add eax,0x3000+TASKDATA.pid |
mov eax,[eax] |
mov [application_table_status],eax |
pop eax |
ret |
clear_application_table_status: |
push eax |
mov eax,[0x3000] |
shl eax, 5 |
add eax,0x3000+TASKDATA.pid |
mov eax,[eax] |
cmp eax,[application_table_status] |
jne apptsl1 |
mov [application_table_status],0 |
apptsl1: |
pop eax |
ret |
sys_resize_app_memory: |
; eax = 1 - resize |
; ebx = new amount of memory |
cmp eax,1 |
jne .no_application_mem_resize |
jmp new_mem_resize ;resize for new type of processes |
.no_application_mem_resize: |
ret |
get_app_params: |
push eax |
cmp [0x90000+6],word '00' |
jne no_00_header |
mov eax,[0x90000+12] |
mov [app_start],eax |
mov eax,[0x90000+16] |
mov [app_i_end],eax |
mov eax,[0x90000+20] |
mov [app_mem],eax |
shr eax,1 |
sub eax,0x10 |
mov [app_esp],eax |
mov eax,[0x90000+24] |
mov [app_i_param],eax |
mov [app_i_icon],dword 0 |
pop eax |
mov esi,1 |
ret |
no_00_header: |
cmp [0x90000+6],word '01' |
jne no_01_header |
mov eax,[0x90000+12] |
mov [app_start],eax |
mov eax,[0x90000+16] |
mov [app_i_end],eax |
mov eax,[0x90000+20] |
mov [app_mem],eax |
mov eax,[0x90000+24] |
mov [app_esp],eax |
mov eax,[0x90000+28] |
mov [app_i_param],eax |
mov eax,[0x90000+32] |
mov [app_i_icon],eax |
pop eax |
mov esi,1 |
ret |
no_01_header: |
pop eax |
mov esi,0 |
ret |
start_application_fl: |
jmp new_start_application_fl |
;************************************************************************ |
start_application_floppy: |
jmp new_start_application_floppy |
;******************************************************************** |
start_application_hd: |
jmp new_start_application_hd |
uglobal |
new_process_place dd 0x0 |
app_start dd 0x0 |
app_i_end dd 0x0 |
app_mem dd 0x0 |
app_esp dd 0x0 |
app_i_param dd 0x0 |
app_i_icon dd 0x0 |
;app_mem_pos dd 0x0 |
appl_path dd 0x0 |
appl_path_size dd 0x0 |
endg |
;iglobal |
;hd_app_string db 'HDAPP ' |
;process_loading db 'K : Process - loading ',13,10,0 |
;process_running db 'K : Process - done',13,10,0 |
;first_gdt_search dd 0x2 |
;endg |
sys_threads: |
; eax=1 create thread |
; |
; ebx=thread start |
; ecx=thread stack value |
; |
; on return : eax = pid |
jmp new_sys_threads |
iglobal |
process_terminating db 'K : Process - terminating',13,10,0 |
process_terminated db 'K : Process - done',13,10,0 |
endg |
terminate: ; terminate application |
push esi |
mov esi,process_terminating |
call sys_msg_board_str |
pop esi |
@@: |
cli |
cmp [application_table_status],0 |
je term9 |
sti |
call change_task |
jmp @b |
term9: |
call set_application_table_status |
mov eax,esi |
call dispose_app_cr3_table |
cmp [prev_user_of_fpu],esi ; if user fpu last -> fpu user = 1 |
jne fpu_ok_1 |
mov [prev_user_of_fpu],1 |
fpu_ok_1: |
mov [0xf400],byte 0 ; empty keyboard buffer |
mov [0xf500],byte 0 ; empty button buffer |
; remove defined hotkeys |
mov eax, hotkey_list |
.loop: |
cmp [eax+8], esi |
jnz .cont |
mov ecx, [eax] |
jecxz @f |
push dword [eax+12] |
pop dword [ecx+12] |
@@: |
mov ecx, [eax+12] |
push dword [eax] |
pop dword [ecx] |
xor ecx, ecx |
mov [eax], ecx |
mov [eax+4], ecx |
mov [eax+8], ecx |
mov [eax+12], ecx |
.cont: |
add eax, 16 |
cmp eax, hotkey_list+256*16 |
jb .loop |
; remove hotkeys in buffer |
mov eax, hotkey_buffer |
.loop2: |
cmp [eax], esi |
jnz .cont2 |
and dword [eax+4], 0 |
and dword [eax], 0 |
.cont2: |
add eax, 8 |
cmp eax, hotkey_buffer+120*8 |
jb .loop2 |
mov ecx,esi ; remove buttons |
bnewba2: |
mov edi,[0xfe88] |
mov eax,edi |
cld |
movzx ebx,word [edi] |
inc bx |
bnewba: |
dec bx |
jz bnmba |
add eax,0x10 |
cmp cx,[eax] |
jnz bnewba |
pusha |
mov ecx,ebx |
inc ecx |
shl ecx,4 |
mov ebx,eax |
add eax,0x10 |
call memmove |
dec dword [edi] |
popa |
jmp bnewba2 |
bnmba: |
pusha ; save window coordinates for window restoring |
cld |
shl esi,5 |
add esi,window_data |
mov eax,[esi+WDATA.box.left] |
mov [dlx],eax |
add eax,[esi+WDATA.box.width] |
mov [dlxe],eax |
mov eax,[esi+WDATA.box.top] |
mov [dly],eax |
add eax,[esi+WDATA.box.height] |
mov [dlye],eax |
mov [esi+WDATA.box.left], 0 |
mov [esi+WDATA.box.width], 5 |
mov eax,[0xFE04] |
mov [esi+WDATA.box.top],eax |
mov [esi+WDATA.box.height], 5 |
xor eax, eax |
mov [esi+WDATA.cl_workarea],eax |
mov [esi+WDATA.cl_titlebar],eax |
mov [esi+WDATA.cl_frames],eax |
mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn |
lea edi, [esi-window_data+draw_data] |
mov ecx,32/4 |
rep stosd |
popa |
; debuggee test |
pushad |
mov edi, esi |
shl edi, 5 |
mov eax, [0x80000+edi*8+APPDATA.debugger_slot] |
test eax, eax |
jz .nodebug |
push 8 |
pop ecx |
push dword [0x3000+edi+TASKDATA.pid] ; PID |
push 2 |
call debugger_notify |
pop ecx |
pop ecx |
.nodebug: |
popad |
pusha ; at 0x80000+ |
mov edi,esi |
shl edi,8 |
add edi,0x80000 |
mov ecx,256/4 |
xor eax, eax |
rep stosd |
popa |
pusha ; name to spaces |
mov edi,esi |
shl edi,8 |
add edi,0x80000+APPDATA.app_name |
mov ecx,11 |
mov eax,' ' |
rep stosb |
popa |
; activate window |
movzx eax, word [0xC000 + esi*2] |
cmp eax, [0x3004] |
jne .dont_activate |
pushad |
.check_next_window: |
dec eax |
cmp eax, 1 |
jbe .nothing_to_activate |
lea esi, [0xc400+eax*2] |
movzx edi, word [esi] ; edi = process |
shl edi, 5 |
cmp [0x3000 + edi + TASKDATA.state], byte 9 ; skip dead slots |
je .check_next_window |
add edi, window_data |
call waredraw |
.nothing_to_activate: |
popad |
.dont_activate: |
push esi ; remove hd1 & cd & flp reservation |
shl esi, 5 |
mov esi, [esi+0x3000+TASKDATA.pid] |
cmp [hd1_status], esi |
jnz @f |
mov [hd1_status], 0 |
@@: |
cmp [cd_status], esi |
jnz @f |
mov [cd_status], 0 |
@@: |
cmp [flp_status], esi |
jnz @f |
mov [flp_status], 0 |
@@: |
pop esi |
pusha ; remove all irq reservations |
mov eax,esi |
shl eax, 5 |
mov eax,[eax+0x3000+TASKDATA.pid] |
mov edi,irq_owner |
mov ecx,16 |
newirqfree: |
scasd |
jne nofreeirq |
mov [edi-4],dword 0 |
nofreeirq: |
loop newirqfree |
popa |
pusha ; remove all port reservations |
mov edx,esi |
shl edx, 5 |
add edx,0x3000 |
mov edx,[edx+TASKDATA.pid] |
rmpr0: |
mov esi,[0x2d0000] |
cmp esi,0 |
je rmpr9 |
rmpr3: |
mov edi,esi |
shl edi,4 |
add edi,0x2d0000 |
cmp edx,[edi] |
je rmpr4 |
dec esi |
jnz rmpr3 |
jmp rmpr9 |
rmpr4: |
mov ecx,256 |
sub ecx,esi |
shl ecx,4 |
mov esi,edi |
add esi,16 |
cld |
rep movsb |
dec dword [0x2d0000] |
jmp rmpr0 |
rmpr9: |
popa |
mov edi,esi ; do not run this process slot |
shl edi, 5 |
mov [edi+0x3000 + TASKDATA.state],byte 9 |
; debugger test - terminate all debuggees |
mov eax, 2 |
mov ecx, 0x80000+2*0x100+APPDATA.debugger_slot |
.xd0: |
cmp eax, [0x3004] |
ja .xd1 |
cmp dword [ecx], esi |
jnz @f |
and dword [ecx], 0 |
pushad |
xchg eax, ebx |
mov eax, 2 |
call sys_system |
popad |
@@: |
inc eax |
add ecx, 0x100 |
jmp .xd0 |
.xd1: |
; call systest |
sti ; .. and life goes on |
mov eax, [dlx] |
mov ebx, [dly] |
mov ecx, [dlxe] |
mov edx, [dlye] |
call [calculatescreen] |
xor eax, eax |
xor esi, esi |
call redrawscreen |
mov [0xfff4],byte 0 ; no mouse background |
mov [0xfff5],byte 0 ; draw mouse |
mov [application_table_status],0 |
mov esi,process_terminated |
call sys_msg_board_str |
ret |
iglobal |
boot_sched_1 db 'Building gdt tss pointer',0 |
boot_sched_2 db 'Building IDT table',0 |
endg |
build_scheduler: |
mov esi,boot_sched_1 |
call boot_log |
call build_process_gdt_tss_pointer |
mov esi,boot_sched_2 |
call boot_log |
call build_interrupt_table |
ret |
/kernel/branches/gfx_kernel/core/syscall.inc |
---|
0,0 → 1,151 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SYSTEM CALL ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
i40: |
push ds es |
pushad |
cld |
mov ax,word os_data |
mov ds,ax |
mov es,ax |
; for syscall trace function |
call save_registers |
; load all registers in crossed order |
mov edi,[esp+28] ; eax |
mov eax,[esp+16] ; ebx |
mov ebx,[esp+24] ; ecx |
mov ecx,[esp+20] ; edx |
mov edx,[esp+4] ; esi |
mov esi,[esp+0] ; edi |
; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler |
sti |
push eax |
and edi,0xff |
call dword [servetable+edi*4] |
pop eax |
cli |
popad |
pop es ds |
iretd |
align 4 |
save_registers: |
mov esi, [0x3010] |
mov eax, [esi+TASKDATA.pid] ; load PID |
lea esi, [esp+4] |
inc [save_syscall_count] |
mov edi,[save_syscall_count] |
and edi,0xF |
shl edi,6 |
add edi,save_syscall_data+32 |
mov [edi-32],eax |
mov ecx,32 / 4 |
cld |
rep movsd |
ret |
uglobal |
save_syscall_count dd 0x0 |
endg |
label save_syscall_data dword at 0x5000 |
iglobal |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; SYSTEM FUNCTIONS TABLE ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
servetable: |
dd sys_drawwindow ; 0-DrawWindow |
dd syscall_setpixel ; 1-SetPixel |
dd sys_getkey ; 2-GetKey |
dd sys_clock ; 3-GetTime |
dd syscall_writetext ; 4-WriteText |
dd delay_hs ; 5-DelayHs |
dd syscall_openramdiskfile ; 6-OpenRamdiskFile |
dd syscall_putimage ; 7-PutImage |
dd sys_button ; 8-DefineButton |
dd sys_cpuusage ; 9-GetProcessInfo |
dd sys_waitforevent ; 10-WaitForEvent |
dd sys_getevent ; 11-CheckForEvent |
dd sys_redrawstat ; 12-BeginDraw and EndDraw |
dd syscall_drawrect ; 13-DrawRect |
dd syscall_getscreensize ; 14-GetScreenSize |
dd sys_background ; 15-bgr |
dd sys_cachetodiskette ; 16-FlushFloppyCache |
dd sys_getbutton ; 17-GetButton |
dd sys_system ; 18-System Services |
dd syscall_startapp ; 19-StartApp |
dd sys_midi ; 20-ResetMidi and OutputMidi |
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. |
dd sys_settime ; 22-setting date,time,clock and alarm-clock |
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent |
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist |
dd sys_sb16 ; 25-SetSb16 |
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. |
dd sys_wss ; 27-SetWssMainVol and SetWssCdVol |
dd sys_sb16II ; 28-SetSb16 |
dd sys_date ; 29-GetDate |
; dd syscall_readhd ; 30-ReadHd - obsolete <diamond> |
dd undefined_syscall ; 30-reserved |
; dd syscall_starthdapp ; 31-StartHdApp - obsolete <diamond> |
dd undefined_syscall ; 31-reserved |
dd syscall_delramdiskfile ; 32-DelRamdiskFile |
dd syscall_writeramdiskfile; 33-WriteRamdiskFile |
; dd read_floppy_file ; 34-ReadFloppyDrive - obsolete <diamond> |
dd undefined_syscall ; 34-reserved |
dd syscall_getpixel ; 35-GetPixel |
dd syscall_readstring ; 36-ReadString (not yet ready) |
dd readmousepos ; 37-GetMousePosition_ScreenRelative,. |
dd syscall_drawline ; 38-DrawLine |
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,. |
dd set_app_param ; 40-WantEvents |
dd syscall_getirqowner ; 41-GetIrqOwner |
dd get_irq_data ; 42-ReadIrqData |
dd sys_outport ; 43-SendDeviceData |
dd sys_programirq ; 44-ProgramIrqs |
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq |
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea |
dd display_number ; 47-WriteNum |
dd display_settings ; 48-SetRedrawType and SetButtonType |
dd sys_apm ; 49-Advanced Power Management (APM) |
dd random_shaped_window ; 50-Window shape & scale |
dd syscall_threads ; 51-Threads |
dd stack_driver_stat ; 52-Stack driver status |
dd socket ; 53-Socket interface |
dd user_events ; 54-User events |
dd sound_interface ; 55-Sound interface |
dd write_to_hd ; 56-Write a file to hd |
; dd delete_from_hd ; 57-Delete a file from hd - obsolete <diamond> |
dd undefined_syscall ; 57-reserved |
dd file_system ; 58-Common file system interface |
dd sys_trace ; 59-System call trace |
dd new_sys_ipc ; 60-Inter Process Communication |
dd sys_gs ; 61-Direct graphics access |
dd sys_pci ; 62-PCI functions |
dd sys_msg_board ; 63-System message board |
dd sys_resize_app_memory ; 64-Resize application memory usage |
dd undefined_syscall ; 65-UTF |
dd sys_process_def ; 66-Process definitions - keyboard |
dd sys_window_move ; 67-Window move or resize |
dd sys_internal_services ; 68-Some internal services |
dd sys_debug_services ; 69-Debug |
dd file_system_lfn ; 70-Common file system interface, version 2 |
dd syscall_windowsettings ; 71-Window settings |
times 255 - ( ($-servetable) /4 ) dd undefined_syscall |
dd sys_end ; -1-end application |
endg |
/kernel/branches/gfx_kernel/detect/commouse.inc |
---|
0,0 → 1,135 |
;************************************************** |
;* ÏÎÈÑÊ ÌÛØÈ ÏÎ ÏÎÑËÅÄÎÂÀÒÅËÜÍÛÌ ÏÎÐÒÀÌ * |
;* Ïðîöåäóðà ïîäãîòàâëèâàåò ãëîáàëüíûå ïåðåìåííûå * |
;* COMPortNum è COMPortBaseAddr äëÿ ïîäïðîãðàììû * |
;* óñòàíîâêè îáðàáîò÷èêà ïðåðûâàíèÿ * |
;************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
Detect_COM_Mouse: |
pusha |
call MSMouseSearch |
cmp AL,'M' |
jne @f |
mov [com1_mouse_detected],1 |
pusha |
mov eax,4 |
shl eax,2 |
mov [irq_owner+eax],byte 1 |
inc dword [0x2d0000] |
mov edi,[0x2d0000] |
shl edi,4 |
mov [0x2d0000+edi+0],dword 1 |
mov [0x2d0000+edi+4],dword 0x3f0 |
mov [0x2d0000+edi+8],dword 0x3ff |
popa |
mov esi,boot_setmouse_type+22 |
call boot_log |
@@: |
sub [COMPortBaseAddr],100h |
call MSMouseSearch |
cmp AL,'M' |
jne @f |
mov [com2_mouse_detected],1 |
pusha |
mov eax,3 |
shl eax,2 |
mov [irq_owner+eax],byte 1 |
inc dword [0x2d0000] |
mov edi,[0x2d0000] |
shl edi,4 |
mov [0x2d0000+edi+0],dword 1 |
mov [0x2d0000+edi+4],dword 0x2f0 |
mov [0x2d0000+edi+8],dword 0x2ff |
popa |
mov esi,boot_setmouse_type+44 |
call boot_log |
@@: |
popa |
jmp end_detecting_mouse |
MSMouseSearch: |
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ |
MouseSearch: |
; Óñòàíàâëèâàåì ñêîðîñòü |
; ïðèåìà/ïåðåäà÷è 1200 áîä |
mov DX,[COMPortBaseAddr] |
add DX,3 |
in AL,DX |
or AL,80h ;óñòàíîâèòü áèò DLAB |
out DX,AL |
mov DX,[COMPortBaseAddr] |
mov AL,60h ;1200 áîä |
out DX,AL |
inc DX |
mov AL,0 |
out DX,AL |
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò, |
; ÷åòíîñòü íå êîíòðîëèðîâàòü |
mov DX,[COMPortBaseAddr] |
add DX,3 |
mov AL,00000010b |
out DX,AL |
; Çàïðåòèòü âñå ïðåðûâàíèÿ |
mov DX,[COMPortBaseAddr] |
inc DX |
mov AL,0 |
out DX,AL |
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñÿ |
; ìûøüþ òèïà MSMouse |
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíèÿ |
mov DX,[COMPortBaseAddr] |
add DX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì |
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2 |
out DX,AL |
; Îæèäàòü 5 "òèêîâ" (0,2 ñ) |
mov ecx,0xffff |
dT_1: |
dec ecx |
cmp ecx,0 |
jne dT_1 |
mov ecx,0xffff |
; Âêëþ÷èòü ïèòàíèå ìûøè |
mov AL,11b ;óñòàíîâèòü DTR è RTS |
out DX,AL |
; Î÷èñòèòü ðåãèñòð äàííûõ |
mov DX,[COMPortBaseAddr] |
in AL,DX |
; Öèêë îïðîñà ïîðòà |
WaitData: |
; Îæèäàòü åùå 10 "òèêîâ" |
dec ecx |
cmp ecx,0 |
je NoMouse |
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà |
mov DX,[COMPortBaseAddr] |
add DX,5 |
in AL,DX |
test AL,1 ;Äàííûå ãîòîâû? |
jz WaitData |
; Ââåñòè äàííûå |
mov DX,[COMPortBaseAddr] |
in AL,DX |
NoMouse: |
ret |
iglobal |
COMPortBaseAddr dw 3F8h |
;COMPortNum dw 0 |
endg |
iglobal |
boot_setmouse_type db 'Detected - PS2 mouse',0 |
db 'Detected - COM1 mouse',0 |
db 'Detected - COM2 mouse',0 |
endg |
end_detecting_mouse: |
/kernel/branches/gfx_kernel/detect/dev_fd.inc |
---|
0,0 → 1,20 |
;*************************************************** |
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû |
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD |
; àâòîð Mario79 |
;*************************************************** |
xor eax,eax |
mov edi,0x40000 |
mov ecx,16384 |
cld |
rep stosd |
mov al,0x10 |
out 0x70,al |
mov cx,0xff |
wait_cmos: |
dec cx |
cmp cx,0 |
jne wait_cmos |
in al,0x71 |
mov [0x40000],al |
/kernel/branches/gfx_kernel/detect/dev_hdcd.inc |
---|
0,0 → 1,374 |
;****************************************************** |
; ïîèñê ïðèâîäîâ HDD è CD |
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; àäàïòàöèÿ è äîðàáîòêà Mario79 |
;****************************************************** |
;**************************************************** |
;* ÏÎÈÑÊ HDD è CD * |
;**************************************************** |
FindHDD: |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov ax,[Sector512+176] |
; mov [0x40006],ax |
; mov ax,[Sector512+126] |
; mov [0x40008],ax |
; mov ax,[Sector512+128] |
; mov [0x40008],ax |
mov [DiskNumber],1 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [0x40007],al |
inc [ChannelNumber] |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [0x40008],al |
mov [DiskNumber],1 |
call FindHDD_1 |
; mov al,[Sector512+176] |
; mov [0x40009],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 [0x40001] |
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 [0x40001] |
inc byte [0x40001] |
FindHDD_2_2: |
ret |
FindHDD_3: |
call FindHDD_1 |
shl byte [0x40001],2 |
ret |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA |
SectorAddress DD ? |
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadHDD_ID: |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures],0 |
mov [ATAHead],0 |
mov [ATACommand],0ECh |
call SendCommandToHDD |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
mov DX,[ATABasePortAddr] |
add DX,7 ;àäðåñ ðåãèñòðà ñîñòîÿíèÿ |
mov ecx,0xffff |
@@WaitCompleet: |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
dec ecx |
cmp ecx,0 |
je @@Error1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI,Sector512 ;offset Sector512 |
mov DX,[ATABasePortAddr] ;ðåãèñòð äàííûõ |
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw ;ïðèíÿòü áëîê äàííûõ |
jmp @@End |
; Çàïèñàòü êîä îøèáêè |
@@Error1: |
mov [DevErrorCode],1 |
jmp @@End |
@@Error6: |
mov [DevErrorCode],6 |
@@End: ret |
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2 |
StandardATABases DW 1F0h, 170h |
; Íîìåð êàíàëà |
ChannelNumber DW ? |
; Íîìåð äèñêà |
DiskNumber DB ? |
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà ATA |
ATABasePortAddr DW ? |
; Ïàðàìåòðû ATA-êîìàíäû |
ATAFeatures DB ? ;îñîáåííîñòè |
ATASectorCount DB ? ;êîëè÷åñòâî îáðàáàòûâàåìûõ ñåêòîðîâ |
ATASectorNumber DB ? ;íîìåð íà÷àëüíîãî ñåêòîðà |
ATACylinder DW ? ;íîìåð íà÷àëüíîãî öèëèíäðà |
ATAHead DB ? ;íîìåð íà÷àëüíîé ãîëîâêè |
ATAAddressMode DB ? ;ðåæèì àäðåñàöèè (0 - CHS, 1 - LBA) |
ATACommand DB ? ;êîä êîìàíäû, ïîäëåæàùåé âûïîëíåíèþ |
; Êîä îøèáêè (0 - íåò îøèáîê, 1 - ïðåâûøåí äîïóñòèìûé |
; èíòåðâàë îæèäàíèÿ, 2 - íåâåðíûé êîä ðåæèìà àäðåñàöèè, |
; 3 - íåâåðíûé íîìåð êàíàëà, 4 - íåâåðíûé íîìåð äèñêà, |
; 5 - íåâåðíûé íîìåð ãîëîâêè, 6 - îøèáêà ïðè âûïîëíåíèè |
; êîìàíäû) |
DevErrorCode DB ? |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè. * |
;**************************************************** |
SendCommandToHDD: |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode],1 |
ja @@Err2 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3 |
cmp BX,2 |
ja @@Err3 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov AX,[ebx+StandardATABases] |
mov [ATABasePortAddr],AX |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX,[ATABasePortAddr] |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
mov ecx,0xfff |
; mov eax,[timer_ticks] |
; mov [TickCounter_1],eax |
@@WaitHDReady: |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
dec ecx |
cmp ecx,0 |
je @@Err1 |
; mov eax,[timer_ticks] |
; sub eax,[TickCounter_1] |
; cmp eax,300 ;îæèäàòü 300 òèêîâ |
; ja @@Err1 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL,08h |
jnz @@WaitHDReady |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX,[ATABasePortAddr] |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL,[ATAFeatures] |
out DX,AL |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL,[ATASectorCount] |
out DX,AL |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL,[ATASectorNumber] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX,[ATACylinder] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL,AH |
out DX,AL |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL,[DiskNumber] |
shl AL,4 |
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5 |
or AL,[ATAHead] |
or AL,10100000b |
mov AH,[ATAAddressMode] |
shl AH,6 |
or AL,AH |
out DX,AL |
; Ïîñëàòü êîìàíäó |
mov AL,[ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode],0 |
jmp @@End_2 |
; Çàïèñàòü êîä îøèáêè |
@@Err1: mov [DevErrorCode],1 |
jmp @@End_2 |
@@Err2: mov [DevErrorCode],2 |
jmp @@End_2 |
@@Err3: mov [DevErrorCode],3 |
jmp @@End_2 |
@@Err4: mov [DevErrorCode],4 |
jmp @@End_2 |
@@Err5: mov [DevErrorCode],5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
@@End_2: |
ret |
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadCD_ID: |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures],0 |
mov [ATASectorCount],0 |
mov [ATASectorNumber],0 |
mov [ATACylinder],0 |
mov [ATAHead],0 |
mov [ATACommand],0A1h |
call SendCommandToHDD |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
mov ecx,0xffff |
@@WaitCompleet_1: |
; Ïðîâåðèòü âðåìÿ |
dec ecx |
cmp ecx,0 |
je @@Error1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6_1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet_1 |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI,Sector512 ;offset Sector512 |
mov DX,[ATABasePortAddr] ;ïîðò 1x0h |
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw |
jmp @@End_1 |
; Çàïèñàòü êîä îøèáêè |
@@Error1_1: |
mov [DevErrorCode],1 |
jmp @@End_1 |
@@Error6_1: |
mov [DevErrorCode],6 |
@@End_1: |
ret |
;************************************************* |
;* ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1). * |
;************************************************* |
DeviceReset: |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3_2 |
cmp BX,2 |
ja @@Err3_2 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov DX,[ebx+StandardATABases] |
mov [ATABasePortAddr],DX |
; Âûáðàòü íóæíûé äèñê |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_2 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Ïîñëàòü êîìàíäó "Ñáðîñ" |
mov AL,08h |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
mov ecx,0xffff |
@@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/gfx_kernel/detect/disks.inc |
---|
0,0 → 1,4 |
include 'dev_fd.inc' |
include 'dev_hdcd.inc' |
include 'sear_par.inc' |
/kernel/branches/gfx_kernel/detect/ps2mouse.inc |
---|
0,0 → 1,69 |
MouseSearch_PS2: |
pusha |
mov bl, 0xAD |
call kb_cmd |
mov bl,0xa8 ; enable mouse cmd |
call kb_cmd |
cmp ah,1 |
je @@DataInputError |
mov bl,0xd4 ; for mouse |
call kb_cmd |
cmp ah,1 |
je @@DataInputError |
mov al,0xeb ; |
call kb_write |
cmp ah,1 |
je @@DataInputError |
call kb_read ; Acknowledge |
call kb_read |
mov [ps2_mouse_detected],0 |
test al,18h |
jz @f |
mov [ps2_mouse_detected],1 |
@@: |
call kb_read ; |
call kb_read ; |
mov bl,0x20 ; get command byte |
call kb_cmd |
cmp ah,1 |
je @@DataInputError |
call kb_read |
cmp ah,1 |
je @@DataInputError |
or al,3 ; enable interrupt |
mov bl,0x60 ; write command |
push eax |
call kb_cmd |
pop eax |
call kb_write |
cmp ah,1 |
je @@DataInputError |
mov bl,0xd4 ; for mouse |
call kb_cmd |
cmp ah,1 |
je @@DataInputError |
mov al,0xf4 ; enable mouse device |
call kb_write |
cmp ah,1 |
je @@DataInputError |
call kb_read ; read status return |
cmp ah,1 |
je @@DataInputError |
cmp AL,0FAh |
jnz @@DataInputError ;íåò ïîäòâåðæäåíèÿ |
@@DataInputError: |
cmp [ps2_mouse_detected],0 |
je @f |
mov esi,boot_setmouse_type |
call boot_log |
@@: |
mov bl, 0xAE |
call kb_cmd |
popa |
/kernel/branches/gfx_kernel/detect/sear_par.inc |
---|
0,0 → 1,118 |
;**************************************************** |
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD |
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû |
; àâòîð Mario79 |
;**************************************************** |
mov [transfer_adress],0x4000a |
search_partitions_ide0: |
test [0x40001],byte 0x40 |
jz search_partitions_ide1 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
mov [fat32part],1 |
search_partitions_ide0_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide1 |
inc byte [0x40002] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide0_1 |
search_partitions_ide1: |
test [0x40001],byte 0x10 |
jz search_partitions_ide2 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
mov [fat32part],1 |
search_partitions_ide1_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide2 |
inc byte [0x40003] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide1_1 |
search_partitions_ide2: |
test [0x40001],byte 0x4 |
jz search_partitions_ide3 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
mov [fat32part],1 |
search_partitions_ide2_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide3 |
inc byte [0x40004] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide2_1 |
search_partitions_ide3: |
test [0x40001],byte 0x1 |
jz end_search_partitions_ide |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
mov [fat32part],1 |
search_partitions_ide3_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne end_search_partitions_ide |
inc byte [0x40005] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide3_1 |
partition_data_transfer: |
mov edi,[transfer_adress] |
mov esi,PARTITION_START |
xor ecx,ecx |
mov cx,69 ;100 |
rep movsb |
ret |
transfer_adress dd 0 |
partition_data_transfer_1: |
cli |
push edi |
mov edi,PARTITION_START |
mov esi,[transfer_adress] |
xor ecx,ecx |
mov cx,69 ;100 |
rep movsb |
pop edi |
sti |
ret |
end_search_partitions_ide: |
;PARTITION_START dd 0x3f |
;PARTITION_END dd 0 |
;SECTORS_PER_FAT dd 0x1f3a |
;NUMBER_OF_FATS dd 0x2 |
;SECTORS_PER_CLUSTER dd 0x8 |
;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
;ROOT_CLUSTER dd 2 ; first rootdir cluster |
;FAT_START dd 0 ; start of fat table |
;ROOT_START dd 0 ; start of rootdir (only fat16) |
;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
;DATA_START dd 0 ; start of data area (=first cluster 2) |
;LAST_CLUSTER dd 0 ; last availabe cluster |
;ADR_FSINFO dd 0 ; used only by fat32 |
; |
;fatRESERVED dd 0x0FFFFFF6 |
;fatBAD dd 0x0FFFFFF7 |
;fatEND dd 0x0FFFFFF8 |
;fatMASK dd 0x0FFFFFFF |
; |
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32 |
/kernel/branches/gfx_kernel/docs/apm/README.TXT |
---|
0,0 → 1,255 |
Advanced Power Management |
SYSTEM CALL |
eax = 70 |
dx = íîìåð ôóíêöèè APM BIOS (àíàëîãè÷åí ax â ðåàëüíîì ðåæèìå) |
îñòàëüíûå (bx, cx) ðåãèñòðû ïî ñïåöèôèêàöèè (ñì. apm.txt) |
ðåçóëüòàò : ïî ñïåöèôèêàöèè (âêëþ÷àÿ CF), ñòàðøàÿ ÷àñòü 32 áèòíûõ ðåãèñòðîâ íå îïðåäåëåíà |
MEMORY MAP |
Boot: |
0x9040 - dword - entry point of APM BIOS |
0x9044 - word - version (BCD) |
0x9046 - word - flags |
ÈÇÌÅÍÅÍÈß |
sys32.inc |
syscall.inc |
kernel.asm |
bootcode.inc |
##############[core\sys32.inc]##################### |
Òðè íîâûõ äåñêðèïòîðà |
............. |
............. |
; GDT TABLE |
gdts: |
dw gdte-$-1 |
dd gdts |
dw 0 |
int_code_l: |
os_code_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10011010b |
db 0x00 |
int_data_l: |
os_data_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10010010b |
db 0x00 |
; --------------- APM --------------------- |
apm_code_32: |
dw 0x10 ; limit 64kb |
db 0, 0, 0 |
dw 11011111b *256 +10011010b |
db 0x00 |
apm_code_16: |
dw 0x10 |
db 0, 0, 0 |
dw 10011111b *256 +10011010b |
db 0x00 |
apm_data_16: |
dw 0x10 |
db 0, 0, 0 |
dw 10011111b *256 +10010010b |
db 0x00 |
; ----------------------------------------- |
app_code_l: |
dw ((0x80000000-std_application_base_address) shr 12) and 0xffff |
dw 0 |
db 0 |
dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28) |
db std_application_base_address shr 24 |
app_data_l: |
dw (0x80000000-std_application_base_address) shr 12 and 0xffff |
dw 0 |
db 0 |
dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28) |
db std_application_base_address shr 24 |
graph_data_l: |
dw 0x3ff |
dw 0x0000 |
db 0x00 |
dw 11010000b *256 +11110010b |
db 0x00 |
tss0_l: |
times (max_processes+10) dd 0,0 |
............. |
............. |
##############[core\syscall.inc]################### |
............. |
............. |
dd undefined_syscall ; 65-UTF |
dd sys_process_def ; 66-Process definitions - keyboard |
dd sys_window_move ; 67-Window move or resize |
dd sys_internal_services ; 68-Some internal services |
dd sys_debug_services ; 69-Debug |
dd sys_apm ; 70-APM |
............. |
............. |
##############[kernel.asm]######################### |
×àñòü 1 (ïîñëå ìåòêè "; SAVE REAL MODE VARIABLES"): |
............. |
............. |
; SAVE REAL MODE VARIABLES |
; --------------- APM --------------------- |
mov eax, [0x2f0000 + 0x9040] ; entry point |
mov dword[apm_entry], eax |
mov word [apm_entry + 4], apm_code_32 - gdts |
mov eax, [0x2f0000 + 0x9044] ; version & flags |
mov [apm_vf], eax |
; ----------------------------------------- |
............. |
............. |
×àñòü 2 (ñèñòåìíûé âûçîâ, ðàñïîëîæåíèå íå êðèòè÷íî, |
ÿ ðàñïîëîæèë ïåðåä ìåòêîé "undefined_syscall:") |
............. |
............. |
; --------------- APM --------------------- |
apm_entry dp 0 |
apm_vf dd 0 |
align 4 |
sys_apm: |
cmp word [apm_vf], 0 ; Check APM BIOS enable |
jne @f |
or [esp + 40], byte 1 ; error |
mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported |
ret |
@@: xchg eax, ecx |
xchg ebx, ecx |
cmp al, 3 |
ja @f |
and [esp + 40], byte 0xfe ; emulate func 0..3 as func 0 |
mov eax, [apm_vf] |
mov [esp + 36], eax |
shr eax, 16 |
mov [esp + 32], eax |
ret |
@@: call pword [apm_entry] ; call APM BIOS |
mov [esp + 8 ], edi |
mov [esp + 12], esi |
mov [esp + 24], ebx |
mov [esp + 28], edx |
mov [esp + 32], ecx |
mov [esp + 36], eax |
setc al |
and [esp + 40], byte 0xfe |
or [esp + 40], al |
ret |
; ----------------------------------------- |
align 4 |
undefined_syscall: ; Undefined system call |
............. |
............. |
##############[boot\bootcode.inc]################## |
Ïåðåä ìåòêîé "; DISPLAY VESA INFORMATION" |
............. |
............. |
; --------------- APM --------------------- |
push 0 |
pop es |
mov word [es : 0x9044], 0 ; ver = 0.0 (APM not found) |
mov ax, 0x5300 |
xor bx, bx |
int 0x15 |
jc apm_end ; APM not found |
test cx, 2 |
jz apm_end ; APM 32-bit protected-mode interface not supported |
mov [es : 0x9044], ax ; Save APM Version |
mov [es : 0x9046], cx ; Save APM flags |
; Write APM ver ---- |
jmp @f |
msg_apm:db ' APM x.x ', 0 |
@@: and ax, 0xf0f |
add ax, '00' |
mov [msg_apm - 0x10000 + 5], ah |
mov [msg_apm - 0x10000 + 7], al |
_setcursor 0, 3 |
mov si, msg_apm - 0x10000 |
call printplain |
_setcursor d80x25_top_num,0 |
; ------------------ |
mov ax, 0x5304 ; Disconnect interface |
xor bx, bx |
int 0x15 |
mov ax, 0x5303 ; Connect 32 bit mode interface |
xor bx, bx |
int 0x15 |
; init selectors |
movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment |
shl eax, 4 |
mov [apm_code_32 - 0x10000 + 2], ax |
shr eax, 16 |
mov [apm_code_32 - 0x10000 + 4], al |
movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment |
shl ecx, 4 |
mov [apm_code_16 - 0x10000 + 2], cx |
shr ecx, 16 |
mov [apm_code_16 - 0x10000 + 4], cl |
movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment |
shl edx, 4 |
mov [apm_data_16 - 0x10000 + 2], dx |
shr edx, 16 |
mov [apm_data_16 - 0x10000 + 4], dl |
mov [es : 0x9040], ebx ; offset of APM entry point |
apm_end: |
; ----------------------------------------- |
; DISPLAY VESA INFORMATION |
............. |
............. |
/kernel/branches/gfx_kernel/docs/apm/apm.txt |
---|
0,0 → 1,518 |
--------p-155300----------------------------- |
INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK |
AX = 5300h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AH = major version (BCD) |
AL = minor version (BCD) |
BX = 504Dh ("PM") |
CX = flags (see #00472) |
CF set on error |
AH = error code (06h,09h,86h) (see #00473) |
BUG: early versions of the Award Modular BIOS with built-in APM support |
reportedly do not set BX on return |
Bitfields for APM flags: |
Bit(s) Description (Table 00472) |
0 16-bit protected mode interface supported |
1 32-bit protected mode interface supported |
2 CPU idle call reduces processor speed |
3 BIOS power management disabled |
4 BIOS power management disengaged (APM v1.1) |
5-7 reserved |
(Table 00473) |
Values for APM error code: |
01h power management functionality disabled |
02h interface connection already in effect |
03h interface not connected |
04h real-mode interface not connected |
05h 16-bit protected-mode interface already connected |
06h 16-bit protected-mode interface not supported |
07h 32-bit protected-mode interface already connected |
08h 32-bit protected-mode interface not supported |
09h unrecognized device ID |
0Ah invalid parameter value in CX |
0Bh (APM v1.1) interface not engaged |
0Ch (APM v1.2) function not supported |
0Dh (APM v1.2) Resume Timer disabled |
0Eh-1Fh reserved for other interface and general errors |
20h-3Fh reserved for CPU errors |
40h-5Fh reserved for device errors |
60h can't enter requested state |
61h-7Fh reserved for other system errors |
80h no power management events pending |
81h-85h reserved for other power management event errors |
86h APM not present |
87h-9Fh reserved for other power management event errors |
A0h-FEh reserved |
FFh undefined |
--------p-155301----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE |
AX = 5301h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
CF set on error |
AH = error code (02h,05h,07h,09h) (see #00473) |
Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5302h,AX=5303h,AX=5304h |
--------p-155302----------------------------- |
INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE |
AX = 5302h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AX = real-mode segment base address of protected-mode 16-bit code |
segment |
BX = offset of entry point |
CX = real-mode segment base address of protected-mode 16-bit data |
segment |
---APM v1.1--- |
SI = APM BIOS code segment length |
DI = APM BIOS data segment length |
CF set on error |
AH = error code (02h,05h,06h,07h,09h) (see #00473) |
Notes: the caller must initialize two consecutive descriptors with the |
returned segment base addresses; these descriptors must be valid |
whenever the protected-mode interface is called, and will have |
their limits arbitrarily set to 64K. |
the protected mode interface is invoked by making a far call with the |
same register values as for INT 15; it must be invoked while CPL=0, |
the code segment descriptor must have a DPL of 0, the stack must be |
in a 16-bit segment and have enough room for BIOS use and possible |
interrupts, and the current I/O permission bit map must allow access |
to the I/O ports used for power management. |
functions 00h-03h are not available from protected mode |
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5301h,AX=5303h,AX=5304h |
--------p-155303----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE |
AX = 5303h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AX = real-mode segment base address of protected-mode 32-bit code |
segment |
EBX = offset of entry point |
CX = real-mode segment base address of protected-mode 16-bit code |
segment |
DX = real-mode segment base address of protected-mode 16-bit data |
segment |
---APM v1.1--- |
SI = APM BIOS code segment length |
DI = APM BIOS data segment length |
CF set on error |
AH = error code (02h,05h,07h,08h,09h) (see #00473) |
Notes: the caller must initialize three consecutive descriptors with the |
returned segment base addresses for 32-bit code, 16-bit code, and |
16-bit data, respectively; these descriptors must be valid whenever |
the protected-mode interface is called, and will have their limits |
arbitrarily set to 64K. |
the protected mode interface is invoked by making a far call to the |
32-bit code segment with the same register values as for INT 15; it |
must be invoked while CPL=0, the code segment descriptor must have a |
DPL of 0, the stack must be in a 32-bit segment and have enough room |
for BIOS use and possible interrupts, and the current I/O permission |
bit map must allow access to the I/O ports used for power management. |
functions 00h-03h are not available from protected mode |
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5301h,AX=5302h,AX=5304h |
--------p-155304----------------------------- |
INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE |
AX = 5304h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,09h) (see #00473) |
SeeAlso: AX=5301h,AX=5302h,AX=5303h |
--------p-155305----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CPU IDLE |
AX = 5305h |
Return: CF clear if successful (after system leaves idle state) |
CF set on error |
AH = error code (03h,0Bh) (see #00473) |
Notes: call when the system is idle and should be suspended until the next |
system event or interrupt |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
if an interrupt causes the system to resume normal processing, the |
interrupt may or may not have been handled when the BIOS returns |
from this call; thus, the caller should allow interrupts on return |
interrupt handlers may not retain control if the BIOS allows |
interrupts while in idle mode even if they are able to determine |
that they were called from idle mode |
the caller should issue this call continuously in a loop until it needs |
to perform some processing of its own |
SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h |
--------p-155306----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CPU BUSY |
AX = 5306h |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,0Bh) (see #00473) |
Notes: called to ensure that the system runs at full speed even on systems |
where the BIOS is unable to recognize increased activity (especially |
if interrupts are hooked by other programs and not chained to the |
BIOS) |
this call may be made even when the system is already running at full |
speed, but it will create unnecessary overhead |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5305h |
--------p-155307----------------------------- |
INT 15 - Advanced Power Management v1.0+ - SET POWER STATE |
AX = 5307h |
BX = device ID (see #00474) |
CX = system state ID (see #00475) |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473) |
Note: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=530Ch |
(Table 00474) |
Values for APM device IDs: |
0000h system BIOS |
0001h all devices for which the system BIOS manages power |
01xxh display (01FFh for all attached display devices) |
02xxh secondary storage (02FFh for all attached secondary storage devices) |
03xxh parallel ports (03FFh for all attached parallel ports) |
04xxh serial ports (04FFh for all attached serial ports) |
---APM v1.1+ --- |
05xxh network adapters (05FFh for all attached network adapters) |
06xxh PCMCIA sockets (06FFh for all) |
0700h-7FFFh reserved |
80xxh system battery devices (APM v1.2) |
8100h-DFFFh reserved |
Exxxh OEM-defined power device IDs |
F000h-FFFFh reserved |
(Table 00475) |
Values for system state ID: |
0000h ready (not supported for device ID 0001h) |
0001h stand-by |
0002h suspend |
0003h off (not supported for device ID 0001h in APM v1.0) |
---APM v1.1--- |
0004h last request processing notification (only for device ID 0001h) |
0005h last request rejected (only for device ID 0001h) |
0006h-001Fh reserved system states |
0020h-003Fh OEM-defined system states |
0040h-007Fh OEM-defined device states |
0080h-FFFFh reserved device states |
--------p-155307CX0001----------------------- |
INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY |
AX = 5307h |
CX = 0001h |
BX = 0001h (device ID for all power-managed devices) |
Return: CF clear |
Notes: puts the entire system into stand-by mode; normally called in response |
to a System Stand-by Request notification after any necessary |
processing, but may also be invoked at the caller's discretion |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the stand-by state is typically exited on an interrupt |
SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh |
--------p-155307CX0002----------------------- |
INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM |
AX = 5307h |
CX = 0002h |
BX = 0001h (device ID for all power-managed devices) |
Return: after system is resumed |
CF clear |
Notes: puts the entire system into a low-power suspended state; normally |
called in response to a Suspend System Request notification after |
any necessary processing, but may also be invoked at the caller's |
discretion |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the caller may need to update its date and time values because the |
system could have been suspended for a long period of time |
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh |
--------p-155307CX0003----------------------- |
INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM |
AX = 5307h |
CX = 0003h |
BX = 0001h (device ID for all power-managed devices) |
Return: after system is resumed |
CF clear |
Notes: if supported by the system's power supply, turns off the system power |
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh |
--------p-155308----------------------------- |
INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT |
AX = 5308h |
BX = device ID for all devices power-managed by APM |
0001h (APM v1.1+) |
FFFFh (APM v1.0) |
CX = new state |
0000h disabled |
0001h enabled |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) |
Notes: when power management is disabled, the system BIOS will not |
automatically power down devices, enter stand-by or suspended mode, |
or perform any power-saving actions in response to AX=5305h calls |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the APM BIOS should never be both disabled and disengaged at the same |
time |
SeeAlso: AX=5309h,AX=530Dh,AX=530Fh |
--------p-155309----------------------------- |
INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS |
AX = 5309h |
BX = device ID for all devices power-managed by APM |
0001h (APM v1.1) |
FFFFh (APM v1.0) |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,09h,0Bh) (see #00473) |
Note: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5308h |
--------p-15530A----------------------------- |
INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS |
AX = 530Ah |
BX = device ID |
0001h all devices power-managed by APM |
80xxh specific battery unit number XXh (01h-FFh) (APM v1.2) |
Return: CF clear if successful |
BH = AC line status |
00h off-line |
01h on-line |
02h on backup power (APM v1.1) |
FFh unknown |
other reserved |
BL = battery status (see #00476) |
CH = battery flag (APM v1.1+) (see #00477) |
CL = remaining battery life, percentage |
00h-64h (0-100) percentage of full charge |
FFh unknown |
DX = remaining battery life, time (APM v1.1) (see #00478) |
---if specific battery unit specified--- |
SI = number of battery units currently installed |
CF set on error |
AH = error code (09h,0Ah) (see #00473) |
Notes: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
supported in real mode (INT 15) and both 16-bit and 32-bit protected |
mode |
(Table 00476) |
Values for APM v1.0+ battery status: |
00h high |
01h low |
02h critical |
03h charging |
FFh unknown |
other reserved |
SeeAlso: #00477,#00478 |
Bitfields for APM v1.1+ battery flag: |
Bit(s) Description (Table 00477) |
0 high |
1 low |
2 critical |
3 charging |
4 selected battery not present (APM v1.2) |
5-6 reserved (0) |
7 no system battery |
Note: all bits set (FFh) if unknown |
SeeAlso: #00476,#00478 |
Bitfields for APM v1.1+ remaining battery life: |
Bit(s) Description (Table 00478) |
15 time units: 0=seconds, 1=minutes |
14-0 battery life in minutes or seconds |
Note: all bits set (FFFFh) if unknown |
SeeAlso: #00476,#00477 |
--------p-15530B----------------------------- |
INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT |
AX = 530Bh |
Return: CF clear if successful |
BX = event code (see #00479) |
CX = event information (APM v1.2) if BX=0003h or BX=0004h |
bit 0: PCMCIA socket was powered down in suspend state |
CF set on error |
AH = error code (03h,0Bh,80h) (see #00473) |
Notes: although power management events are often asynchronous, notification |
will not be made until polled via this call to permit software to |
only receive event notification when it is prepared to process |
power management events; since these events are not very time- |
critical, it should be sufficient to poll once or twice per second |
the critical resume notification is made after the system resumes |
from an emergency suspension; normally, the system BIOS only notifies |
its partner that it wishes to suspend and relies on the partner to |
actually request the suspension, but no notification is made on an |
emergency suspension |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND" |
(Table 00479) |
Values for APM event code: |
0001h system stand-by request |
0002h system suspend request |
0003h normal resume system notification |
0004h critical resume system notification |
0005h battery low notification |
---APM v1.1--- |
0006h power status change notification |
0007h update time notification |
0008h critical system suspend notification |
0009h user system standby request notification |
000Ah user system suspend request notification |
000Bh system standby resume notification |
---APM v1.2--- |
000Ch capabilities change notification (see AX=5310h) |
------ |
000Dh-00FFh reserved system events |
01xxh reserved device events |
02xxh OEM-defined APM events |
0300h-FFFFh reserved |
--------p-15530C----------------------------- |
INT 15 - Advanced Power Management v1.1+ - GET POWER STATE |
AX = 530Ch |
BX = device ID (see #00474) |
Return: CF clear if successful |
CX = system state ID (see #00475) |
CF set on error |
AH = error code (01h,09h) (see #00473) |
SeeAlso: AX=5307h |
--------p-15530D----------------------------- |
INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT |
AX = 530Dh |
BX = device ID (see #00474) |
CX = function |
0000h disable power management |
0001h enable power management |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) |
Desc: specify whether automatic power management should be active for a |
given device |
SeeAlso: AX=5308h,AX=530Fh |
--------p-15530E----------------------------- |
INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION |
AX = 530Eh |
BX = device ID of system BIOS (0000h) |
CH = APM driver major version (BCD) |
CL = APM driver minor version (BCD) (02h for APM v1.2) |
Return: CF clear if successful |
AH = APM connection major version (BCD) |
AL = APM connection minor version (BCD) |
CF set on error |
AH = error code (03h,09h,0Bh) (see #00473) |
SeeAlso: AX=5300h,AX=5303h |
--------p-15530F----------------------------- |
INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT |
AX = 530Fh |
BX = device ID (see #00474) |
CX = function |
0000h disengage power management |
0001h engage power management |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,09h) (see #00473) |
Notes: unlike AX=5308h, this call does not affect the functioning of the APM |
BIOS |
when cooperative power management is disengaged, the APM BIOS performs |
automatic power management of the system or device |
SeeAlso: AX=5308h,AX=530Dh |
--------p-155310----------------------------- |
INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES |
AX = 5310h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
Return: CF clear if successful |
BL = number of battery units supported (00h if no system batteries) |
CX = capabilities flags (see #00480) |
CF set on error |
AH = error code (01h,09h,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces; it does not require that a |
connection be established prior to use |
this function will return the capabilities currently in effect, not |
any new settings which have been made but do not take effect until |
a system restart |
SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h |
Bitfields for APM v1.2 capabilities flags: |
Bit(s) Description (Table 00480) |
15-8 reserved |
7 PCMCIA Ring Indicator will wake up system from suspend mode |
6 PCMCIA Ring Indicator will wake up system from standby mode |
5 Resume on Ring Indicator will wake up system from suspend mode |
4 Resume on Ring Indicator will wake up system from standby mode |
3 resume timer will wake up system from suspend mode |
2 resume timer will wake up system from standby mode |
1 can enter global suspend state |
0 can enter global standby state |
--------p-155311----------------------------- |
INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER |
AX = 5311h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable Resume Timer |
01h get Resume Timer |
02h set Resume Timer |
CH = resume time, seconds (BCD) |
DL = resume time, minutes (BCD) |
DH = resume time, hours (BCD) |
SI = resume date (BCD), high byte = month, low byte = day |
DI = resume date, year (BCD) |
Return: CF clear if successful |
---if getting timer--- |
CH = resume time, seconds (BCD) |
DL = resume time, minutes (BCD) |
DH = resume time, hours (BCD) |
SI = resume date (BCD), high byte = month, low byte = day |
DI = resume date, year (BCD) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h |
--------p-155312----------------------------- |
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING |
AX = 5312h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable Resume on Ring Indicator |
01h enable Resume on Ring Indicator |
02h get Resume on Ring Indicator status |
Return: CF clear if successful |
CX = resume status (0000h disabled, 0001h enabled) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h |
--------p-155313----------------------------- |
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS |
AX = 5313h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable timer-based requests |
01h enable timer-based requests |
02h get timer-based requests status |
Return: CF clear if successful |
CX = timer-based requests status (0000h disabled, 0001h enabled) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
some BIOSes set AH on return even when successful |
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h |
/kernel/branches/gfx_kernel/docs/sysfuncr.txt |
---|
0,0 → 1,4467 |
Kolibri 0.5.8.1 |
®¬¥à äãªæ¨¨ ¯®¬¥é ¥âáï ¢ ॣ¨áâà eax. |
맮¢ á¨á⥬®© äãªæ¨¨ ®áãé¥á⢫ï¥âáï ª®¬ ¤®© "int 0x40". |
ᥠॣ¨áâàë, ªà®¬¥  㪠§ ëå ¢ ¢®§¢à é ¥¬®¬ § 票¨, |
¢ª«îç ï ॣ¨áâà ä« £®¢ eflags, á®åà ïîâáï. |
====================================================================== |
============== ãªæ¨ï 0 - ®¯à¥¤¥«¨âì ¨ à¨á®¢ âì ®ª®. ============= |
====================================================================== |
¯à¥¤¥«ï¥â ®ª® ¯à¨«®¦¥¨ï. ¨áã¥â à ¬ªã ®ª , § £®«®¢®ª ¨ à ¡®çãî |
®¡« áâì. «ï ®ª® ᮠ᪨®¬ ®¯à¥¤¥«ï¥â áâ ¤ àâë¥ ª®¯ª¨ § ªàëâ¨ï ¨ |
¬¨¨¬¨§ 樨. |
à ¬¥âàë: |
* eax = 0 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 0xXYRRGGBB, £¤¥: |
* Y = áâ¨«ì ®ª : |
* Y=0 - ⨯ I - ®ª® 䨪á¨à®¢ ëå à §¬¥à®¢ |
* Y=1 - ⮫쪮 ®¯à¥¤¥«¨âì ®¡« áâì ®ª , ¨ç¥£® ¥ à¨á®¢ âì |
* Y=2 - ⨯ II - ®ª® ¨§¬¥ï¥¬ëå à §¬¥à®¢ |
* Y=3 - ®ª® ᮠ᪨®¬ |
* ®áâ «ìë¥ ¢®§¬®¦ë¥ § 票ï (®â 4 ¤® 15) § १¥à¢¨à®¢ ë, |
¢ë§®¢ äãªæ¨¨ á â ª¨¬¨ Y ¨£®à¨àã¥âáï |
* RR, GG, BB = ᮮ⢥âá⢥® ªà á ï, §¥«¥ ï, á¨ïï |
á®áâ ¢«ïî騥 梥â à ¡®ç¥© ®¡« á⨠®ª |
(¨£®à¨àã¥âáï ¤«ï á⨫ï Y=2) |
* X = DCBA (¡¨âë) |
* A = 1 - ã ®ª ¥áâì § £®«®¢®ª; ¤«ï á⨫ï Y=3 ¤à¥á áâப¨ |
§ £®«®¢ª § ¤ ¸âáï ¢ edi, ¤«ï ¯à®ç¨å á⨫¥© |
¨á¯®«ì§ã¥âáï ¯®¤äãªæ¨ï 1 äãªæ¨¨ 71 |
* B = 1 - ª®®à¤¨ âë ¢á¥å £à ä¨ç¥áª¨å ¯à¨¬¨â¨¢®¢ § ¤ îâáï |
®â®á¨â¥«ì® ª«¨¥â᪮© ®¡« á⨠®ª |
* C § १¥à¢¨à®¢ (ãáâ ¢«¨¢ ©â¥ ¢ 0) |
* D = 0 - ®à¬ «ì ï § «¨¢ª à ¡®ç¥© ®¡« áâ¨, 1 - £à ¤¨¥â ï |
«¥¤ãî騥 ¯ à ¬¥âàë ¯à¥¤ § ç¥ë ¤«ï ®ª® ⨯ I ¨ II ¨ |
¨£®à¨àãîâáï ¤«ï á⨫¥© Y=1,3: |
* esi = 0xXYRRGGBB - 梥⠧ £®«®¢ª |
* RR, GG, BB ®¯à¥¤¥«ïîâ á ¬ 梥â |
* Y=0 - ®¡ë箥 ®ª®, Y=1 - ¥¯¥à¥¬¥é ¥¬®¥ ®ª® |
* X ®¯à¥¤¥«ï¥â £à ¤¨¥â § £®«®¢ª : X=0 - ¥â £à ¤¨¥â , |
X=8 - ®¡ëçë© £à ¤¨¥â, |
¤«ï ®ª® ⨯ II X=4 - ¥£ â¨¢ë© £à ¤¨¥â |
* ¯à®ç¨¥ § 票ï X ¨ Y § १¥à¢¨à®¢ ë |
* edi = 0x00RRGGBB - 梥â à ¬ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®«®¦¥¨¥ ¨ à §¬¥àë ®ª ãáâ ¢«¨¢ îâáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ |
í⮩ äãªæ¨¨ ¨ ¨£®à¨àãîâáï ¯à¨ ¯®á«¥¤ãîé¨å; ¤«ï ¨§¬¥¥¨ï |
¯®«®¦¥¨ï ¨/¨«¨ à §¬¥à®¢ 㦥 ᮧ¤ ®£® ®ª ¨á¯®«ì§ã©â¥ |
67-î äãªæ¨î. |
* «ï ®ª® á⨫ï Y=3 á § £®«®¢ª®¬ (A=1) áâப § £®«®¢ª |
ãáâ ¢«¨¢ ¥âáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ í⮩ äãªæ¨¨ ¨ ¨£®à¨àã¥âáï ¯à¨ |
¯®á«¥¤ãîé¨å (â®ç¥¥ £®¢®àï, ¨£®à¨àã¥âáï ¯®á«¥ ¢ë§®¢ |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 12 - ª®æ ¯¥à¥à¨á®¢ª¨); |
¤«ï ¨§¬¥¥¨ï áâப¨ § £®«®¢ª 㦥 ᮧ¤ ®£® ®ª ¨á¯®«ì§ã©â¥ |
¯®¤äãªæ¨î 1 äãªæ¨¨ 71. |
* ᫨ ¨á¯®«ì§®¢ âì ®ª ᮮ⢥âáâ¢ãîé¨å á⨫¥©, â® ¯®«®¦¥¨¥ |
¨/¨«¨ à §¬¥àë ®ª ¬®£ãâ ¬¥ïâìáï ¯®«ì§®¢ ⥫¥¬. |
¥ªã騥 ¯®«®¦¥¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì ¯®«ãç¥ë ¢ë§®¢®¬ äãªæ¨¨ 9. |
* ª® ¤®«¦® 㬥é âìáï íªà ¥. ᫨ ¯¥à¥¤ ë¥ ª®®à¤¨ âë |
¨ à §¬¥àë ¥ 㤮¢«¥â¢®àïîâ í⮬ã ãá«®¢¨î, ⮠ᮮ⢥âáâ¢ãîé ï |
ª®®à¤¨ â (¨«¨, ¢®§¬®¦®, ®¡¥) áç¨â ¥âáï ã«¥¬, ¥á«¨ ¨ íâ® |
¥ ¯®¬®£ ¥â, ⮠ᮮ⢥âáâ¢ãî騩 à §¬¥à (¨«¨, ¢®§¬®¦®, ®¡ ) |
ãáâ ¢«¨¢ ¥âáï ¢ à §¬¥à íªà . |
«¥¥ ®¡®§ 稬 xpos,ypos,xsize,ysize - § 票ï, ¯¥à¥¤ ¢ ¥¬ë¥ |
¢ ebx,ecx. ®®à¤¨ âë ¯à¨¢®¤ïâáï ®â®á¨â¥«ì® «¥¢®£® ¢¥à奣® |
㣫 ®ª , ª®â®àë©, â ª¨¬ ®¡à §®¬, § ¤ ¥âáï ª ª (0,0), ª®®à¤¨ âë |
¯à ¢®£® ¨¦¥£® 㣫 áãâì (xsize,ysize). |
* §¬¥àë ®ª ¯®¨¬ îâáï ¢ á¬ëá«¥ ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 . |
â® ¦¥ ®â®á¨âáï ¨ ª® ¢á¥¬ ®áâ «ìë¬ äãªæ¨ï¬. |
â® ®§ ç ¥â, ç⮠ॠ«ìë¥ à §¬¥àë 1 ¯¨ªá¥«ì ¡®«ìè¥. |
* ¨¤ ®ª ⨯ I: |
* à¨áã¥âáï ¢¥èïï à ¬ª 梥â , 㪠§ ®£® ¢ edi, |
è¨à¨®© 1 ¯¨ªá¥«ì |
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (1,1) |
¨ ¯à ¢ë¬ ¨¦¨¬ (xsize-1,min(25,ysize)) 梥â , 㪠§ ®£® ¢ esi |
(á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (1,21) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-1,ysize-1) (à §¬¥à ¬¨ (xsize-1)*(ysize-21)) - 梥⮬, |
㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ A=1 ¨ áâப § £®«®¢ª ãáâ ®¢«¥ ¯®¤äãªæ¨¥© 1 |
äãªæ¨¨ 71, â® ® ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª |
* ¨¤ ®ª á⨫ï Y=1: |
* ¯®«®áâìî ®¯à¥¤¥«ï¥âáï ¯à¨«®¦¥¨¥¬ |
* ¨¤ ®ª ⨯ II: |
* à¨áã¥âáï ¢¥èïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì "§ ⥸®£®" 梥â |
edi (¢á¥ á®áâ ¢«ïî騥 梥â 㬥ìè îâáï ¢ ¤¢ à § ) |
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç ï à ¬ª è¨à¨®© 3 ¯¨ªá¥«ï 梥â edi |
* à¨áã¥âáï ¢ãâà¥ïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
"§ ⥸®£®" 梥â edi |
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (4,4) |
¨ ¯à ¢ë¬ ¨¦¨¬ (xsize-4,min(20,ysize)) 梥â , 㪠§ ®£® ¢ esi |
(á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (5,20) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-5,ysize-5) - 梥⮬, 㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ A=1 ¨ áâப § £®«®¢ª ãáâ ®¢«¥ ¯®¤äãªæ¨¥© 1 |
äãªæ¨¨ 71, â® ® ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª |
* ¨¤ ®ª ᮠ᪨®¬: |
* à¨áã¥âáï ¢¥èïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
梥â 'outer' ¨§ ᪨ |
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç ï à ¬ª è¨à¨®© 3 ¯¨ªá¥«ï |
梥â 'frame' ¨§ ᪨ |
* à¨áã¥âáï ¢ãâà¥ïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
梥â 'inner' ¨§ ᪨ |
* à¨áã¥âáï § £®«®¢®ª (¯® ª à⨪ ¬ ¨§ ᪨ ) ¢ ¯àאַ㣮«ì¨ª¥ |
(0,0) - (xsize,_skinh-1) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (5,_skinh) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-5,ysize-5) - 梥⮬, 㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ®¯à¥¤¥«ïîâáï ¤¢¥ áâ ¤ àâë¥ ª®¯ª¨: § ªàëâ¨ï ¨ ¬¨¨¬¨§ 樨 |
(ᬮâਠäãªæ¨î 8) |
* ¥á«¨ A=1 ¨ ¢ edi (¥ã«¥¢®©) 㪠§ ⥫ì áâப㠧 £®«®¢ª , |
â® ® ¢ë¢®¤¨âáï ¢ § £®«®¢ª¥ ¢ ¬¥áâ¥, ®¯à¥¤¥«ï¥¬®¬ ᪨®¬ |
* 票¥ ¯¥à¥¬¥®© _skinh ¤®áâ㯮 ª ª १ã«ìâ ⠢맮¢ |
¯®¤äãªæ¨¨ 4 äãªæ¨¨ 48 |
====================================================================== |
================= ãªæ¨ï 1 - ¯®áâ ¢¨âì â®çªã ¢ ®ª¥. ================ |
====================================================================== |
à ¬¥âàë: |
* eax = 1 - ®¬¥à äãªæ¨¨ |
* ebx = x-ª®®à¤¨ â (®â®á¨â¥«ì® ®ª ) |
* ecx = y-ª®®à¤¨ â (®â®á¨â¥«ì® ®ª ) |
* edx = 0x00RRGGBB - 梥â â®çª¨ |
edx = 0x01xxxxxx - ¨¢¥àâ¨à®¢ âì 梥â â®çª¨ |
(¬« ¤è¨¥ 24 ¡¨â ¨£®à¨àãîâáï) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
============== ãªæ¨ï 2 - ¯®«ãç¨âì ª®¤ ¦ ⮩ ª« ¢¨è¨. ============= |
====================================================================== |
¡¨à ¥â ª®¤ ¦ ⮩ ª« ¢¨è¨ ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 2 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1 |
* ¥á«¨ ¡ãä¥à ¥¯ãáâ, â® ¢®§¢à é ¥âáï al=0, ah=ª®¤ ¦ ⮩ ª« ¢¨è¨, |
áâ à襥 á«®¢® ॣ¨áâà eax ®¡ã«¥® |
* ¥á«¨ ¥áâì "£®àïç ï ª« ¢¨è ", â® ¢®§¢à é ¥âáï |
al=2, ah=᪠ª®¤ ¦ ⮩ ª« ¢¨è¨ (0 ¤«ï ã¯à ¢«ïîé¨å ª« ¢¨è), |
áâ à襥 á«®¢® ॣ¨áâà eax ᮤ¥à¦¨â á®áâ®ï¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è |
¢ ¬®¬¥â ¦ â¨ï £®àï祩 ª« ¢¨è¨ |
¬¥ç ¨ï: |
* ãé¥áâ¢ã¥â ®¡é¥á¨áâ¥¬ë© ¡ãä¥à ¦ âëå ª« ¢¨è à §¬¥à®¬ 120 ¡ ©â, |
®à£ ¨§®¢ ë© ª ª ®ç¥à¥¤ì. |
* ãé¥áâ¢ã¥â ¥é¸ ®¤¨ ®¡é¥á¨áâ¥¬ë© ¡ãä¥à 120 "£®àïç¨å ª« ¢¨è". |
* ਠ¢ë§®¢¥ í⮩ äãªæ¨¨ ¯à¨«®¦¥¨¥¬ á ¥ ªâ¨¢ë¬ ®ª®¬ |
áç¨â ¥âáï, çâ® ¡ãä¥à ¦ âëå ª« ¢¨è ¯ãáâ. |
* ® 㬮«ç ¨î íâ äãªæ¨ï ¢®§¢à é ¥â ASCII-ª®¤ë; ¯¥à¥ª«îç¨âìáï |
०¨¬ ᪠ª®¤®¢ (¨ § ¤) ¬®¦® á ¨á¯®«ì§®¢ ¨¥¬ äãªæ¨¨ 66. |
¤ ª®, £®àï稥 ª« ¢¨è¨ ¢á¥£¤ ¢®§¢à é îâáï ª ª ᪠ª®¤ë. |
* § âì, ª ª¨¥ ª®¬¡¨ 樨 ª« ¢¨è ᮮ⢥âáâ¢ãîâ ª ª¨¬ ª®¤ ¬, ¬®¦®, |
§ ¯ãá⨢ ¯à¨«®¦¥¨ï keyascii ¨ scancode. |
* ª ª®¤ë ¢®§¢à é îâáï ¥¯®á।á⢥® ª« ¢¨ âãன ¨ 䨪á¨à®¢ ë; |
ASCII-ª®¤ë ¯®«ãç îâáï á ¨á¯®«ì§®¢ ¨¥¬ â ¡«¨æ ¯à¥®¡à §®¢ ¨ï, |
ª®â®àë¥ ¬®¦® ãáâ ®¢¨âì ¯®¤äãªæ¨¥© 2 äãªæ¨¨ 21 ¨ ¯à®ç¨â âì |
¯®¤äãªæ¨¥© 2 äãªæ¨¨ 26. |
* ª á«¥¤á⢨¥, ASCII-ª®¤ë ãç¨âë¢ îâ ⥪ãéãî à ᪫ ¤ªã ª« ¢¨ âãàë |
(rus/en) ¢ ®â«¨ç¨¥ ®â ᪠ª®¤®¢. |
* ®áâ㯠¥â ¨ä®à¬ æ¨ï ⮫쪮 ® â¥å £®àïç¨å ª« ¢¨è å, ª®â®àë¥ ¡ë«¨ |
®¯à¥¤¥«¥ë í⨬ ¯®â®ª®¬ ¯®¤äãªæ¨¥© 4 äãªæ¨¨ 66. |
====================================================================== |
================ ãªæ¨ï 3 - ¯®«ãç¨âì á¨á⥬®¥ ¢à¥¬ï. =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 3 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00SSMMHH, £¤¥ HH:MM:SS = ç áë:¬¨ãâë:ᥪã¤ë |
* ª ¦¤ë© í«¥¬¥â ¢®§¢à é ¥âáï ª ª BCD-ç¨á«®, ¯à¨¬¥à, |
¤«ï ¢à¥¬¥¨ 23:59:59 १ã«ìâ ⠡㤥â 0x00595923 |
¬¥ç ¨ï: |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 9 äãªæ¨¨ 26 - ¯®«ã票¥ ¢à¥¬¥¨ |
á ¬®¬¥â § ¯ã᪠á¨á⥬ë; ® ¢® ¬®£¨å á«ãç ïå 㤮¡¥¥, |
¯®áª®«ìªã ¢®§¢à é ¥â ¯à®áâ® DWORD-§ 票¥ áç¥â稪 ¢à¥¬¥¨. |
* ¨á⥬®¥ ¢à¥¬ï ¬®¦® ãáâ ®¢¨âì äãªæ¨¥© 22. |
====================================================================== |
============== ãªæ¨ï 4 - ¢ë¢¥á⨠áâபã ⥪áâ ¢ ®ª®. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 4 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* ecx = 0xX0RRGGBB, £¤¥ |
* RR, GG, BB § ¤ îâ 梥â ⥪áâ |
* X § ¤ ¥â ¨á¯®«ì§ã¥¬ë© èà¨äâ: 0=á¨áâ¥¬ë© ¬®®è¨à¨ë©, |
1=á¨áâ¥¬ë© èà¨äâ ¯¥à¥¬¥®© è¨à¨ë |
* edx = 㪠§ ⥫ì ç «® áâப¨ |
* esi = ¤«¨ áâப¨, ¤®«¦ ¡ëâì ¥ ¡®«ìè¥ 255 |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* 뢮¤ïâáï «¨¡® ¯¥à¢ë¥ (esi and 0xFF) ᨬ¢®«®¢, |
«¨¡® ¢á¥ ᨬ¢®«ë ¤® (® ¥ ¢ª«îç ï) § ¢¥àè î饣® ã«ï |
(¤«ï ASCIIZ-áâப) ¢ § ¢¨á¨¬®á⨠®â ⮣®, çâ® ¯à®¨§®©¤¸â à ìè¥. |
* ¥à¢ë© á¨áâ¥¬ë© èà¨äâ áç¨âë¢ ¥âáï ¯à¨ § £à㧪¥ ¨§ ä ©« char.mt, |
¢â®à®© - ¨§ char2.mt. |
* ¡ èà¨äâ ¨¬¥îâ ¢ëá®âã 9 ¯¨ªá¥«¥©, è¨à¨ ¬®®è¨à¨®£® èà¨äâ |
à ¢ 6 ¯¨ªá¥«¥©. |
====================================================================== |
========================= ãªæ¨ï 5 - ¯ 㧠. ========================= |
====================================================================== |
¤¥à¦¨¢ ¥â ¢ë¯®«¥¨¥ ¯à®£à ¬¬ë § ¤ ®¥ ¢à¥¬ï. |
à ¬¥âàë: |
* eax = 5 - ®¬¥à äãªæ¨¨ |
* ebx = ¢à¥¬ï ¢ á®âëå ¤®«ïå ᥪã¤ë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥à¥¤ ç ebx=0 ¥ ¯¥à¥¤ ¥â ã¯à ¢«¥¨¥ á«¥¤ãî饬㠯à®æ¥ááã ¨ |
¢®®¡é¥ ¥ ¯à®¨§¢®¤¨â ¨ª ª¨å ¤¥©á⢨©. ᫨ ¤¥©áâ¢¨â¥«ì® |
âॡã¥âáï ¯¥à¥¤ âì ã¯à ¢«¥¨¥ á«¥¤ãî饬㠯à®æ¥ááã |
(§ ª®ç¨âì ⥪ã騩 ª¢ ⠢६¥¨), ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 1 |
äãªæ¨¨ 68. |
* ਠ⥪ã饩 ॠ«¨§ 樨 ¯à®¨§®©¤¥â ¥¬¥¤«¥ë© ¢®§¢à â ¨§ äãªæ¨¨, |
¥á«¨ á«®¦¥¨¥ ebx á ⥪ã騬 § 票¥¬ áç¥â稪 ¢à¥¬¥¨ ¢ë§®¢¥â |
32-¡¨â®¥ ¯¥à¥¯®«¥¨¥. |
====================================================================== |
=============== ãªæ¨ï 6 - ¯à®ç¨â âì ä ©« á à ¬¤¨áª . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 6 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
* ecx = ®¬¥à áâ à⮢®£® ¡«®ª , áç¨â ï á 1; |
ecx=0 - ç¨â âì á ç « ä ©« (â® ¦¥ á ¬®¥, çâ® ¨ ecx=1) |
* edx = ç¨á«® ¡«®ª®¢ ¤«ï ç⥨ï; |
edx=0 - ç¨â âì ®¤¨ ¡«®ª (â® ¦¥ á ¬®¥, çâ® ¨ edx=1) |
* esi = 㪠§ â¥«ì ®¡« áâì ¯ ¬ïâ¨, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤«¨ ä ©« ¢ ¡ ©â å, ¥á«¨ ä ©« ãá¯¥è® ¯à®ç¨â |
* eax = -1, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* ï äãªæ¨ï ï¥âáï ãáâ ॢ襩; äãªæ¨ï 70 |
¯®§¢®«ï¥â ¢ë¯®«ïâì ⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* «®ª = 512 ¡ ©â. |
* «ï çâ¥¨ï ¢á¥£® ä ©« ¬®¦® 㪠§ âì § ¢¥¤®¬® ¡®«ì讥 § 票¥ |
¢ edx, ¯à¨¬¥à, edx = -1; ® ¢ í⮬ á«ãç ¥ ¡ã¤ì⥠£®â®¢ë ª ⮬ã, |
çâ® ¯à®£à ¬¬ "㯠¤¥â", ¥á«¨ ä ©« ®ª ¦¥âáï ᫨誮¬ ¡®«ì訬 |
¨ "¥ ¢«¥§¥â" ¢ ¯ ¬ïâì ¯à®£à ¬¬ë. |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ |
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯ª¨ à ¬¤¨áª¥. |
====================================================================== |
=============== ãªæ¨ï 7 - ¢ë¢¥á⨠¨§®¡à ¦¥¨¥ ¢ ®ª®. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 7 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨§®¡à ¦¥¨¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¨§®¡à ¦¥¨ï - íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
¨§®¡à ¦¥¨ï ®â®á¨â¥«ì® ®ª . |
* §¬¥à ¨§®¡à ¦¥¨ï ¢ ¡ ©â å ¥áâì 3*xsize*ysize. |
====================================================================== |
=============== ãªæ¨ï 8 - ®¯à¥¤¥«¨âì/㤠«¨âì ª®¯ªã. =============== |
====================================================================== |
à ¬¥âàë ¤«ï ®¯à¥¤¥«¥¨ï ª®¯ª¨: |
* eax = 8 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 0xXYnnnnnn, £¤¥: |
* nnnnnn = ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
* áâ à訩 (31-©) ¡¨â edx á¡à®è¥ |
* ¥á«¨ 30-© ¡¨â edx ãáâ ®¢«¥ - ¥ ¯à®à¨á®¢ë¢ âì ª®¯ªã |
* ¥á«¨ 29-© ¡¨â edx ãáâ ®¢«¥ - ¥ à¨á®¢ âì à ¬ªã |
¯à¨ ¦ ⨨ ª®¯ªã |
* esi = 0x00RRGGBB - 梥⠪®¯ª¨ |
à ¬¥âàë ¤«ï 㤠«¥¨ï ª®¯ª¨: |
* eax = 8 - ®¬¥à äãªæ¨¨ |
* edx = 0x80nnnnnn, £¤¥ nnnnnn - ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* §¬¥àë ª®¯ª¨ ¤®«¦ë ¡ëâì ¡®«ìè¥ 0 ¨ ¬¥ìè¥ 0x8000. |
* «ï ®ª® ᮠ᪨®¬ ¯à¨ ®¯à¥¤¥«¥¨¨ ®ª (¢ë§®¢¥ 0-© äãªæ¨¨) |
ᮧ¤ îâáï ¤¢¥ áâ ¤ àâë¥ ª®¯ª¨ - § ªàëâ¨ï ®ª |
á ¨¤¥â¨ä¨ª â®à®¬ 1 ¨ ¬¨¨¬¨§ 樨 ®ª á ¨¤¥â¨ä¨ª â®à®¬ 0xffff. |
* ®§¤ ¨¥ ¤¢ãå ª®¯®ª á ®¤¨ ª®¢ë¬¨ ¨¤¥â¨ä¨ª â®à ¬¨ |
¢¯®«¥ ¤®¯ãá⨬®. |
* ®¯ª á ¨¤¥â¨ä¨ª â®à®¬ 0xffff ¯à¨ ¦ ⨨ ¨â¥à¯à¥â¨àã¥âáï |
á¨á⥬®© ª ª ª®¯ª ¬¨¨¬¨§ 樨, á¨á⥬ ®¡à ¡ âë¢ ¥â â ª®¥ |
¦ ⨥ á ¬®áâ®ï⥫ì®, ¥ ®¡à é ïáì ª ¯à¨«®¦¥¨î. |
®á⠫쮬 íâ® ®¡ëç ï ª®¯ª . |
* ¡é¥¥ ª®«¨ç¥á⢮ ª®¯®ª ¤«ï ¢á¥å ¯à¨«®¦¥¨© ®£à ¨ç¥® |
ç¨á«®¬ 4095. |
====================================================================== |
============= ãªæ¨ï 9 - ¨ä®à¬ æ¨ï ® ¯®â®ª¥ ¢ë¯®«¥¨ï. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 9 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à 1 ¡ |
* ecx = ®¬¥à ᫮⠯®â®ª |
ecx = -1 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ⥪ã饬 ¯®â®ª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¬ ªá¨¬ «ìë© ®¬¥à ᫮⠯®â®ª |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â ebx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨ä®à¬ æ¨î: |
* +0: dword: ¨á¯®«ì§®¢ ¨¥ ¯à®æ¥áá®à (᪮«ìª® ⠪⮢ ¢ ᥪã¤ã |
ã室¨â ¨á¯®«¥¨¥ ¨¬¥® í⮣® ¯®â®ª ) |
* +4: word: ¯®§¨æ¨ï ®ª ¯®â®ª ¢ ®ª®®¬ áâíª¥ |
* +6: word: (¥ ¨¬¥¥â ®â®è¥¨ï ª § ¯à®è¥®¬ã ¯®â®ªã) |
®¬¥à ᫮⠯®â®ª , ®ª® ª®â®à®£® 室¨âáï ¢ ®ª®®¬ áâíª¥ |
¢ ¯®§¨æ¨¨ ecx |
* +8: word: § १¥à¢¨à®¢ ® |
* +10 = +0xA: 11 ¡ ©â: ¨¬ï ¯à®æ¥áá |
(¨¬ï ᮮ⢥âáâ¢ãî饣® ¨á¯®«ï¥¬®£® ä ©« ¢ ä®à¬ ⥠8+3) |
* +21 = +0x15: byte: ¢ëà ¢¨¢ ¨¥, íâ®â ¡ ©â ¥ ¨§¬¥ï¥âáï |
* +22 = +0x16: dword: ¤à¥á ¯à®æ¥áá ¢ ¯ ¬ï⨠|
* +26 = +0x1A: dword: à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ï⨠- 1 |
* +30 = +0x1E: dword: ¨¤¥â¨ä¨ª â®à (PID/TID) |
* +34 = +0x22: dword: ª®®à¤¨ â ®ª ¯®â®ª ¯® ®á¨ x |
* +38 = +0x26: dword: ª®®à¤¨ â ®ª ¯®â®ª ¯® ®á¨ y |
* +42 = +0x2A: dword: à §¬¥à ®ª ¯®â®ª ¯® ®á¨ x |
* +46 = +0x2E: dword: à §¬¥à ®ª ¯®â®ª ¯® ®á¨ y |
* +50 = +0x32: word: á®áâ®ï¨¥ ᫮⠯®â®ª : |
* 0 = ¯®â®ª ¢ë¯®«ï¥âáï |
* 1 = ¯®â®ª ¯à¨®áâ ®¢«¥ |
* 2 = ¯®â®ª ¯à¨®áâ ®¢«¥ ¢ ¬®¬¥â ®¦¨¤ ¨ï ᮡëâ¨ï |
* 3 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ ⥠¢ë§®¢ äãªæ¨¨ -1 ¨«¨ |
ᨫìá⢥® ª ª á«¥¤á⢨¥ ¢ë§®¢ ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18 |
¨«¨ § ¢¥à襨ï à ¡®âë á¨á⥬ë |
* 4 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ ⥠¨áª«î票ï |
* 5 = ¯®â®ª ®¦¨¤ ¥â ᮡëâ¨ï |
* 9 = § ¯à®è¥ë© á«®â ᢮¡®¤¥, ¢áï ®áâ «ì ï ¨ä®à¬ æ¨ï ® |
᫮⥠¥ ¨¬¥¥â á¬ëá« |
¬¥ç ¨ï: |
* «®âë 㬥àãîâáï á 1. |
* ®§¢à é ¥¬®¥ § 票¥ ¥ ¥áâì ®¡é¥¥ ç¨á«® ¯®â®ª®¢, ¯®áª®«ìªã |
¡ë¢ îâ ᢮¡®¤ë¥ á«®âë. |
* ਠᮧ¤ ¨¨ ¯à®æ¥áá ¢â®¬ â¨ç¥áª¨ ᮧ¤ ¥âáï ¯®â®ª ¢ë¯®«¥¨ï. |
* ãªæ¨ï ¢ë¤ ¥â ¨ä®à¬ æ¨î ® ¯®â®ª¥. ¦¤ë© ¯à®æ¥áá ¨¬¥¥â |
å®âï ¡ë ®¤¨ ¯®â®ª. ¤¨ ¯à®æ¥áá ¬®¦¥â ᮧ¤ âì ¥áª®«ìª® ¯®â®ª®¢, |
¢ í⮬ á«ãç ¥ ª ¦¤ë© ¯®â®ª ¯®«ãç ¥â ᢮© á«®â, ¯à¨ç¥¬ ¯®«ï |
+10, +22, +26 ¢ íâ¨å á«®â å ᮢ¯ ¤ îâ. |
«ï ¯à¨«®¦¥¨© ¥ áãé¥áâ¢ã¥â ®¡é¥£® ᯮᮡ ®¯à¥¤¥«¨âì, |
¯à¨ ¤«¥¦ â «¨ ¤¢ ¯®â®ª ®¤®¬ã ¯à®æ¥ááã. |
* ªâ¨¢®¥ ®ª® - ®ª®, 室ï饥áï ¢¥à訥 ®ª®®£® áâíª , |
®® ¯®«ãç ¥â á®®¡é¥¨ï ® ¢¢®¤¥ á ª« ¢¨ âãàë. «ï ¥£® ¯®§¨æ¨ï ¢ |
®ª®®¬ áâíª¥ ᮢ¯ ¤ ¥â á ¢®§¢à é ¥¬ë¬ § 票¥¬. |
* «®â 1 ᮮ⢥âáâ¢ã¥â á¯¥æ¨ «ì®¬ã ¯®â®ªã ®¯¥à 樮®© á¨á⥬ë, |
¤«ï ª®â®à®£®: |
* ®ª® 室¨âáï ¢¨§ã ®ª®®£® áâíª , ¯®«ï +4 ¨ +6 ᮤ¥à¦ â |
§ 票¥ 1 |
* ¨¬ï ¯à®æ¥áá - "OS/IDLE" (¤®¯®«¥®¥ ¯à®¡¥« ¬¨) |
* ¤à¥á ¯à®æ¥áá ¢ ¯ ¬ïâ¨ à ¢¥ 0, à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ï⨠|
16 Mb (0x1000000) |
* PID=1 |
* ª®®à¤¨ âë ¨ à §¬¥àë ®ª ãá«®¢® ¯®« £ îâáï à ¢ë¬¨ 0 |
* á®áâ®ï¨¥ á«®â - ¢á¥£¤ 0 (¢ë¯®«ï¥âáï) |
* ¢à¥¬ï ¢ë¯®«¥¨ï ᪫ ¤ë¢ ¥âáï ¨§ ¢à¥¬¥¨, ã室ï饣® |
ᮡá⢥® à ¡®âã, ¨ ¢à¥¬¥¨ ¯à®áâ®ï ¢ ®¦¨¤ ¨¨ ¯à¥àë¢ ¨ï |
(ª®â®à®¥ ¬®¦® ¯®«ãç¨âì ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 4 äãªæ¨¨ 18). |
* ç¨ ï á® á«®â 2, à §¬¥é îâáï ®¡ëçë¥ ¯à¨«®¦¥¨ï. |
* ¡ëçë¥ ¯à¨«®¦¥¨ï à §¬¥é îâáï ¢ ¯ ¬ï⨠¯® ¤à¥áã 0x10000000 |
(ª®áâ â ï¤à std_application_base_address). |
«®¦¥¨ï ¥ ¯à®¨á室¨â, ¯®áª®«ìªã ã ª ¦¤®£® ¯à®æ¥áá ᢮ï |
â ¡«¨æ áâà ¨æ. |
* ਠᮧ¤ ¨¨ ¯®â®ª ¥¬ã § ç îâáï ᫮⠢ á¨á⥬®© â ¡«¨æ¥ ¨ |
¨¤¥â¨ä¨ª â®à (Process/Thread IDentifier = PID/TID), ª®â®àë¥ ¤«ï |
§ ¤ ®£® ¯®â®ª ¥ ¨§¬¥ïîâáï á® ¢à¥¬¥¥¬. |
®á«¥ § ¢¥àè¥¨ï ¯®â®ª ¥£® ᫮⠬®¦¥â ¡ëâì § ®¢® ¨á¯®«ì§®¢ |
¤«ï ¤à㣮£® ¯®â®ª . ¤¥â¨ä¨ª â®à ¯®â®ª ¥ ¬®¦¥â ¡ëâì § ç¥ |
¤à㣮¬ã ¯®â®ªã ¤ ¦¥ ¯®á«¥ § ¢¥àè¥¨ï ¯¥à¢®£®. |
§ ç ¥¬ë¥ ®¢ë¬ ¯®â®ª ¬ ¨¤¥â¨ä¨ª â®àë ¬®®â®® à áâãâ. |
* ᫨ ¯®â®ª ¥é¥ ¥ ®¯à¥¤¥«¨« ᢮¥ ®ª® ¢ë§®¢®¬ äãªæ¨¨ 0, â® |
¯®«®¦¥¨¥ ¨ à §¬¥àë í⮣® ®ª ¯®« £ îâáï ã«ï¬¨. |
* ¤ ë© ¬®¬¥â ¨á¯®«ì§ã¥âáï ⮫쪮 ç áâì ¡ãä¥à à §¬¥à®¬ |
52 = 0x34 ¡ ©â . ¥¬ ¥ ¬¥¥¥ ४®¬¥¤ã¥âáï ¨á¯®«ì§®¢ âì ¡ãä¥à |
à §¬¥à®¬ 1 ¡ ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨, ¢ ¡ã¤ã饬 ¬®£ãâ ¡ëâì |
¤®¡ ¢«¥ë ¥ª®â®àë¥ ¯®«ï. |
====================================================================== |
==================== ãªæ¨ï 10 - ®¦¨¤ âì ᮡëâ¨ï. =================== |
====================================================================== |
᫨ ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ , â® ¦¤¥â ¯®ï¢«¥¨ï á®®¡é¥¨ï ¢ ®ç¥à¥¤¨. |
â ª®¬ á®áâ®ï¨¨ ¯®â®ª ¥ ¯®«ãç ¥â ¯à®æ¥áá®à®£® ¢à¥¬¥¨. |
⥬ áç¨âë¢ ¥â á®®¡é¥¨¥ ¨§ ®ç¥à¥¤¨. |
à ¬¥âàë: |
* eax = 10 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 11. |
â®¡ë ¦¤ âì ¥ ¡®«¥¥ ®¯à¥¤¥«¥®£® ¢à¥¬¥¨, ¨á¯®«ì§ã©â¥ |
äãªæ¨î 23. |
====================================================================== |
======= ãªæ¨ï 11 - ¯à®¢¥à¨âì, ¥áâì «¨ ᮡë⨥, ¡¥§ ®¦¨¤ ¨ï. ======= |
====================================================================== |
᫨ ¢ ®ç¥à¥¤¨ á®®¡é¥¨© ¥áâì ª ª®¥-⮠ᮡë⨥, â® áç¨âë¢ ¥â ¨ |
¢®§¢à é ¥â ¥£®. ᫨ ®ç¥à¥¤ì ¯ãáâ , ¢®§¢à é ¥â ã«ì. |
à ¬¥âàë: |
* eax = 11 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ |
* ¨ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ®¦¨¤ ¨ï ¯®ï¢«¥¨ï ᮡëâ¨ï ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 10. |
â®¡ë ¦¤ âì ¥ ¡®«¥¥ ®¯à¥¤¥«¥®£® ¢à¥¬¥¨, ¨á¯®«ì§ã©â¥ |
äãªæ¨î 23. |
====================================================================== |
=========== ãªæ¨ï 12 - ç âì/§ ª®ç¨âì ¯¥à¥à¨á®¢ªã ®ª . ========== |
====================================================================== |
-------------- ®¤äãªæ¨ï 1 - ç âì ¯¥à¥à¨á®¢ªã ®ª . --------------- |
à ¬¥âàë: |
* eax = 12 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------- ®¤äãªæ¨ï 2 - § ª®ç¨âì ¯¥à¥à¨á®¢ªã ®ª . ------------- |
à ¬¥âàë: |
* eax = 12 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ç « ¯¥à¥à¨á®¢ª¨ 㤠«ï¥â ¢á¥ ®¯à¥¤¥«¸ë¥ |
äãªæ¨¥© 8 ª®¯ª¨, ¨å á«¥¤ã¥â ®¯à¥¤¥«¨âì ¯®¢â®à®. |
====================================================================== |
============ ãªæ¨ï 13 - à¨á®¢ âì ¯àאַ㣮«ì¨ª ¢ ®ª¥. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 13 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 梥â 0xRRGGBB ¨«¨ 0x80RRGGBB ¤«ï £à ¤¨¥â®© § «¨¢ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®¤ ª®®à¤¨ â ¬¨ ¯®¨¬ îâáï ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 |
¯àאַ㣮«ì¨ª ®â®á¨â¥«ì® ®ª . |
====================================================================== |
================ ãªæ¨ï 14 - ¯®«ãç¨âì à §¬¥àë íªà . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 14 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [xsize]*65536 + [ysize], £¤¥ |
* xsize = x-ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 íªà = |
à §¬¥à ¯® £®à¨§®â «¨ - 1 |
* ysize = y-ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 íªà = |
à §¬¥à ¯® ¢¥à⨪ «¨ - 1 |
¬¥ç ¨ï: |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 5 äãªæ¨¨ 48 - ¯®«ãç¨âì à §¬¥àë à ¡®ç¥© |
®¡« á⨠íªà . |
====================================================================== |
= ãªæ¨ï 15, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì à §¬¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. = |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = è¨à¨ ¨§®¡à ¦¥¨ï |
* edx = ¢ëá®â ¨§®¡à ¦¥¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï. áâ ®¢ª ᫨誮¬ ¡®«ìè¨å |
§ 票© ¯à¨¢¥¤¸â ª ⮬ã, çâ® ¢ ä® ¢®©¤ãâ ¤ ë¥ § £à ¨æ¥© |
¡ãä¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. §¬¥à ¡ãä¥à = 0x160000-0x10, çâ® |
ᮮ⢥âáâ¢ã¥â ¬ ªá¨¬ «ìë¬ à §¬¥à ¬ 800*600. (800*600*3=0x15F900) |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 39. |
====================================================================== |
= ãªæ¨ï 15, ¯®¤äãªæ¨ï 2 - ¯®áâ ¢¨âì â®çªã ä®®¢®¬ ¨§®¡à ¦¥¨¨. = |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
* edx = 梥â â®çª¨ 0xRRGGBB |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¬¥é¥¨¥ ¤«ï â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª |
(x+y*xsize)*3. |
* ᫨ 㪠§ ®¥ ᬥ饨¥ ¯à¥¢ëè ¥â 0x160000-16 = |
1.375 Mb - 16 bytes, ¢ë§®¢ ¨£®à¨àã¥âáï. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï â®çª¨ á ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 39. |
====================================================================== |
============ ãªæ¨ï 15, ¯®¤äãªæ¨ï 3 - ¯¥à¥à¨á®¢ âì ä®. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ०¨¬ ®âà¨á®¢ª¨: |
* 1 = § ¬®áâ¨âì |
* 2 = à áâïãâì |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï ª®¬ ¤ ¯®«ã票ï ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 39. |
====================================================================== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 5 - ¯®¬¥áâ¨âì ¡«®ª ¯¨ªá¥«¥© ä®. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* edx = ᬥ饨¥ ¢ ¤ ëå ä®®¢®£® ¨§®¡à ¦¥¨ï |
* esi = à §¬¥à ¤ ëå ¢ ¡ ©â å = 3 * ç¨á«® ¯¨ªá¥«¥© |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¡«®ª ¢ë«¥§ ¥â § £à ¨æã 0x160000-16 = 1.375 Mb - 16 bytes, |
â® ¢ë§®¢ ¨£®à¨àã¥âáï. |
* ¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ¨âáï ª ª 3-¡ ©â ï ¢¥«¨ç¨ BBGGRR. |
* ¨ªá¥«¨ ä®®¢®£® ¨§®¡à ¦¥¨ï § ¯¨áë¢ îâáï ¯®á«¥¤®¢ â¥«ì® |
á«¥¢ ¯à ¢®, ᢥàåã ¢¨§. |
* ¬¥é¥¨¥ ¯¨ªá¥«ï á ª®®à¤¨ â ¬¨ (x,y) ¥áâì (x+y*xsize)*3. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
====================================================================== |
============= ãªæ¨ï 16 - á®åà ¨âì à ¬¤¨áª ¤¨áª¥âã. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 16 - ®¬¥à äãªæ¨¨ |
* ebx = 1 ¨«¨ ebx = 2 - ª ªãî ¤¨áª¥âã á®åà ïâì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª |
====================================================================== |
============== ãªæ¨ï 17 - ¯®«ãç¨âì ª®¤ ¦ ⮩ ª®¯ª¨. ============= |
====================================================================== |
¡¨à ¥â ª®¤ ¦ ⮩ ª®¯ª¨ ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 17 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1 |
* ¥á«¨ ¡ãä¥à ¥¯ãáâ, â® ¢®§¢à é ¥âáï al=0, áâ à訥 24 ¡¨â eax |
ᮤ¥à¦ â ¨¤¥â¨ä¨ª â®à ª®¯ª¨ (¢ ç áâ®áâ¨, ¢ ah ®ª §ë¢ ¥âáï |
¬« ¤è¨© ¡ ©â ¨¤¥â¨ä¨ª â®à ; ¥á«¨ ¢á¥ ª®¯ª¨ ¨¬¥îâ ¨¤¥â¨ä¨ª â®à, |
¬¥ì訩 256, â® ¤«ï à §«¨ç¥¨ï ¤®áâ â®ç® ah) |
¬¥ç ¨ï: |
* "ãä¥à" åà ¨â ⮫쪮 ®¤ã ª®¯ªã, ¯à¨ ¦ ⨨ ®¢®© ª®¯ª¨ |
¨ä®à¬ æ¨ï ® áâ ன â¥àï¥âáï. |
* ਠ¢ë§®¢¥ í⮩ äãªæ¨¨ ¯à¨«®¦¥¨¥¬ á ¥ ªâ¨¢ë¬ ®ª®¬ |
¢®§¢à é ¥âáï ®â¢¥â "¡ãä¥à ¯ãáâ". |
====================================================================== |
======== ãªæ¨ï 18, ¯®¤äãªæ¨ï 1 - § ¢¥àè¨âì à ¡®âã á¨á⥬ë. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ¢á¥£¤ ¢®§¢à é ¥âáï eax = 0 ª ª ¯à¨§ ª ãᯥå |
¬¥ç ¨ï: |
* ¯®á«¥¤¥¬ è £¥ ¯®ï¢«ï¥âáï ¬¥î ¢ë室 ¨§ á¨á⥬ë, ®¦¨¤ î饥 |
ॠªæ¨¨ ¯®«ì§®¢ ⥫ï. |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 9, § ¢¥à襨¥ à ¡®âë á¨á⥬ë á ¯ à ¬¥â஬, |
ç⮡ë ä®àá¨à®¢ âì ¢ë¡®à ¢ ¬¥î ¢ë室 . |
====================================================================== |
==== ãªæ¨ï 18, ¯®¤äãªæ¨ï 2 - § ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® á«®âã. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᫮⠯à®æ¥áá /¯®â®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à 樮®© á¨á⥬ë OS/IDLE (®¬¥à á«®â |
1), ¬®¦® § ¢¥àè¨âì «î¡®© ®¡ëçë© ¯®â®ª/¯à®æ¥áá. |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 18 - § ¢¥à襨¥ |
¯à®æ¥áá /¯®â®ª á § ¤ ë¬ ¨¤¥â¨ä¨ª â®à®¬. |
====================================================================== |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 3 - ᤥ« âì ªâ¨¢ë¬ ®ª® § ¤ ®£® ¯®â®ª . = |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᫮⠯®â®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ਠ㪠§ ¨¨ ª®à४⮣®, ® ¥áãé¥áâ¢ãî饣® ᫮⠪⨢¨§¨àã¥âáï |
ª ª®¥-â® ®ª®. |
* § âì, ª ª®¥ ®ª® ï¥âáï ªâ¨¢ë¬, ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7. |
====================================================================== |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì áç¸â稪 ¯ãáâëå ⠪⮢ ¢ ᥪã¤ã. |
====================================================================== |
®¤ ¯ãáâ묨 ⠪⠬¨ ¯®¨¬ ¥âáï ¢à¥¬ï, ¢ ª®â®à®¥ ¯à®æ¥áá®à ¯à®áâ ¨¢ ¥â |
¢ ®¦¨¤ ¨¨ ¯à¥àë¢ ¨ï (¢ ¨áâàãªæ¨¨ hlt). |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = § 票¥ áç¸â稪 ¯ãáâëå ⠪⮢ ¢ ᥪã¤ã |
====================================================================== |
======== ãªæ¨ï 18, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì ⠪⮢ãî ç áâ®âã. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⠪⮢ ï ç áâ®â (¯® ¬®¤ã«î 2^32 ⠪⮢ = 4æ) |
====================================================================== |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 6 - á®åà ¨âì à ¬¤¨áª ¢ ä ©« ¦¸á⪮¬ ¤¨áª¥. |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx ®¯à¥¤¥«ï¥â ¯ãâì ª ä ©«ã: |
* 1 = ¢ ¯ ¯ª¥ "/KOLIBRI" |
* 2 = ¢ ª®à¥¢®¬ ª â «®£¥ |
* 3 = edx 㪠§ë¢ ¥â ¯ãâì (¨¬¥ ¯ ¯®ª ¢ ä®à¬ ⥠8+3, |
à §¤¥«¸ë¥ '/') |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* ¨ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* ¬ï ä ©« 䨪á¨à®¢ ®, "menuet.img" (£«®¡ «ì ï ¯¥à¥¬¥ ï ï¤à |
image_save ¨§ preboot.inc) |
* ª ª®¬ à §¤¥«¥ ª ª®£® ¤¨áª ä ©« ¡ã¤¥â á®åà ¸, ®¯à¥¤¥«ï¥âáï |
¯®¤äãªæ¨¥© 7 ¨ ¯®¤äãªæ¨¥© 8 äãªæ¨¨ 21. |
* ᥠ¯ ¯ª¨ ¢ 㪠§ ®¬ ¯ã⨠¤®«¦ë áãé¥á⢮¢ âì, ¨ ç¥ ¢¥à¸âáï |
§ 票¥ 5, "ä ©« ¥ ©¤¥". |
====================================================================== |
====== ãªæ¨ï 18, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ®¬¥à ªâ¨¢®£® ®ª . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ªâ¨¢®£® ®ª (®¬¥à ᫮⠯®â®ª , ®ª® ª®â®à®£® |
ªâ¨¢®) |
¬¥ç ¨ï: |
* ªâ¨¢®¥ ®ª® 室¨âáï ¢¢¥àåã ®ª®®£® áâíª ¨ ¯®«ãç ¥â |
á®®¡é¥¨ï ®¡® ¢á¸¬ ¢¢®¤¥ á ª« ¢¨ âãàë. |
* ¤¥« âì ®ª® ªâ¨¢ë¬ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 3. |
====================================================================== |
==== ãªæ¨ï 18, ¯®¤äãªæ¨ï 8 - ®âª«îç¨âì/à §à¥è¨âì §¢ãª ᯨª¥à . ==== |
====================================================================== |
ਠ®âª«î縮¬ §¢ãª¥ ¢ë§®¢ë ¯®¤äãªæ¨¨ 55 äãªæ¨¨ 55 ¨£®à¨àãîâáï. |
ਠ¢ª«î縮¬ - ¯à ¢«ïîâáï ¢áâà®¥ë© á¯¨ª¥à. |
--------------- ®¤¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥. ---------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - §¢ãª ᯨª¥à à §à¥è¸; 1 - § ¯à¥é¸ |
-------------- ®¤¯®¤äãªæ¨ï 2 - ¯¥à¥ª«îç¨âì á®áâ®ï¨¥. -------------- |
¥à¥ª«îç ¥â á®áâ®ï¨ï à §à¥è¥¨ï/§ ¯à¥é¥¨ï. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 9 - § ¢¥à襨¥ à ¡®âë á¨á⥬ë á ¯ à ¬¥â஬. = |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¯ à ¬¥âà: |
* 1 = ¯®á«¥¤¥¬ è £¥ § ¢¥à襨ï à ¡®âë á®åà ¨âì à ¬¤¨áª |
¤¨áª¥âã, ¯®á«¥ 祣® ¢ë¢¥á⨠¬¥î ¢ë室 ¨ § ¯à®á¨âì ã |
¯®«ì§®¢ â¥«ï ¤ «ì¥©è¨¥ ¤¥©á⢨ï |
* 2 = ¢ëª«îç¨âì ª®¬¯ìîâ¥à |
* 3 = ¯¥à¥§ £à㧨âì ª®¬¯ìîâ¥à |
* 4 = ¯¥à¥§ ¯ãáâ¨âì ï¤à® ¨§ ä ©« kernel.mnt à ¬¤¨áª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* ¯à¨ ¥¢¥à®¬ ecx ॣ¨áâàë ¥ ¬¥ïîâáï (â.¥. eax=18) |
* ¯à¨ ¯à ¢¨«ì®¬ ¢ë§®¢¥ ¢á¥£¤ ¢®§¢à é ¥âáï ¯à¨§ ª ãᯥå eax=0 |
¬¥ç ¨ï: |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥ ¯à¨ ¥¢¥à®¬ |
¢ë§®¢¥, ®® ¬®¦¥â ¨§¬¥¨âìáï ¢ ¯®á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à . |
* ®¦® ¨á¯®«ì§®¢ âì ¯®¤äãªæ¨î 1, çâ®¡ë ¯®á«¥¤¥¬ è £¥ |
§ ¢¥à襨ï à ¡®âë ¯®«ì§®¢ ⥫ì á ¬ à¥è «, çâ® ¥¬ã 㦮. |
* ¥ ४®¬¥¤ã¥âáï ¨á¯®«ì§®¢ âì § 票¥ ecx=1 (çâ®¡ë ¥ à §¤à ¦ âì |
¯®«ì§®¢ â¥«ï ¨§«¨è¨¬¨ ¢®¯à®á ¬¨); á®åà ¨âì à ¬¤¨áª ¤¨áª¥âã |
¬®¦® äãªæ¨¥© 16 (ª®â®à ï ¤®¯ã᪠¥â ãâ®ç¥¨¥, ª ªãî ¨¬¥® |
¤¨áª¥âã ¯¨á âì), § ¢¥àè¨âì à ¡®âã á ¬¥î ¢ë室 ¬®¦® 㦥 |
㯮¬ïã⮩ ¯®¤äãªæ¨¥© 1. |
====================================================================== |
======== ãªæ¨ï 18, ¯®¤äãªæ¨ï 10 - ᢥàãâì ®ª® ¯à¨«®¦¥¨ï. ======= |
====================================================================== |
¢®à 稢 ¥â ᮡá⢥®¥ ®ª®. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¨¨¬¨§¨à®¢ ®¥ ®ª® á â®çª¨ §à¥¨ï äãªæ¨¨ 9 á®åà ï¥â ¯®«®¦¥¨¥ |
¨ à §¬¥àë. |
* ®ááâ ®¢«¥¨¥ ®ª ¯à¨«®¦¥¨ï ¯à®¨á室¨â ¯à¨ ªâ¨¢¨§¨à®¢ ¨¨ |
¯®¤äãªæ¨¥© 3. |
* ¡ëç® ¥â ¥®¡å®¤¨¬®á⨠ ᢮à 稢 âì/à §¢®à 稢 âì ᢮¸ ®ª®: |
᢮à 稢 ¨¥ ®ª ®áãé¥á⢫ï¥âáï á¨á⥬®© ¯à¨ ¦ ⨨ ª®¯ªã |
¬¨¨¬¨§ 樨 (ª®â®à ï ¤«ï ®ª® ᮠ᪨®¬ ®¯à¥¤¥«ï¥âáï ¢â®¬ â¨ç¥áª¨ |
äãªæ¨¥© 0, ¤«ï ®ª® ¡¥§ ᪨ ¥¸ ¬®¦® ®¯à¥¤¥«¨âì äãªæ¨¥© 8), |
¢®ááâ ®¢«¥¨¥ - ¯à¨«®¦¥¨¥¬ @panel. |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 11 ===================== |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ® ¤¨áª®¢®© ¯®¤á¨á⥬¥. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ â ¡«¨æë: |
* 1 = ª®à®âª ï ¢¥àá¨ï, 10 ¡ ©â |
* 2 = ¯®« ï ¢¥àá¨ï, 65536 ¡ ©â |
* edx = 㪠§ â¥«ì ¡ãä¥à (¢ ¯à¨«®¦¥¨¨) ¤«ï â ¡«¨æë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â â ¡«¨æë: ª®à®âª ï ¢¥àá¨ï: |
* +0: byte: ¨ä®à¬ æ¨ï ® (¤¨áª®¢®¤ å ¤«ï ¤¨áª¥â), AAAABBBB, |
£¤¥ AAAA § ¤ ¸â ⨯ ¯¥à¢®£® ¤¨áª®¢®¤ , BBBB - ¢â®à®£® ᮣ« á® |
á«¥¤ãî饬ã ᯨáªã: |
* 0 = ¥â ¤¨áª®¢®¤ |
* 1 = 360Kb, 5.25'' |
* 2 = 1.2Mb, 5.25'' |
* 3 = 720Kb, 3.5'' |
* 4 = 1.44Mb, 3.5'' |
* 5 = 2.88Mb, 3.5'' (â ª¨¥ ¤¨áª¥âë ᥩç á 㦥 ¥ ¨á¯®«ì§ãîâáï) |
¯à¨¬¥à, ¤«ï áâ ¤ à⮩ ª®ä¨£ãà 樨 ¨§ ®¤®£® 1.44-¤¨áª®¢®¤ |
§¤¥áì ¡ã¤¥â 40h, ¤«ï á«ãç ï 1.2Mb A: ¨ 1.44Mb B: |
§ 票¥ ®ª §ë¢ ¥âáï 24h. |
* +1: byte: ¨ä®à¬ æ¨ï ® ¦¸áâª¨å ¤¨áª å ¨ CD-¯à¨¢®¤ å, AABBCCDD, |
£¤¥ AA ᮮ⢥âáâ¢ã¥â ª®â஫«¥àã IDE0, ..., DD - IDE3: |
* 0 = ãáâனá⢮ ®âáãâáâ¢ã¥â |
* 1 = ¦¸á⪨© ¤¨áª |
* 2 = CD-¯à¨¢®¤ |
¯à¨¬¥à, ¢ á«ãç ¥ HD IDE0 ¨ CD IDE2 §¤¥áì ¡ã¤¥â 48h. |
* +2: 4 db: ç¨á«® ©¤¥ëå à §¤¥«®¢ ¦¸áâª¨å ¤¨áª å á |
ᮮ⢥âá⢥® IDE0,...,IDE3. |
ਠ®âáãâá⢨¨ ¦¸á⪮£® ¤¨áª IDEx ᮮ⢥âáâ¢ãî騩 ¡ ©â |
ã«¥¢®©, ¯à¨ «¨ç¨¨ ¯®ª §ë¢ ¥â ç¨á«® à ᯮ§ ëå à §¤¥«®¢, |
ª®â®àëå ¬®¦¥â ¨ ¥ ¡ëâì (¥á«¨ ®á¨â¥«ì ¥ ®âä®à¬ â¨à®¢ ¨«¨ |
¥á«¨ ä ©«®¢ ï á¨á⥬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï). ⥪ã饩 ¢¥àᨨ ï¤à |
¤«ï ¦¸áâª¨å ¤¨áª®¢ ¯®¤¤¥à¦¨¢ îâáï ⮫쪮 FAT16 ¨ FAT32. |
* +6: 4 db: § १¥à¢¨à®¢ ® |
®à¬ â â ¡«¨æë: ¯®« ï ¢¥àá¨ï: |
* +0: 10 db: â ª¨¥ ¦¥, ª ª ¨ ¢ ª®à®âª®© ¢¥àᨨ |
* +10: 100 db: ¤ ë¥ ¤«ï ¯¥à¢®£® à §¤¥« |
* +110: 100 db: ¤ ë¥ ¤«ï ¢â®à®£® à §¤¥« |
* ... |
* +10+100*(n-1): 100 db: ¤ ë¥ ¤«ï ¯®á«¥¤¥£® à §¤¥« |
§¤¥«ë à ᯮ«®¦¥ë ¢ á«¥¤ãî饬 ¯®à浪¥: á ç « ¯®á«¥¤®¢ â¥«ì® ¢á¥ |
à ᯮ§ ë¥ à §¤¥«ë HD IDE0 (¥á«¨ ¥áâì), |
§ ⥬ HD IDE1 (¥á«¨ ¥áâì) ¨ â.¤. ¤® IDE3. |
®à¬ â ¨ä®à¬ 樨 ® à §¤¥«¥ (¯®ª ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 FAT): |
* +0: dword: ç «ìë© ä¨§¨ç¥áª¨© ᥪâ®à à §¤¥« |
* +4: dword: ¯®á«¥¤¨© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« |
(¯à¨ ¤«¥¦¨â à §¤¥«ã) |
* +8: dword: ᥪâ®à®¢ ¢ ®¤®© ª®¯¨¨ FAT |
* +12 = +0xC: dword: ç¨á«® ª®¯¨© FAT |
* +16 = +0x10: dword: ç¨á«® ᥪâ®à®¢ ¢ ª« áâ¥à¥ |
* +20 = +0x14: dword: ¡ ©â ¢ ᥪâ®à¥; ⥪ãé ï ॠ«¨§ æ¨ï ®¦¨¤ ¥â, |
çâ® §¤¥áì 0x200 = 512 |
* +24 = +0x18: dword: ¯¥à¢ë© ª« áâ¥à ª®à¥¢®£® ª â «®£ ¢ FAT32, |
0 ¤«ï FAT16 |
* +28 = +0x1C: dword: ç «ìë© ä¨§¨ç¥áª¨© ᥪâ®à FAT |
* +32 = +0x20: dword: ¯¥à¢ë© 䨧¨ç¥áª¨© ᥪâ®à ª®à¥¢®£® ª â «®£ |
¤«ï FAT16, ¨£®à¨àã¥âáï ¤«ï FAT32 |
* +36 = +0x24: dword: ç¨á«® ᥪâ®à®¢ ¢ ª®à¥¢®¬ ª â «®£¥ ¤«ï FAT16, |
0 ¤«ï FAT32 |
* +40 = +0x28: dword: 䨧¨ç¥áª¨© ᥪâ®à ç « ®¡« á⨠¤ ëå |
* +44 = +0x2C: dword: ¬ ªá¨¬ «ìë© ®¬¥à ª« áâ¥à |
* +48 = +0x30: dword: 䨧¨ç¥áª¨© ᥪâ®à ¨ä®à¬ 樨 ® |
ä ©«®¢®© á¨á⥬¥ ¤«ï FAT32, ¨£®à¨àã¥âáï ¤«ï FAT16 |
* +52 = +0x34: dword: § 票¥, ¨á¯®«ì§ã¥¬®¥ ª ª £à ¨æ |
á¯¥æ¨ «ìëå § 票© ¢ FAT |
* +56 = +0x38: dword: § 票¥, ¨á¯®«ì§ã¥¬®¥ ¤«ï ¯«®å¨å ª« áâ¥à®¢ |
¢ FAT |
* +60 = +0x3C: dword: § 票¥, ¨á¯®«ì§ã¥¬®¥ ª ª ¬ àª¥à ª®æ |
¯à¨ § ¯¨á¨ 楯®çª¨ ¢ FAT |
* +64 = +0x40: dword: ¬ ᪠, ª« ¤ë¢ ¥¬ ï í«¥¬¥â FAT |
* +68 = +0x44: byte: ⨯ ä ©«®¢®© á¨á⥬ë: 16 ¨«¨ 32 |
* +69 = +0x45: 31 db: § १¥à¢¨à®¢ ® |
¬¥ç ¨ï: |
* ®à®âª ï â ¡«¨æ ¬®¦¥â ¡ëâì ¨á¯®«ì§®¢ ¤«ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 |
®¡ ¨¬¥îé¨åáï ãáâனá⢠å. |
* ¥à¢ë¥ ¤¢ ¯®«ï ¨ä®à¬ 樨 ® à §¤¥«¥ ¢ ¯®«®© ¢¥àᨨ â ¡«¨æë |
á®®¡é îâ ¯ à ¬¥âàë à §¤¥« , ®á⠢訥áï - ¯ à ¬¥âàë ä ©«®¢®© |
á¨á⥬ë FAT. «ï ¤à㣨å ä ©«®¢ëå á¨á⥬ (ª®£¤ ®¨ ¡ã¤ãâ |
¯®¤¤¥à¦¨¢ âìáï) ᯥæ¨ä¨ç¥áª ï ¤«ï ä ©«®¢®© á¨áâ¥¬ë ¨ä®à¬ æ¨ï, |
¥áâ¥á⢥®, ¡ã¤¥â ¤à㣮©, ® ¯¥à¢ë¥ ¤¢ ¯®«ï |
á®åà ïâáï ¥¨§¬¥ë¬¨. |
====================================================================== |
========== ãªæ¨ï 18, ¯®¤äãªæ¨ï 13 - ¯®«ãç¨âì ¢¥àá¨î ï¤à . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à (¥ ¬¥¥¥ 16 ¡ ©â), ªã¤ ¡ã¤¥â ¯®¬¥é¥ |
¨ä®à¬ æ¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
âàãªâãà ¡ãä¥à : |
db a,b,c,d ¤«ï ¢¥àᨨ a.b.c.d |
db UID_xxx: ®¤® ¨§ UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 |
db 'name',0 - ASCIIZ-áâப á ¨¬¥¥¬ |
«ï ï¤à Kolibri 0.5.8.1: |
db 0,5,8,1 |
db 2 |
db 'Kolibri',0 |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 14 ===================== |
======= ¦¨¤ âì ç « ®¡à ⮣® 室 «ãç à §¢¸à⪨ ¬®¨â®à . ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ª ª ¯à¨§ ª ãᯥå |
¬¥ç ¨ï: |
* ãªæ¨ï ¯à¥¤ § ç¥ ¨áª«îç¨â¥«ì® ¤«ï ªâ¨¢ëå |
¢ë᮪®¯à®¨§¢®¤¨â¥«ìëå £à ä¨ç¥áª¨å ¯à¨«®¦¥¨©; ¨á¯®«ì§ã¥âáï ¤«ï |
¯« ¢®£® ¢ë¢®¤ £à 䨪¨. |
====================================================================== |
== ãªæ¨ï 18, ¯®¤äãªæ¨ï 15 - ¯®¬¥áâ¨âì ªãàá®à ¬ëè¨ ¢ æ¥âà íªà . = |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 15 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ª ª ¯à¨§ ª ãᯥå |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 16 ===================== |
============ ®«ãç¨âì à §¬¥à ᢮¡®¤®© ®¯¥à ⨢®© ¯ ¬ïâ¨. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 16 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = à §¬¥à ᢮¡®¤®© ¯ ¬ï⨠¢ ª¨«®¡ ©â å |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 17 ===================== |
============ ®«ãç¨âì à §¬¥à ¨¬¥î饩áï ®¯¥à ⨢®© ¯ ¬ïâ¨. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 17 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¡é¨© à §¬¥à ¨¬¥î饩áï ¯ ¬ï⨠¢ ª¨«®¡ ©â å |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 18 ===================== |
============= ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® ¨¤¥â¨ä¨ª â®àã. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 18 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯à®æ¥áá /¯®â®ª (PID/TID) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡ª (¯à®æ¥áá ¥ ©¤¥ ¨«¨ ï¥âáï á¨á⥬ë¬) |
¬¥ç ¨ï: |
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à 樮®© á¨á⥬ë OS/IDLE (®¬¥à á«®â |
1), ¬®¦® § ¢¥àè¨âì «î¡®© ®¡ëçë© ¯®â®ª/¯à®æ¥áá. |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 2 - § ¢¥à襨¥ |
¯à®æ¥áá /¯®â®ª ¯® § ¤ ®¬ã á«®âã. |
====================================================================== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 19 ===================== |
============= ®«ãç¨âì/ãáâ ®¢¨âì áâனª¨ ¬ëè¨. =================== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ¯®äãªæ¨¨ 2-£® ã஢ï. |
ecx = 0 - ¯®«ãç¨âì ᪮à®áâì ¬ëè¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ãé ï ᪮à®áâì ¬ëè¨ |
ecx = 1 - ãáâ ®¢¨âì ᪮à®áâì ¬ëè¨ |
edx = ãáâ ¢«¨¢ ¥¬®¥ § 票¥ ᪮à®á⨠|
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
ecx = 2 - ¯®«ãç¨âì § ¤¥à¦ªã ã᪮२ï |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ãé ï § ¤¥à¦ª ã᪮२ï |
ecx = 3 - ãáâ ®¢¨âì § ¤¥à¦ªã ã᪮२ï |
edx = ãáâ ¢«¨¢ ¥¬ ï § ¤¥à¦ª ã᪮२ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
ecx = 4 - ãáâ ®¢¨âì ¯®§¨æ¨î ªãàá®à ¬ëè¨ íªà ¥ |
edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥ª®¬¥¤ã¥¬ ï ᪮à®áâì ¬ëè¨ (¢ ¯®¤äãªæ¨¨ 1) ®â 1 ¤® 9. |
áâ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨ ¥ ª®â஫¨àã¥âáï ª®¤®¬ ï¤à , ¯® í⮬ã |
¨á¯®«ì§ã©â¥ ®áâ®à®¦®, ¯à¨ ¥ª®à४⮬ § 票¨ ªãàá®à ¬®¦¥â "§ ¬¥à§ãâì". |
ª®à®áâì ¬ëè¨ ¬®¦® ॣ㫨஢ âì ç¥à¥§ ¯à¨«®¦¥¨¥ SETUP. |
* ¥ª®¬¥¤ã¥¬ ï ¢¥«¨ç¨ § ¤¥à¦ª¨ (¢ ¯®¤äãªæ¨¨ 3) = 10. ®«¥¥ ¨§ª®¥ |
§ 票¥ ¥ ®¡à ¡ âë¢ ¥âáï COM ¬ëè ¬¨. ਠ®ç¥ì ¡®«ìè¨å § 票ïå |
¥¢®§¬®¦® ¯¥à¥¤¢¨¦¥¨¥ ¬ëè¨ 1 ¯¨ªá¥«ì ¨ ªãàá®à ¡ã¤¥â ¯àë£ âì |
¢¥«¨ç¨ã ãáâ ®¢«¥®© ᪮à®á⨠(¯®¤äãªæ¨ï 1). |
áâ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨ ¥ ª®â஫¨àã¥âáï ª®¤®¬ ï¤à . |
* ¯®¤äãªæ¨¨ 4 ãáâ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨ ¥ ª®â஫¨àã¥âáï ª®¤®¬ ï¤à . |
¥à¥¤ ¨á¯®«ì§®¢ ¨¥¬ ¥®¡å®¤¨¬® 㧠âì ⥪ã饥 à §à¥è¥¨¥ íªà ¨ |
¯à¨ ãáâ ®¢ª¥ ¯®§¨æ¨¨ á«¥¤¨âì, çâ®¡ë ¢¥«¨ç¨ ¯®§¨æ¨¨ ¥ ¢ë室¨« § |
¯à¥¤¥«ë íªà . |
====================================================================== |
============ ãªæ¨ï 19 - § ¯ãáâ¨âì ¯à®£à ¬¬ã á à ¬¤¨áª . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 19 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ¯à®£à ¬¬ë ¢ ä®à¬ â¥, «®£¨ç®¬ äãªæ¨¨ 6 |
* ecx = 0 ¨«¨ ecx = 㪠§ â¥«ì ¯ à ¬¥âàë ª®¬ ¤®© áâப¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ᫨ eax > 0, â® eax ᮤ¥à¦¨â PID ᮧ¤ ®£® ¯à®æ¥áá |
* ᫨ eax < 0, â® -eax - ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 7 äãªæ¨¨ 70. |
* ®¬ ¤ ï áâப ¤®«¦ § ª 稢 âìáï ᨬ¢®«®¬ á ª®¤®¬ 0 |
(ASCIIZ-áâப ); ãç¨âë¢ îâáï «¨¡® ¢á¥ ᨬ¢®«ë ¤® § ¢¥àè î饣® ã«ï |
¢ª«îç¨â¥«ì®, «¨¡® ¯¥à¢ë¥ 256 ᨬ¢®«®¢, ¢ § ¢¨á¨¬®á⨠®â ⮣®, |
çâ® ¬¥ìè¥. |
====================================================================== |
==================== ãªæ¨ï 20 - ¨â¥à䥩á MIDI. ==================== |
====================================================================== |
------------------------ ®¤äãªæ¨ï 1 - á¡à®á ------------------------ |
à ¬¥âàë: |
* eax = 20 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
-------------------- ®¤äãªæ¨ï 2 - ¢ë¢¥á⨠¡ ©â --------------------- |
à ¬¥âàë: |
* eax = 20 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ¡ ©â ¤«ï ¢ë¢®¤ |
®§¢à é ¥¬®¥ § 票¥ (®¤¨ ª®¢® ¤«ï ®¡¥¨å ¯®¤äãªæ¨©): |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¸ ¡ §®¢ë© ¯®àâ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ®¯à¥¤¥«¸ ¡ §®¢ë© ¯®à⠢맮¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 21. |
====================================================================== |
==== ãªæ¨ï 21, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ¡ §®¢®£® ¯®àâ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡®çë© ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* ®¬¥à ¯®àâ ¤®«¦¥ 㤮¢«¥â¢®àïâì ãá«®¢¨ï¬ 0x100<=ecx<=0xFFFF. |
* áâ ®¢ª ¡ §ë 㦠¤«ï à ¡®âë äãªæ¨¨ 20. |
* ®«ãç¨âì ãáâ ®¢«¥ë© ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 26. |
====================================================================== |
===== ãªæ¨ï 21, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì à ᪫ ¤ªã ª« ¢¨ âãàë. ==== |
====================================================================== |
᪫ ¤ª ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ¨ï ᪠ª®¤®¢, |
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨âë¢ ¥¬ë¥ äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª ªãî à ᪫ ¤ªã ãáâ ¢«¨¢ âì: |
* 1 = ®à¬ «ìãî |
* 2 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Shift |
* 3 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Alt |
* edx = 㪠§ ⥫ì à ᪫ ¤ªã - â ¡«¨æã ¤«¨®© 128 ¡ ©â |
Ǭ: |
* ecx = 9 |
* dx = ¨¤¥â¨ä¨ª â®à áâà ë (1=eng, 2=fi, 3=ger, 4=rus) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯ à ¬¥âà § ¤ ¥¢¥à® |
¬¥ç ¨ï: |
* ᫨ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Alt; |
¥á«¨ ¥ ¦ â Alt, ® ¦ â Shift, â® |
¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Shift; |
¥á«¨ ¥ ¦ âë Alt ¨ Shift, ® ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª , ¯®á«¥ 祣® ¨§ ª®¤ ¢ëç¨â ¥âáï 0x60; |
¥á«¨ ¥ ¦ â ¨ ®¤ ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª . |
* ®«ãç¨âì à ᪫ ¤ª¨ ¨ ¨¤¥â¨ä¨ª â®à áâà ë ¬®¦® á ¯®¬®éìî |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 26. |
* ¤¥â¨ä¨ª â®à áâà ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ª®â®à ï |
á ¬¨¬ ï¤à®¬ ¥ ¨á¯®«ì§ã¥âáï; ®¤ ª® ¯à¨«®¦¥¨¥ @panel ®â®¡à ¦ ¥â |
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ¥ ¨ª®ªã. |
* ਫ®¦¥¨¥ @panel ¯¥à¥ª«îç ¥â à ᪫ ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ ⥫ï. |
====================================================================== |
=========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì ¡ §ã CD. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ § CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* § CD ¨á¯®«ì§ã¥âáï äãªæ¨¥© 24. |
* ®«ãç¨âì ãáâ ®¢«¥ãî ¡ §ã CD ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 26. |
====================================================================== |
== ãªæ¨ï 21, ¯®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ¡ §®¢ë© ¯®àâ Sound Blaster. = |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ¡ §®¢®£® ¯®àâ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡®çë© ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* ®¬¥à ¯®àâ ¤®«¦¥ 㤮¢«¥â¢®àïâì ãá«®¢¨ï¬ 0x100<=ecx<=0xFFFF. |
* áâ ®¢ª ¡ §ë 㦠¤«ï à ¡®âë äãªæ¨© 25, 28, 55. |
* ®«ãç¨âì ãáâ ®¢«¥ë© ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 4 äãªæ¨¨ 26. |
====================================================================== |
========= ãªæ¨ï 21, ¯®¤äãªæ¨ï 5 - ãáâ ®¢¨âì ï§ëª á¨á⥬ë. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* §ëª á¨á⥬ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ¨ª ª |
¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤ ª® ¯à¨«®¦¥¨¥ @panel à¨áã¥â |
ᮮ⢥âáâ¢ãîéãî ¨ª®ªã. |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï, ¯®áª®«ìªã ï¤à® íâã |
¯¥à¥¬¥ãî ¥ ¨á¯®«ì§ã¥â. |
* ®«ãç¨âì ï§ëª á¨áâ¥¬ë ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 5 äãªæ¨¨ 26. |
====================================================================== |
======= ãªæ¨ï 21, ¯®¤äãªæ¨ï 6 - ãáâ ®¢¨âì ¡ §®¢ë© ¯®àâ WSS. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ §®¢ë© ¯®àâ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡®çë© ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* ®¬¥à ¯®àâ ¤®«¦¥ 㤮¢«¥â¢®àïâì ãá«®¢¨î 0x100<=ecx. |
* § WSS ¨á¯®«ì§ã¥âáï äãªæ¨¥© 27. |
* ®«ãç¨âì ãáâ ®¢«¥ë© ¡ §®¢ë© ¯®àâ WSS ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 6 äãªæ¨¨ 26. |
====================================================================== |
=========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 7 - ãáâ ®¢¨âì ¡ §ã HD. =========== |
====================================================================== |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦¸á⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢè¨å äãªæ¨© à ¡®âë á ä ©«®¢®© á¨á⥬®© ¨ äãªæ¨©, |
¥ï¢® ¨á¯®«ì§ãîé¨å ¦¸á⪨© ¤¨áª (⨯ ¯®¤äãªæ¨¨ 6 äãªæ¨¨ 18); |
¯à¨ ¨á¯®«ì§®¢ ¨¨ äãªæ¨© 58 ¨ 70 ¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 í⨠äãªæ¨¨ á ¬¨ ãáâ ¢«¨¢ îâ ¡ §ã. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì ¡ §ã, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦¸á⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ãî ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 26. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦¸á⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 8. |
====================================================================== |
========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 8 - ãáâ ®¢¨âì à §¤¥« HD. ========== |
====================================================================== |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦¸á⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢè¨å äãªæ¨© à ¡®âë á ä ©«®¢®© |
á¨á⥬®© ¨ äãªæ¨©, ¥ï¢® ¨á¯®«ì§ãîé¨å ¦¸á⪨© ¤¨áª (⨯ |
¯®¤äãªæ¨¨ 6 äãªæ¨¨ 18); ¯à¨ ¨á¯®«ì§®¢ ¨¨ äãªæ¨© 58 ¨ 70 |
¨ ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 í⨠äãªæ¨¨ á ¬¨ |
ãáâ ¢«¨¢ îâ ¡ §ã ¨ à §¤¥«. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = à §¤¥« HD (áç¨â ï á 1) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì à §¤¥«, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦¸á⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ë© à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 |
äãªæ¨¨ 26. |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï. |
* § âì ç¨á«® à §¤¥«®¢ ¦¸á⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦¸á⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 7. |
====================================================================== |
===== ãªæ¨ï 21, ¯®¤äãªæ¨ï 10 - ãáâ ®¢¨âì ª « DMA ¤«ï §¢ãª . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ª « (®â 0 ¤® 3 ¢ª«îç¨â¥«ì®) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ¥¢¥àë© ®¬¥à ª « |
¬¥ç ¨ï: |
* ®¬¥à ª « DMA ¨á¯®«ì§ã¥âáï ¢ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 55. |
* ®«ãç¨âì ª « DMA ¤«ï §¢ãª ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 10 äãªæ¨¨ 26. |
====================================================================== |
====================== ãªæ¨ï 21, ¯®¤äãªæ¨ï 11 ===================== |
=========== §à¥è¨âì/§ ¯à¥â¨âì ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª HD. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ LBA-ç⥨¨ (¯®¤äãªæ¨ï 8 äãªæ¨¨ 58). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* ®«ãç¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 11 äãªæ¨¨ 26. |
====================================================================== |
====================== ãªæ¨ï 21, ¯®¤äãªæ¨ï 12 ===================== |
========== §à¥è¨âì/§ ¯à¥â¨âì ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ à ¡®â¥ á 訮© PCI (äãªæ¨ï 62). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* ®«ãç¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 12 äãªæ¨¨ 26. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 1 ============= |
==== ¨æ¨ «¨§¨à®¢ âì + ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ¤à ©¢¥à¥ vmode.mdr. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à 512 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¤à ©¢¥à ¥ § £à㦥 (¨ª®£¤ ¥ ¡ë¢ ¥â ¢ ⥪ã饩 ॠ«¨§ 樨): |
* eax = -1 |
* ebx, ecx à §àãè îâáï |
* ¥á«¨ ¤à ©¢¥à § £à㦥: |
* eax = 'MDAZ' (¢ á⨫¥ fasm' , â.¥. 'M' - ¬« ¤è¨© ¡ ©â, |
'Z' - áâ à訩) - ᨣ âãà |
* ebx = ⥪ãé ï ç áâ®â à §¢¸à⪨ (¢ æ) |
* ecx à §àãè ¥âáï |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â edx, § ¯®«¥ |
®à¬ â ¡ãä¥à : |
* +0: 32*byte: ¨¬ï ¤à ©¢¥à , "Trans VideoDriver" (¡¥§ ª ¢ë祪, |
¤®¯®«¥® ¯à®¡¥« ¬¨) |
* +32 = +0x20: dword: ¢¥àá¨ï ¤à ©¢¥à (¢¥àá¨ï x.y ª®¤¨àã¥âáï ª ª |
y*65536+x), ¤«ï ⥪ã饩 ॠ«¨§ 樨 1 (1.0) |
* +36 = +0x24: 7*dword: § १¥à¢¨à®¢ ® (0 ¢ ⥪ã饩 ॠ«¨§ 樨) |
* +64 = +0x40: 32*word: ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ¢¨¤¥®à¥¦¨¬®¢ (ª ¦¤®¥ |
á«®¢® - ®¬¥à ¢¨¤¥®à¥¦¨¬ , ¯®á«¥ ᮡá⢥® ᯨ᪠¨¤ãâ 㫨) |
* +128 = +0x80: 32*(5*word): ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â à §¢¸à⮪ |
¤«ï ¢¨¤¥®à¥¦¨¬®¢: ¤«ï ª ¦¤®£® ¢¨¤¥®à¥¦¨¬ , 㪠§ ®£® ¢ ¯à¥¤ë¤ã饬 |
¯®«¥, 㪠§ ® ¤® 5 ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â |
(¢ ¥¨á¯®«ì§ã¥¬ëå ¯®§¨æ¨ïå § ¯¨á ë 㫨) |
¬¥ç ¨ï: |
* ãªæ¨ï ¨¨æ¨ «¨§¨àã¥â ¤à ©¢¥à (¥á«¨ ® ¥é¸ ¥ ¨¨æ¨ «¨§¨à®¢ ) |
¨ ¤®«¦ ¢ë§ë¢ âìáï ¯¥à¢®©, ¯¥à¥¤ ®áâ «ì묨 (¨ ç¥ ®¨ ¡ã¤ãâ |
¢®§¢à é âì -1, ¨ç¥£® ¥ ¤¥« ï). |
* ⥪ã饩 ॠ«¨§ 樨 ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ®¤ ç áâ®â à §¢¸à⪨ |
¢¨¤¥®à¥¦¨¬. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 2 ============= |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ® ⥪ã饬 ¢¨¤¥®à¥¦¨¬¥. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ ; |
ebx,ecx à §àãè îâáï |
* eax = [è¨à¨ ]*65536 + [¢ëá®â ] |
* ebx = ç áâ®â ¢¥à⨪ «ì®© à §¢¸à⪨ (¢ æ) |
* ecx = ®¬¥à ⥪ã饣® ¢¨¤¥®à¥¦¨¬ |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ᫨ ã¦ë ⮫쪮 à §¬¥àë íªà , 楫¥á®®¡à §¥© ¨á¯®«ì§®¢ âì |
äãªæ¨î 14 á ãç¸â®¬ ⮣®, çâ® ® ¢®§¢à é ¥â à §¬¥àë 1 ¬¥ìè¥. |
====================================================================== |
= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì ¢¨¤¥®à¥¦¨¬. |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 3 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = [ç áâ®â à §¢¸à⪨]*65536 + [®¬¥à ¢¨¤¥®à¥¦¨¬ ] |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥, ¥ ¨¨æ¨ «¨§¨à®¢ ¨«¨ |
¯à®¨§®è« ®è¨¡ª |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ®¬¥à ¢¨¤¥®à¥¦¨¬ ¨ ç áâ®â ¤®«¦ë ¡ëâì ¢ â ¡«¨æ¥, ¢®§¢à é ¥¬®© |
äãªæ¨¥© ¤à ©¢¥à 1. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 4 ============= |
================= ¥àãâìáï ª ç «ì®¬ã ¢¨¤¥®à¥¦¨¬ã. ================ |
====================================================================== |
®§¢à é ¥â íªà ¢ ¢¨¤¥®à¥¦¨¬, ãáâ ®¢«¥ë© ¯à¨ § £à㧪¥ á¨á⥬ë. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 4 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
====================================================================== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 5 ============= |
======== ¢¥«¨ç¨âì/㬥ìè¨âì à §¬¥à ¢¨¤¨¬®© ®¡« á⨠¬®¨â®à . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 5 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = 0/1 - 㬥ìè¨âì/㢥«¨ç¨âì à §¬¥à ¯® £®à¨§®â «¨ |
®¤ã ¯®§¨æ¨î |
* edx = 2/3 - ¢ ⥪ã饩 ॠ«¨§ 樨 ¥ ¯®¤¤¥à¦¨¢ ¥âáï; ¯« ¨àã¥âáï |
ª ª 㬥ì襨¥/㢥«¨ç¥¨¥ à §¬¥à ¯® ¢¥à⨪ «¨ ®¤ã ¯®§¨æ¨î |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ãªæ¨ï ¢«¨ï¥â ⮫쪮 䨧¨ç¥áª¨© à §¬¥à ¨§®¡à ¦¥¨ï |
¬®¨â®à¥; «®£¨ç¥áª¨© à §¬¥à (ç¨á«® ¯¨ªá¥«¥©) ¥ ¬¥ï¥âáï. |
====================================================================== |
============ ãªæ¨ï 22 - ãáâ ®¢¨âì á¨á⥬ãî ¤ âã/¢à¥¬ï. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 22 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ãáâ ®¢¨âì ¢à¥¬ï |
* ecx = 0x00SSMMHH - ¢à¥¬ï ¢ ¤¢®¨ç®-¤¥áïâ¨ç®¬ ª®¤¥ (BCD): |
* HH=ç á 00..23 |
* MM=¬¨ãâ 00..59 |
* SS=ᥪ㤠00..59 |
* ebx = 1 - ãáâ ®¢¨âì ¤ âã |
* ecx = 0x00DDMMYY - ¤ â ¢ ¤¢®¨ç®-¤¥áïâ¨ç®¬ ª®¤¥ (BCD): |
* DD=¤¥ì 01..31 |
* MM=¬¥áïæ 01..12 |
* YY=£®¤ 00..99 |
* ebx = 2 - ãáâ ®¢¨âì ¤¥ì ¥¤¥«¨ |
* ecx = 1 ¤«ï ¢®áªà¥á¥ìï, ..., 7 ¤«ï áã¡¡®âë |
* ebx = 3 - ãáâ ®¢¨âì ¡ã¤¨«ì¨ª |
* ecx = 0x00SSMMHH |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯ à ¬¥âà § ¤ ¥¢¥à® |
* eax = 2 - CMOS-¡ â ३ª¨ à §à廊«¨áì |
¬¥ç ¨ï: |
* ¥®áâì ãáâ ®¢ª¨ ¤ï ¥¤¥«¨ ¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©, |
¯®áª®«ìªã ® ¬ «® £¤¥ ¨á¯®«ì§ã¥âáï |
(¤¥ì ¥¤¥«¨ ¬®¦® à ááç¨â âì ¯® ¤ â¥). |
* 㤨«ì¨ª ¬®¦® ãáâ ®¢¨âì áà ¡ âë¢ ¨¥ ¢ § ¤ ®¥ ¢à¥¬ï |
ª ¦¤ë¥ áã⪨. ਠí⮬ ®âª«îç¨âì ¥£® áãé¥áâ¢ãî騬¨ á¨á⥬묨 |
äãªæ¨ï¬¨ ¥«ì§ï. |
* à ¡ âë¢ ¨¥ ¡ã¤¨«ì¨ª § ª«îç ¥âáï ¢ £¥¥à 樨 IRQ8. |
* ®®¡é¥-â® CMOS ¯®¤¤¥à¦¨¢ ¥â ¤«ï ¡ã¤¨«ì¨ª ãáâ ®¢ªã § 票ï |
0xFF ¢ ª ç¥á⢥ ®¤®£® ¨§ ¯ à ¬¥â஢ ¨ ®§ ç ¥â íâ®, çâ® |
ᮮ⢥âáâ¢ãî騩 ¯ à ¬¥âà ¨£®à¨àã¥âáï. ® ¢ ⥪ã饩 ॠ«¨§ 樨 |
íâ® ¥ ¯à®©¤¸â (¢¥à¸âáï § 票¥ 1). |
* 㤨«ì¨ª - £«®¡ «ìë© á¨áâ¥¬ë© à¥áãàá; ãáâ ®¢ª ¡ã¤¨«ì¨ª |
¢â®¬ â¨ç¥áª¨ ®â¬¥ï¥â ¯à¥¤ë¤ãéãî ãáâ ®¢ªã. ¯à®ç¥¬, ¤ ë© |
¬®¬¥â ¨ ®¤ ¯à®£à ¬¬ ¥£® ¥ ¨á¯®«ì§ã¥â. |
====================================================================== |
============== ãªæ¨ï 23 - ®¦¨¤ âì ᮡëâ¨ï á â ©¬ ã⮬. ============= |
====================================================================== |
᫨ ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ , ¦¤¸â ¯®ï¢«¥¨ï á®®¡é¥¨ï ¢ ®ç¥à¥¤¨, |
® ¥ ¡®«¥¥ 㪠§ ®£® ¢à¥¬¥¨. ⥬ áç¨âë¢ ¥â á®®¡é¥¨¥ ¨§ ®ç¥à¥¤¨. |
à ¬¥âàë: |
* eax = 23 - ®¬¥à äãªæ¨¨ |
* ebx = â ©¬ ãâ (¢ á®âëå ¤®«ïå ᥪã¤ë) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ |
* ¨ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 11. |
â®¡ë ¦¤ âì ᪮«ì 㣮¤® ¤®«£®, ¨á¯®«ì§ã©â¥ äãªæ¨î 10. |
* ¥à¥¤ ç ebx=0 ¯à¨¢®¤¨â ª ¬®¬¥â «ì®¬ã ¢®§¢à 饨î eax=0. |
* ਠ⥪ã饩 ॠ«¨§ 樨 ¯à®¨§®©¤¸â ¥¬¥¤«¥ë© ¢®§¢à â ¨§ äãªæ¨¨ |
á eax=0, ¥á«¨ á«®¦¥¨¥ ebx á ⥪ã騬 § 票¥¬ áç¸â稪 ¢à¥¬¥¨ |
¢ë§®¢¥â 32-¡¨â®¥ ¯¥à¥¯®«¥¨¥. |
====================================================================== |
======= ãªæ¨ï 24, ¯®¤äãªæ¨ï 1 - ç âì ¯à®¨£àë¢ âì CD-audio. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0x00FRSSMM, £¤¥ |
* MM = ç «ì ï ¬¨ãâ |
* SS = ç «ì ï ᥪ㤠|
* FR = ç «ìë© ä३¬ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
* ᥪ㤥 75 ä३¬®¢, ¢ ¬¨ã⥠60 ᥪã¤. |
* ãªæ¨ï á¨åà® (¢®§¢à é ¥â ã¯à ¢«¥¨¥, ª®£¤ ç «®áì |
¯à®¨£àë¢ ¨¥). |
====================================================================== |
===== ãªæ¨ï 24, ¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ¤®à®¦ª å. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï â ¡«¨æë |
(¬ ªá¨¬ã¬ 8*64h+4 ¡ ©â=100 ¤®à®¦¥ª) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ®à¬ â â ¡«¨æë á ¨ä®à¬ 樥© ® ¤®à®¦ª å â ª®© ¦¥, ª ª ¨ ¤«ï |
ATAPI-CD ª®¬ ¤ë 43h (READ TOC), ®¡ë箩 â ¡«¨æë (¯®¤ª®¬ ¤ 00h). |
¤à¥á ¢®§¢à é îâáï ¢ ä®à¬ ⥠MSF. |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
* ãªæ¨ï ¢®§¢à é ¥â ¨ä®à¬ æ¨î ⮫쪮 ® ¥ ¡®«¥¥ 祬 100 |
¯¥à¢ëå ¤®à®¦ª å. ¡®«ìè¨á⢥ á«ãç ¥¢ í⮣® ¤®áâ â®ç®. |
====================================================================== |
==== ãªæ¨ï 24, ¯®¤äãªæ¨ï 3 - ®áâ ®¢¨âì ¯à®¨£àë¢ ¥¬®¥ CD-audio. === |
====================================================================== |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
====================================================================== |
============== ãªæ¨ï 25 - ãáâ ®¢¨âì £à®¬ª®áâì SBPro. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 25 - ®¬¥à äãªæ¨¨ |
* ebx = çâ® ãáâ ¢«¨¢ âì: |
* 1 - ãáâ ®¢¨âì ®¡éãî £à®¬ª®áâì |
* 2 - ãáâ ®¢¨âì £à®¬ª®áâì CD-audio |
* cl = ã஢¥ì £à®¬ª®áâ¨: áâ à訥 4 ¡¨â ¤«ï «¥¢®© ª®«®ª¨, |
¬« ¤è¨¥ 4 - ¤«ï ¯à ¢®© |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § SB |
* eax = 2 - ¥¢¥à ï ¯®¤äãªæ¨ï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ SB ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 4 äãªæ¨¨ 21. |
* ¬®âਠ⠪¦¥ äãªæ¨î 28 |
ãáâ ®¢ª¨ §¢ãª ¤«ï ¡®«¥¥ ¯®§¤¥£® áâ ¤ àâ SB16. |
====================================================================== |
===== ãªæ¨ï 26, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* áâ ®¢¨âì ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 21. |
====================================================================== |
====== ãªæ¨ï 26, ¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì à ᪫ ¤ªã ª« ¢¨ âãàë. ===== |
====================================================================== |
᪫ ¤ª ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ¨ï ᪠ª®¤®¢, |
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨âë¢ ¥¬ë¥ äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª ªãî à ᪫ ¤ªã ¯®«ãç âì: |
* 1 = ®à¬ «ìãî |
* 2 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Shift |
* 3 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Alt |
* edx = 㪠§ â¥«ì ¡ãä¥à ¤«¨®© 128 ¡ ©â, ªã¤ ¡ã¤¥â ᪮¯¨à®¢ |
à ᪫ ¤ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
Ǭ: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 9 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¨¤¥â¨ä¨ª â®à áâà ë (1=eng, 2=fi, 3=ger, 4=rus) |
¬¥ç ¨ï: |
* ᫨ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Alt; |
¥á«¨ ¥ ¦ â Alt, ® ¦ â Shift, â® ¨á¯®«ì§ã¥âáï |
à ᪫ ¤ª á Shift; |
¥á«¨ ¥ ¦ âë Alt ¨ Shift, ® ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª , ¯®á«¥ 祣® ¨§ ª®¤ ¢ëç¨â ¥âáï 0x60; |
¥á«¨ ¥ ¦ â ¨ ®¤ ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª . |
* áâ ®¢¨âì à ᪫ ¤ª¨ ¨ ¨¤¥â¨ä¨ª â®à áâà ë ¬®¦® á ¯®¬®éìî |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 21. |
* ¤¥â¨ä¨ª â®à áâà ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ª®â®à ï |
á ¬¨¬ ï¤à®¬ ¥ ¨á¯®«ì§ã¥âáï; ®¤ ª® ¯à¨«®¦¥¨¥ @panel ®â®¡à ¦ ¥â |
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ¥ ¨ª®ªã |
(¨á¯®«ì§ãï ®¯¨áë¢ ¥¬ãî äãªæ¨î). |
* ਫ®¦¥¨¥ @panel ¯¥à¥ª«îç ¥â à ᪫ ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ ⥫ï. |
====================================================================== |
============ ãªæ¨ï 26, ¯®¤äãªæ¨ï 3 - ¯®«ãç¨âì ¡ §ã CD. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ § CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
¬¥ç ¨ï: |
* § CD ¨á¯®«ì§ã¥âáï äãªæ¨¥© 24. |
* áâ ®¢¨âì ¡ §ã CD ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
====================================================================== |
=== ãªæ¨ï 26, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ Sound Blaster. == |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ¡ §®¢®£® ¯®àâ |
¬¥ç ¨ï: |
* áâ ®¢ª ¡ §ë 㦠¤«ï à ¡®âë äãªæ¨© 25, 55. |
* áâ ®¢¨âì ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 4 äãªæ¨¨ 21. |
====================================================================== |
========== ãªæ¨ï 26, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì ï§ëª á¨á⥬ë. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus) |
¬¥ç ¨ï: |
* §ëª á¨á⥬ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ¨ª ª |
¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤ ª® ¯à¨«®¦¥¨¥ @panel à¨áã¥â |
ᮮ⢥âáâ¢ãîéãî ¨ª®ªã (¨á¯®«ì§ãï ®¯¨áë¢ ¥¬ãî äãªæ¨î). |
* áâ ®¢¨âì ï§ëª á¨áâ¥¬ë ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 5 äãªæ¨¨ 21. |
====================================================================== |
======== ãªæ¨ï 26, ¯®¤äãªæ¨ï 6 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ WSS. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ §®¢ë© ¯®àâ |
¬¥ç ¨ï: |
* § WSS ¨á¯®«ì§ã¥âáï äãªæ¨¥© 27. |
* áâ ®¢¨âì ¡ §®¢ë© ¯®àâ WSS ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 6 äãªæ¨¨ 21. |
====================================================================== |
============ ãªæ¨ï 26, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ¡ §ã HD. ============ |
====================================================================== |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦¸á⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢè¨å äãªæ¨© à ¡®âë á ä ©«®¢®© á¨á⥬®© ¨ äãªæ¨©, |
¥ï¢® ¨á¯®«ì§ãîé¨å ¦¸á⪨© ¤¨áª (⨯ ¯®¤äãªæ¨¨ 6 äãªæ¨¨ 18); |
¯à¨ ¨á¯®«ì§®¢ ¨¨ äãªæ¨© 58 ¨ 70 ¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 í⨠äãªæ¨¨ á ¬¨ ãáâ ¢«¨¢ îâ ¡ §ã. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* áâ ®¢¨âì ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 21. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦¸á⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 8. |
====================================================================== |
=========== ãªæ¨ï 26, ¯®¤äãªæ¨ï 8 - ¯®«ãç¨âì à §¤¥« HD. =========== |
====================================================================== |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦¸á⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢè¨å äãªæ¨© à ¡®âë á ä ©«®¢®© |
á¨á⥬®© ¨ äãªæ¨©, ¥ï¢® ¨á¯®«ì§ãîé¨å ¦¸á⪨© ¤¨áª (⨯ |
¯®¤äãªæ¨¨ 6 äãªæ¨¨ 18); ¯à¨ ¨á¯®«ì§®¢ ¨¨ äãªæ¨© 58 ¨ 70 ¨ |
ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 í⨠äãªæ¨¨ á ¬¨ |
ãáâ ¢«¨¢ îâ ¡ §ã ¨ à §¤¥«. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = à §¤¥« HD (áç¨â ï á 1) |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* áâ ®¢¨âì à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 äãªæ¨¨ 21. |
* § âì ç¨á«® à §¤¥«®¢ ¦¸á⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦¸á⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 7. |
====================================================================== |
=== ãªæ¨ï 26, ¯®¤äãªæ¨ï 9 - ¯®«ãç¨âì § 票¥ áç¸â稪 ¢à¥¬¥¨. === |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® á®âëå ¤®«¥© ᥪã¤ë, ¯à®è¥¤è¨å á ¬®¬¥â |
§ ¯ã᪠á¨á⥬ë |
¬¥ç ¨ï: |
* ç¸â稪 ¡¥à¸âáï ¯® ¬®¤ã«î 2^32, ç⮠ᮮ⢥âáâ¢ã¥â ¥¬®£¨¬ ¡®«¥¥ |
497 áã⮪. |
* ¨á⥬®¥ ¢à¥¬ï ¬®¦® ¯®«ãç¨âì äãªæ¨¥© 3. |
====================================================================== |
====== ãªæ¨ï 26, ¯®¤äãªæ¨ï 10 - ¯®«ãç¨âì ª « DMA ¤«ï §¢ãª . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ª « (®â 0 ¤® 3 ¢ª«îç¨â¥«ì®) |
¬¥ç ¨ï: |
* ®¬¥à ª « DMA ¨á¯®«ì§ã¥âáï ¢ ¯®¤äãªæ¨¨ 1 äãªæ¨¨ 55. |
* áâ ®¢¨âì ª « DMA ¤«ï §¢ãª ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 10 äãªæ¨¨ 21. |
====================================================================== |
====================== ãªæ¨ï 26, ¯®¤äãªæ¨ï 11 ===================== |
=========== § âì, à §à¥è¸ «¨ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª HD. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0/1 - § ¯à¥é¸/à §à¥è¸ |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ LBA-ç⥨¨ (¯®¤äãªæ¨ï 8 äãªæ¨¨ 58). |
* áâ ®¢¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 21. |
====================================================================== |
====================== ãªæ¨ï 26, ¯®¤äãªæ¨ï 12 ===================== |
========== § âì, à §à¥è¸ «¨ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0/1 - § ¯à¥é¸/à §à¥è¸ |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ à ¡®â¥ á 訮© PCI (äãªæ¨ï 62). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* áâ ®¢¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 12 äãªæ¨¨ 21. |
====================================================================== |
==== ãªæ¨ï 27 - ãáâ ®¢¨âì £à®¬ª®áâì Windows Sound System (WSS). === |
====================================================================== |
à ¬¥âàë: |
* eax = 27 - ®¬¥à äãªæ¨¨ |
* ebx = çâ® ãáâ ¢«¨¢ âì: |
* 1 - ãáâ ®¢¨âì ®¡éãî £à®¬ª®áâì |
* 2 - ãáâ ®¢¨âì £à®¬ª®áâì Line In |
* cl = ã஢¥ì £à®¬ª®á⨠(0x0=á ¬ë© ¢ë᮪¨©, 0x1F=á ¬ë© ¨§ª¨©, |
ãáâ ®¢«¥ë© ¡¨â 0x80=®âª«îç¨âì) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § WSS |
* eax = 2 - ¥¢¥à ï ¯®¤äãªæ¨ï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ WSS ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 6 äãªæ¨¨ 21. |
* áâ ®¢ª ®¡é¥© £à®¬ª®áâ¨ ä ªâ¨ç¥áª¨ ¨£®à¨àã¥âáï |
(¢®§¢à é ¥âáï eax=0). |
* áâ ன ¤®ªã¬¥â 樨 ¨ ¢ ¨á室¨ª å ï¤à ¯®¤äãªæ¨ï 2 |
®è¨¡®ç® §¢ £à®¬ª®áâìî CD-audio. |
====================================================================== |
=============== ãªæ¨ï 28 - ãáâ ®¢¨âì £à®¬ª®áâì SB16. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 28 - ®¬¥à äãªæ¨¨ |
* ebx = çâ® ãáâ ¢«¨¢ âì: |
* 1 - ãáâ ®¢¨âì ®¡éãî £à®¬ª®áâì |
* 2 - ãáâ ®¢¨âì £à®¬ª®áâì CD-audio |
* cl = ã஢¥ì £à®¬ª®á⨠(0=off, 0xFF=max) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § SB |
* eax = 2 - ¥¢¥à ï ¯®¤äãªæ¨ï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ SB ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 4 äãªæ¨¨ 21. |
* â äãªæ¨ï ¯à¥¤®áâ ¢«ï¥â ¡®«ìè¥ ¢ ਠ⮢ ¤«ï £à®¬ª®áâ¨, |
祬 äãªæ¨ï 25. |
====================================================================== |
================ ãªæ¨ï 29 - ¯®«ãç¨âì á¨á⥬ãî ¤ âã. =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 29 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00DDMMYY, £¤¥ |
(¨á¯®«ì§ã¥âáï ¤¢®¨ç®-¤¥áïâ¨ç®¥ ª®¤¨à®¢ ¨¥, BCD) |
* YY = ¤¢¥ ¬« ¤è¨¥ æ¨äàë £®¤ (00..99) |
* MM = ¬¥áïæ (01..12) |
* DD = ¤¥ì (01..31) |
¬¥ç ¨ï: |
* ¨á⥬ãî ¤ âã ¬®¦® ãáâ ®¢¨âì äãªæ¨¥© 22. |
====================================================================== |
================ ãªæ¨ï 32 - 㤠«¨âì ä ©« á à ¬¤¨áª . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 32 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 58 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ¥ªãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â ⮫쪮 § 票ï 0(ãᯥå) ¨ |
5(ä ©« ¥ ©¤¥). |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ (¯¥à¢ë¥ |
8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
====================================================================== |
=============== ãªæ¨ï 33 - § ¯¨á âì ä ©« à ¬¤¨áª. =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 33 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
* ecx = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* á«¥¤ã¥â ãáâ ¢«¨¢ âì esi=0 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ᫨ 㪠§ âì ¥ã«¥¢®¥ § 票¥ ¢ esi ¨ à ¬¤¨áª¥ 㦥 ¥áâì |
㪠§ ë© ä ©«, â® ¡ã¤¥â ᮧ¤ ¥é¸ ®¤¨ ä ©« á ⥬ ¦¥ ¨¬¥¥¬. |
* ¯à®â¨¢®¬ á«ãç ¥ ä ©« ¯¥à¥§ ¯¨áë¢ ¥âáï. |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ |
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
====================================================================== |
============ ãªæ¨ï 35 - ¯à®ç¨â âì 梥â â®çª¨ íªà ¥. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 35 |
* ebx = y*xsize+x, £¤¥ |
* (x,y) = ª®®à¤¨ âë â®çª¨ (áç¨â ï ®â 0) |
* xsize = à §¬¥à íªà ¯® £®à¨§®â «¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 梥â 0x00RRGGBB |
¬¥ç ¨ï: |
* § âì à §¬¥àë íªà ¬®¦® ¢ë§®¢®¬ äãªæ¨¨ 14. ¡à â¨â¥ ¢¨¬ ¨¥, |
çâ® ® ¢ëç¨â ¥â 1 ¨§ ®¡®¨å à §¬¥à®¢. |
* ¢¨¤¥®¯ ¬ï⨠¥áâì â ª¦¥ ¯àאַ© ¤®áâ㯠(¡¥§ ¢ë§®¢®¢ á¨á⥬ëå |
äãªæ¨©) ç¥à¥§ ᥫ¥ªâ®à gs. à ¬¥âàë ⥪ã饣® ¢¨¤¥®à¥¦¨¬ |
¬®¦® ¯®«ãç¨âì äãªæ¨¥© 61. |
====================================================================== |
========== ãªæ¨ï 37 - ¯®«ãç¨âì ª®®à¤¨ âë/á®áâ®ï¨¥ ¬ëè¨. ========== |
====================================================================== |
-------------- ®¤äãªæ¨ï 0 - íªà ë¥ ª®®à¤¨ âë ¬ëè¨ --------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ (áç¨â ï ®â 0) |
---------- ®¤äãªæ¨ï 1 - ª®®à¤¨ âë ¬ëè¨ ®â®á¨â¥«ì® ®ª ---------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ ®â®á¨â¥«ì® |
®ª ¯à¨«®¦¥¨ï (áç¨â ï ®â 0) |
¬¥ç ¨ï: |
* 票¥ ¢ëç¨á«ï¥âáï ¯® ä®à¬ã«¥ (x-xwnd)*65536 + (y-ywnd). |
᫨ y>=ywnd, â® ¬« ¤è¥¥ á«®¢® ¥®âà¨æ â¥«ì® ¨ ᮤ¥à¦¨â |
®â®á¨â¥«ìãî y-ª®®à¤¨ âã, áâ à襥 - ®â®á¨â¥«ìãî x-ª®®à¤¨ âã |
(¯à ¢¨«ì®£® § ª ). ¯à®â¨¢®¬ á«ãç ¥ ¬« ¤è¥¥ á«®¢® ®âà¨æ â¥«ì® |
¨ ¢á¸ à ¢® ᮤ¥à¦¨â ®â®á¨â¥«ìãî y-ª®®à¤¨ âã, |
ª áâ à襬ã á«®¢ã á«¥¤ã¥â ¯à¨¡ ¢¨âì 1. |
----------------- ®¤äãªæ¨ï 2 - ¦ âë¥ ª®¯ª¨ ¬ëè¨ ----------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax ᮤ¥à¦¨â ¨ä®à¬ æ¨î ® ¦ âëå ª®¯ª å ¬ëè¨: |
* ¡¨â 0 ãáâ ®¢«¥ = «¥¢ ï ª®¯ª ¦ â |
* ¡¨â 1 ãáâ ®¢«¥ = ¯à ¢ ï ª®¯ª ¦ â |
* ¯à®ç¨¥ ¡¨âë á¡à®è¥ë |
====================================================================== |
================== ãªæ¨ï 38 - à¨á®¢ âì ®â१®ª. ================== |
====================================================================== |
à ¬¥âàë: |
* eax = 38 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ç « ¯® ®á¨ x]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ç « ¯® ®á¨ y]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ y] |
* edx = 0x00RRGGBB - 梥â |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¡¥àãâáï ®â®á¨â¥«ì® ®ª . |
* ®¥ç ï â®çª â ª¦¥ à¨áã¥âáï. |
====================================================================== |
== ãªæ¨ï 39, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì à §¬¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. == |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [è¨à¨ ]*65536 + [¢ëá®â ] |
¬¥ç ¨ï: |
* áâì ¯ à ï ª®¬ ¤ ãáâ ®¢ª¨ à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 15. ®á«¥ ª®â®à®©, à §ã¬¥¥âáï, á«¥¤ã¥â |
§ ®¢® ®¯à¥¤¥«¨âì á ¬® ¨§®¡à ¦¥¨¥. |
====================================================================== |
= ãªæ¨ï 39, ¯®¤äãªæ¨ï 2 - ¯à®ç¨â âì â®çªã á ä®®¢®£® ¨§®¡à ¦¥¨ï. = |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00RRGGBB - 梥â â®çª¨, ¥á«¨ ᬥ饨¥ ¤®¯ãá⨬® |
(¬¥ìè¥ 0x160000-16) |
* eax = 2 - ¨ ç¥ |
¬¥ç ¨ï: |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥ ¢ á«ãç ¥ ¥¢¥à®£® |
ᬥ饨ï, ®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à . |
* ¬¥é¥¨¥ â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª (x+y*xsize)*3. |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ â®çª¨ ä®®¢®¬ ¨§®¡à ¦¥¨¨ - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 15. |
====================================================================== |
====== ãªæ¨ï 39, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 - § ¬®áâ¨âì |
* eax = 2 - à áâïãâì |
¬¥ç ¨ï: |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 15. |
====================================================================== |
======== ãªæ¨ï 40 - ãáâ ®¢¨âì ¬ áªã ¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩. ======== |
====================================================================== |
᪠¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩ ¢«¨ï¥â äãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨ 10, |
11, 23 - ®¨ á®®¡é îâ ⮫쪮 ® ᮡëâ¨ïå, à §à¥è¸ëå í⮩ ¬ ᪮©. |
à ¬¥âàë: |
* eax = 40 - ®¬¥à äãªæ¨¨ |
* ebx = ¬ ᪠: ¡¨â i ᮮ⢥âáâ¢ã¥â ᮡëâ¨î i+1 (á¬. ᯨ᮪ ᮡë⨩) |
(ãáâ ®¢«¥ë© ¡¨â à §à¥è ¥â ¨§¢¥é¥¨¥ ® ᮡë⨨) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᪠¯® 㬮«ç ¨î (7=111b) à §à¥è ¥â ¨§¢¥é¥¨ï ® ¯¥à¥à¨á®¢ª¥ |
¨ ¦ â¨ïå ª« ¢¨è ¨ ª®¯®ª. |
⮣® ¤®áâ â®ç® ¤«ï ¡®«ìè¨á⢠¯à¨«®¦¥¨©. |
* ®¡ëâ¨ï, § ¯à¥é¸ë¥ ¢ ¬ ᪥, ¢á¸ à ¢® á®åà ïîâáï, ¥á«¨ |
¯à¨å®¤ïâ; ® ¨å ¯à®áâ® ¥ ¨§¢¥é îâ äãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨. |
* ãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨ ãç¨âë¢ îâ ¬ áªã ¬®¬¥â |
¢ë§®¢ äãªæ¨¨, ¥ ¬®¬¥â ¯®áâ㯫¥¨ï á®®¡é¥¨ï. |
====================================================================== |
================= ãªæ¨ï 41 - 㧠âì ¢« ¤¥«ìæ IRQ. ================= |
====================================================================== |
à ¬¥âàë: |
* eax = 41 - ®¬¥à äãªæ¨¨ |
* ebx = ®¬¥à IRQ, 0..15 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = PID ¢« ¤¥«ìæ |
* eax = 0, ¥á«¨ ¢« ¤¥«ìæ ¥â |
* eax = -1 ¤«ï ¥ª®à४⮣® ebx |
====================================================================== |
========== ãªæ¨ï 42 - ¯à®ç¨â âì ¤ ë¥, ¯®«ãç¥ë¥ ¯® IRQ. ========= |
====================================================================== |
ਠ¢®§¨ª®¢¥¨¨ IRQ á¨á⥬ ¬®¦¥â áç¨âë¢ âì ¤ ë¥ ¨§ 㪠§ ëå |
à ¥¥ äãªæ¨¥© 44 ¯®à⮢ ¨ § ¯¨áë¢ âì í⨠¤ ë¥ ¢ ¡ãä¥à. |
¯¨áë¢ ¥¬ ï äãªæ¨ï áç¨âë¢ ¥â ¯®¡ ©â® ¤ ë¥ ¨§ í⮣® ¡ãä¥à . |
à ¬¥âàë: |
* eax = 42 - ®¬¥à äãªæ¨¨ |
* ebx = ®¬¥à IRQ, 0..15 |
®§¢à é ¥¬®¥ § 票¥: (á¨âã æ¨î ¬®¦® à §«¨ç¨âì ¯® § 票î ecx) |
* ¥á«¨ ¯®â®ª ¥ ï¥âáï ¢« ¤¥«ì楬 IRQ |
(¨«¨ ®¬¥à IRQ § ¤ ¥¢¥à®): |
* ecx = 2 |
* ¥á«¨ ¤ ëå ¥â: |
* eax = 0 |
* ecx = 1 |
* ebx à §àãè ¥âáï |
* ¥á«¨ ¢á¸ ¢ ¯®à浪¥ ¨ ¤ ë¥ ¡ë«¨: |
* eax = à §¬¥à ¤ ëå, ¥é¸ ¥ ¯à®ç¨â ëå ¨§ ¡ãä¥à (¢ ¡ ©â å) |
* ecx = 0 |
* ebx = ®ç¥à¥¤®© ¡ ©â |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¯®â®ª ¤®«¦¥ § १¥à¢¨à®¢ âì ¤«ï ᥡï 㪠§ ë© IRQ |
äãªæ¨¥© 45. |
* §¬¥à ¡ãä¥à ¤«ï ¤ ëå - 4000 ¡ ©â, ¯à¨ ¯¥à¥¯®«¥¨¨ |
"ᢥ¦¨¥" ¤ ë¥ ¯¥à¥áâ îâ § ¯¨áë¢ âìáï ¢ ¡ãä¥à. |
====================================================================== |
=================== ãªæ¨ï 43 - ¢¢®¤/¢ë¢®¤ ¢ ¯®àâ. ================== |
====================================================================== |
------------------------ 뢮¤ ¤ ëå ¢ ¯®àâ ------------------------- |
à ¬¥âàë: |
* eax = 43 - ®¬¥à äãªæ¨¨ |
* bl = ¡ ©â ¤«ï ¢ë¢®¤ |
* ecx = ®¬¥à ¯®àâ 0xnnnn (®â 0 ¤® 0xFFFF) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯®â®ª ¥ § १¥à¢¨à®¢ « 㪠§ ë© ¯®àâ |
------------------------ ¢®¤ ¤ ëå ¨§ ¯®àâ ------------------------ |
à ¬¥âàë: |
* eax = 43 - ®¬¥à äãªæ¨¨ |
* ebx ¨£®à¨àã¥âáï |
* ecx = 0x8000nnnn, £¤¥ nnnn = ®¬¥à ¯®àâ (®â 0 ¤® 0xFFFF) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¯à¨ í⮬ ebx = ¢¢¥¤¸ë© ¡ ©â |
* eax = 1 - ¯®â®ª ¥ § १¥à¢¨à®¢ « ¤ ë© ¯®àâ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¯®â®ª ¤®«¦¥ § १¥à¢¨à®¢ âì § ᮡ®© |
㪠§ ë© ¯®àâ äãªæ¨¥© 46. |
* «ï § १¥à¢¨à®¢ ëå ¯®à⮢ ¢¬¥áâ® ¢ë§®¢ íâ¨å äãªæ¨© |
«ãçè¥ ¨á¯®«ì§®¢ âì ª®¬ ¤ë ¯à®æ¥áá®à in/out - íâ® § ç¨â¥«ì® |
¡ëáâ॥ ¨ ¥áª®«ìª® ª®à®ç¥ ¨ ¯à®é¥. § ¥§ १¥à¢¨à®¢ ëå |
¯®à⮢ ç¨â âì ¢á¸ à ¢® ¥«ì§ï. |
====================================================================== |
======== ãªæ¨ï 44 - ®¯à¥¤¥«¨âì ¤¥©áâ¢¨ï ¯à¨ ¯®áâ㯫¥¨¨ IRQ. ======= |
====================================================================== |
ਠ¢®§¨ª®¢¥¨¨ IRQ á¨á⥬ ¬®¦¥â áç¨âë¢ âì ¤ ë¥ ¨§ 㪠§ ëå í⮩ |
äãªæ¨¥© ¯®à⮢ ¨ § ¯¨áë¢ âì í⨠¤ ë¥ ¢ ¡ãä¥à, ®âªã¤ ¨å ¬®¦® |
¯à®ç¨â âì äãªæ¨¥© 42. |
à ¬¥âàë: |
* eax = 44 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¬ áᨢ áâàãªâãà, ®¯¨áë¢ îé¨å ¯® ®¤®¬ã ¯®àâã: |
* +0: word: 0 ®§ ç ¥â ª®¥æ ¬ áᨢ , ¨ ç¥ ®¬¥à ¯®àâ |
* +2: byte: § १¥à¢¨à®¢ ® (¨£®à¨àã¥âáï) |
* +3: byte: 1=áç¨âë¢ âì ¡ ©â ¨§ í⮣® ¯®àâ , 2=áç¨âë¢ âì á«®¢® |
* ecx = ®¬¥à IRQ, 0..15 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯®â®ª ¥ ï¥âáï ¢« ¤¥«ì楬 㪠§ ®£® IRQ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¯®â®ª ¤®«¦¥ § १¥à¢¨à®¢ âì § ᮡ®© |
㪠§ë¢ ¥¬ë© IRQ äãªæ¨¥© 45. |
* ਨ¬ îâáï ¢® ¢¨¬ ¨¥ ⮫쪮 ¯¥à¢ë¥ 16 ¯®à⮢. |
* ¥ªãé ï ॠ«¨§ æ¨ï à áᬠâਢ ¥â ¥¯à ¢¨«ì®¥ § 票¥ ¯®«ï +3 |
ª ª ᨣ « ¯à¥ªà é¥¨ï ®¡à ¡®âª¨ IRQ. |
====================================================================== |
============ ãªæ¨ï 45 - § १¥à¢¨à®¢ âì/®á¢®¡®¤¨âì IRQ. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 45 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - § १¥à¢¨à®¢ âì, 1 = ®á¢®¡®¤¨âì |
* ecx = ®¬¥à IRQ, 0..15 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª (¥¢¥àë© ®¬¥à IRQ ¨«¨ |
¯®¯ë⪠§ १¥à¢¨à®¢ âì ¥á¢®¡®¤ë© IRQ ¨«¨ ®á¢®¡®¤¨âì IRQ, ¥ |
§ १¥à¢¨à®¢ ë© â¥ªã騬 ¯®â®ª®¬) |
¬¥ç ¨ï: |
* ¥§¥à¢¨à®¢ ¨¥ IRQ 㦮 ¤«ï à ¡®âë äãªæ¨© 42 ¨ 44. |
* ®«ìª® ®¤¨ ¯®â®ª ¬®¦¥â § १¥à¢¨à®¢ âì ª®ªà¥âë© IRQ. |
* IRQ, ®¡à ¡ âë¢ ¥¬ë¥ á¨á⥬®© á ¬®áâ®ï⥫ì®, १¥à¢¨àãîâáï |
á¨á⥬®© (¯®â®ª®¬ 1) ¯à¨ § £à㧪¥. |
* ਠ§ ¢¥à襨¨ ¯®â®ª ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï |
¢á¥ § १¥à¢¨à®¢ ë¥ ¨¬ IRQ. |
====================================================================== |
= ãªæ¨ï 46 - § १¥à¢¨à®¢ âì/®á¢®¡®¤¨âì £à㯯㠯®à⮢ ¢¢®¤ /¢ë¢®¤ . |
====================================================================== |
§ १¥à¢¨à®¢ ë¬ ¯®àâ ¬ ¬®¦® ®¡à é âìáï ¯àï¬ãî ¨§ ¯à¨«®¦¥¨ï |
ª®¬ ¤ ¬¨ in/out (४®¬¥¤ã¥¬ë© ᯮᮡ) ¨ ¢ë§®¢®¬ äãªæ¨¨ 43 |
(¥à¥ª®¬¥¤ã¥¬ë© ᯮᮡ). |
à ¬¥âàë: |
* eax = 46 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - § १¥à¢¨à®¢ âì, 1 - ®á¢®¡®¤¨âì |
* ecx = ®¬¥à ç « ¤¨ ¯ §® ¯®à⮢ |
* edx = ®¬¥à ª®æ ¤¨ ¯ §® ¯®à⮢ (¢ª«îç¨â¥«ì®) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª |
¬¥ç ¨ï: |
* á«ãç ¥ १¥à¢¨à®¢ ¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¢ë¯®«¥¨¥ |
®¤®£® ¨§ ãá«®¢¨©: |
* ç «ìë© ¤à¥á ¡®«ìè¥ ª®¥ç®£®; |
* 㪠§ ë© ¤¨ ¯ §® ᮤ¥à¦¨â ¥ª®à४âë© ®¬¥à ¯®àâ |
(ª®à४âë¥ - ®â 0 ¤® 0xFFFF); |
* ¯à¥¢ë襮 ®£à ¨ç¥¨¥ ®¡é¥¥ ç¨á«® § १¥à¢¨à®¢ ëå ®¡« á⥩ |
- ¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 255; |
* 㪠§ ë© ¤¨ ¯ §® ¯¥à¥á¥ª ¥âáï á ®¤¨¬ ¨§ |
à ¥¥ § १¥à¢¨à®¢ ëå |
* á«ãç ¥ ®á¢®¡®¦¤¥¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¯®¯ë⪠|
®á¢®¡®¦¤¥¨ï ¤¨ ¯ §® , ª®â®àë© à ¥¥ ¥ ¡ë« 楫¨ª®¬ |
§ १¥à¢¨à®¢ í⮩ ¦¥ äãªæ¨¥© (á â ª¨¬¨ ¦¥ § 票ﬨ ecx,edx). |
* ਠ®¡ à㦥¨¨ ®è¨¡ª¨ (¢ ®¡®¨å á«ãç ïå) ¨ª ª¨å ¤¥©á⢨© |
¥ ¯à®¨§¢®¤¨âáï. |
* ਠ§ £à㧪¥ á¨á⥬ १¥à¢¨àã¥â § ᮡ®© ¯®àâë 0..0xff, ¯à¨ |
®¡ à㦥¨¨ COM-¬ëè¨ - ¤®¯®«¨â¥«ì® ¤¨ ¯ §® COM-¯®à⮢ |
0x3f0..0x3ff ¨/¨«¨ 0x2f0..0x2ff. |
* ਠ§ ¢¥à襨¨ ¯®â®ª ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï ¢á¥ |
§ १¥à¢¨à®¢ ë¥ ¨¬ ¯®àâë. |
====================================================================== |
================= ãªæ¨ï 47 - ¢ë¢¥á⨠ç¨á«® ¢ ®ª®. ================= |
====================================================================== |
à ¬¥âàë: |
* eax = 47 - ®¬¥à äãªæ¨¨ |
* ebx = ¯ à ¬¥âàë ¯à¥®¡à §®¢ ¨ï ç¨á« ¢ ⥪áâ: |
* bl = 0 - ecx ᮤ¥à¦¨â ç¨á«® |
* bl = 1 - ecx ᮤ¥à¦¨â 㪠§ ⥫ì dword-ç¨á«® |
* bh = 0 - ®â®¡à ¦ âì ¢ ¤¥áïâ¨ç®© á¨á⥬¥ áç¨á«¥¨ï |
* bh = 1 - ®â®¡à ¦ âì ¢ è¥áâ ¤æ â¥à¨ç®© á¨á⥬¥ |
* bh = 2 - ®â®¡à ¦ âì ¢ ¤¢®¨ç®© á¨á⥬¥ |
* ¡¨âë 16-21 = ᪮«ìª® æ¨äà ®â®¡à ¦ âì |
* ¡¨âë 22-31 § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
* ecx = ç¨á«® (¯à¨ bl=0) ¨«¨ 㪠§ ⥫ì (¯à¨ bl=1) |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* esi = 0xN0RRGGBB, RRGGBB=梥â, N=èà¨äâ (0/1) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ª § ï ¤«¨ ¥ ¤®«¦ ¯à¥¢®á室¨âì 60. |
* 뢮¤¨âáï ஢® 㪠§ ®¥ ª®«¨ç¥á⢮ æ¨äà. ᫨ ç¨á«® ¬ «® ¨ |
¬®¦¥â ¡ëâì § ¯¨á ® ¬¥ì訬 ª®«¨ç¥á⢮¬ æ¨äà, ®® ¤®¯®«ï¥âáï |
¢¥¤ã騬¨ ã«ï¬¨; ¥á«¨ ç¨á«® ¢¥«¨ª® ¨ ¥ ¬®¦¥â ¡ëâì § ¯¨á ® |
â ª¨¬ ª®«¨ç¥á⢮¬ æ¨äà, "«¨è¨¥" ¢¥¤ã騥 æ¨äàë ®¡à¥§ îâáï. |
* à ¬¥âàë èà¨ä⮢ 㪠§ ë ¢ ®¯¨á ¨¨ äãªæ¨¨ 4 (¢ë¢®¤ ⥪áâ ). |
====================================================================== |
======= ãªæ¨ï 48, ¯®¤äãªæ¨ï 0 - ¯à¨¬¥¨âì áâனª¨ íªà . ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - § १¥à¢¨à®¢ ® |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¯¥à¥à¨á®¢ë¢ ¥â íªà ¯®á«¥ ¨§¬¥¥¨ï ¯ à ¬¥â஢ |
¯®¤äãªæ¨ï¬¨ 1 ¨ 2. |
* 맮¢ äãªæ¨¨ ¡¥§ ¯à¥¤è¥áâ¢ãîé¨å ¢ë§®¢®¢ 㪠§ ëå ¯®¤äãªæ¨© |
¨£®à¨àã¥âáï. |
* 맮¢ äãªæ¨¨ á ¥ã«¥¢ë¬ ecx ¨£®à¨àã¥âáï. |
====================================================================== |
========= ãªæ¨ï 48, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì áâ¨«ì ª®¯®ª. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ ª®¯®ª: |
* 0 = ¯«®áª¨¥ |
* 1 = ®¡ê¸¬ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®á«¥ ¢ë§®¢ ®¯¨áë¢ ¥¬®© äãªæ¨¨ á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà |
¯®¤äãªæ¨¥© 0. |
* ¨¯ ª®¯®ª ¢«¨ï¥â ⮫쪮 ¨å ¯à®à¨á®¢ªã äãªæ¨¥© 8. |
====================================================================== |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì áâ ¤ àâë¥ æ¢¥â ®ª®. === |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì â ¡«¨æã 梥⮢ |
* edx = à §¬¥à â ¡«¨æë 梥⮢ |
(¤®«¦¥ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨) |
®à¬ â â ¡«¨æë 梥⮢ 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 3. |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®á«¥ ¢ë§®¢ ®¯¨áë¢ ¥¬®© äãªæ¨¨ á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà |
¯®¤äãªæ¨¥© 0. |
* ¡«¨æ áâ ¤ àâëå 梥⮢ ¢«¨ï¥â ⮫쪮 ¯à¨«®¦¥¨ï, |
ª®â®àë¥ íâã â ¡«¨æã ï¢ë¬ ®¡à §®¬ ¯®«ãç îâ (¯®¤äãªæ¨¥© 3) ¨ |
¨á¯®«ì§ãîâ (㪠§ë¢ ï 梥⠨§ ¥¸ ¯à¨ ¢ë§®¢ å äãªæ¨© à¨á®¢ ¨ï). |
* ¡«¨æ áâ ¤ àâëå 梥⮢ ¢å®¤¨â ¢ ᪨ ¨ ãáâ ¢«¨¢ ¥âáï § ®¢® |
¯à¨ ãáâ ®¢ª¥ ᪨ (¯®¤äãªæ¨¨ 8). |
* ¡«¨æã 梥⮢ ¬®¦® ¯à®á¬ âਢ âì/¨§¬¥ïâì ¨â¥à ªâ¨¢® á ¯®¬®éìî |
¯à¨«®¦¥¨ï desktop. |
====================================================================== |
===== ãªæ¨ï 48, ¯®¤äãªæ¨ï 3 - ¯®«ãç¨âì áâ ¤ àâë¥ æ¢¥â ®ª®. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à®¬ edx ¡ ©â, |
ªã¤ ¡ã¤¥â § ¯¨á â ¡«¨æ |
* edx = à §¬¥à â ¡«¨æë 梥⮢ |
(¤®«¦¥ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â â ¡«¨æë 梥⮢: ª ¦¤ë© í«¥¬¥â - |
dword-§ 票¥ 梥â 0x00RRGGBB |
* +0: dword: frames - 梥â à ¬ª¨ |
* +4: dword: grab - 梥⠧ £®«®¢ª |
* +8: dword: grab_button - 梥⠪®¯ª¨ ¯®«®á¥ § £®«®¢ª |
* +12 = +0xC: dword: grab_button_text - 梥â ⥪áâ ª®¯ª¥ |
¯®«®á¥ § £®«®¢ª |
* +16 = +0x10: dword: grab_text - 梥â ⥪áâ § £®«®¢ª¥ |
* +20 = +0x14: dword: work - 梥â à ¡®ç¥© ®¡« á⨠|
* +24 = +0x18: dword: work_button - 梥⠪®¯ª¨ ¢ à ¡®ç¥© ®¡« á⨠|
* +28 = +0x1C: dword: work_button_text - 梥â ⥪áâ ª®¯ª¥ |
¢ à ¡®ç¥© ®¡« á⨠|
* +32 = +0x20: dword: work_text - 梥â ⥪áâ ¢ à ¡®ç¥© ®¡« á⨠|
* +36 = +0x24: dword: work_graph - 梥⠣à 䨪¨ ¢ à ¡®ç¥© ®¡« á⨠|
¬¥ç ¨ï: |
* âàãªâãà â ¡«¨æë 梥⮢ ®¯¨á ¢ áâ ¤ à⮬ ¢ª«îç ¥¬®¬ ä ©«¥ |
macros.inc ¯®¤ §¢ ¨¥¬ system_colors; ¯à¨¬¥à, ¬®¦® ¯¨á âì: |
sc system_colors ; ®¡ê¥¨¥ ¯¥à¥¬¥®© |
... ; £¤¥-â® ¤® ¢ë§¢ âì |
; ®¯¨áë¢ ¥¬ãî äãªæ¨î á ecx=sc |
mov ecx, [sc.work_button_text] ; ç¨â ¥¬ 梥â ⥪áâ |
; ª®¯ª¥ ¢ à ¡®ç¥© ®¡« á⨠|
* ᯮ«ì§®¢ ¨¥/¥¨á¯®«ì§®¢ ¨¥ íâ¨å 梥⮢ - ¤¥«® ¨áª«îç¨â¥«ì® |
á ¬®© ¯à®£à ¬¬ë. «ï ¨á¯®«ì§®¢ ¨ï 㦮 ¯à®áâ® ¯à¨ ¢ë§®¢¥ äãªæ¨© |
à¨á®¢ ¨ï 㪠§ë¢ âì 梥â, ¢§ïâë© ¨§ í⮩ â ¡«¨æë. |
* ਠ¨§¬¥¥¨¨ â ¡«¨æë áâ ¤ àâëå 梥⮢ (¯®¤äãªæ¨¥© 2 á |
¯®á«¥¤ãî騬 ¯à¨¬¥¥¨¥¬ ¨§¬¥¥¨© ¯®¤äãªæ¨¥© 0 ¨«¨ |
¯à¨ ãáâ ®¢ª¥ ᪨ ¯®¤äãªæ¨¥© 8) ¢á¥¬ ®ª ¬ ¯®áë« ¥âáï á®®¡é¥¨¥ |
® ¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ á ª®¤®¬ 1). |
* â ¤ àâë¥ æ¢¥â ¬®¦® ¯à®á¬ âਢ âì/¨§¬¥ïâì ¨â¥à ªâ¨¢® |
á ¯®¬®éìî ¯à¨«®¦¥¨ï desktop. |
====================================================================== |
========== ãªæ¨ï 48, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ¢ëá®âã ᪨ . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¢ëá®â ᪨ |
¬¥ç ¨ï: |
* ëá®â®© ᪨ ¯® ®¯à¥¤¥«¥¨î áç¨â ¥âáï ¢ëá®â § £®«®¢ª ®ª®, |
¨á¯®«ì§ãîé¨å ᪨. |
* ¬®âਠ⠪¦¥ ®¡éãî áâàãªâãàã ®ª ¢ ®¯¨á ¨¨ äãªæ¨¨ 0. |
====================================================================== |
===== ãªæ¨ï 48, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì à ¡®çãî ®¡« áâì íªà . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
¬¥ç ¨ï: |
* ¡®ç ï ®¡« áâì íªà ®¯à¥¤¥«ï¥â ¯®«®¦¥¨¥ ¨ ª®®à¤¨ âë |
¬ ªá¨¬¨§¨à®¢ ®£® ®ª . |
* ¡®ç ï ®¡« áâì íªà ¯à¨ ®à¬ «ì®© à ¡®â¥ ¥áâì ¢¥áì íªà |
§ ¢ëç¥â®¬ ¯ ¥«¨ (@panel). |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï |
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1. |
* ¬®âਠ⠪¦¥ äãªæ¨î 14, |
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà . |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ à ¡®ç¥© ®¡« á⨠- ¯®¤äãªæ¨ï 6. |
====================================================================== |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 6 - ãáâ ®¢¨âì à ¡®çãî ®¡« áâì íªà . === |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = [left]*65536 + [right] |
* edx = [top]*65536 + [bottom] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¡®ç ï ®¡« áâì íªà ®¯à¥¤¥«ï¥â ¯®«®¦¥¨¥ ¨ ª®®à¤¨ âë |
¬ ªá¨¬¨§¨à®¢ ®£® ®ª . |
* â äãªæ¨ï ¨á¯®«ì§ã¥âáï ⮫쪮 ¯à¨«®¦¥¨¥¬ @panel, |
ãáâ ¢«¨¢ î騬 à ¡®ç¥© ®¡« áâìî ¢¥áì íªà § ¢ëç¥â®¬ ¯ ¥«¨. |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï |
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1. |
* ᫨ left>=right, â® x-ª®®à¤¨ âë à ¡®ç¥© ®¡« á⨠¥ ¨§¬¥ïîâáï. |
᫨ left<0, â® left ¥ ãáâ ¢«¨¢ ¥âáï. ᫨ right ¡®«ìè¥ |
¨«¨ à ¢® è¨à¨ë íªà , â® right ¥ ãáâ ¢«¨¢ ¥âáï. |
«®£¨ç® ¯® ®á¨ y. |
* ¬®âਠ⠪¦¥ äãªæ¨î 14, |
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï à ¡®ç¥© ®¡« á⨠- |
¯®¤äãªæ¨ï 5. |
* â äãªæ¨ï ¢â®¬ â¨ç¥áª¨ ¯¥à¥à¨á®¢ë¢ ¥â íªà , ¯® 室㠤¥« |
®¡®¢«ï¥â ª®®à¤¨ âë ¨ à §¬¥àë ¬ ªá¨¬¨§¨à®¢ ëå ®ª®. |
ᥠ®ª ¨§¢¥é îâáï ® ¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1). |
====================================================================== |
====================== ãªæ¨ï 48, ¯®¤äãªæ¨ï 7 ====================== |
============ ®«ãç¨âì ®¡« áâì ᪨ ¤«ï ⥪áâ § £®«®¢ª . ============ |
====================================================================== |
®§¢à é ¥â ®¡« áâì § £®«®¢ª ®ª ᮠ᪨®¬, ¯à¥¤ § ç¥ãî |
¤«ï ¢ë¢®¤ ⥪áâ § £®«®¢ª . |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
¬¥ç ¨ï: |
* ᯮ«ì§®¢ ¨¥/¥¨á¯®«ì§®¢ ¨¥ í⮩ äãªæ¨¨ - |
«¨ç®¥ ¤¥«® ¯à¨«®¦¥¨ï. |
* ¥ª®¬¥¤ã¥âáï ãç¨âë¢ âì § 票ï, ¢®§¢à é ¥¬ë¥ í⮩ äãªæ¨¥©, |
¯à¨ ¢ë¡®à¥ ¬¥áâ ¤«ï à¨á®¢ ¨ï ⥪áâ § £®«®¢ª (äãªæ¨¥© 4) ¨«¨ |
ª ª®£®-¨¡ã¤ì § ¬¥¨â¥«ï ⥪áâ § £®«®¢ª |
(¯® ãᬮâà¥¨î ¯à¨«®¦¥¨ï). |
====================================================================== |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 8 - ãáâ ®¢¨âì ¨á¯®«ì§ã¥¬ë© ᪨ ®ª®. === |
====================================================================== |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡«®ª ¤«ï äãªæ¨¨ 58, ¢ ª®â®à®¬ ãáâ ®¢«¥® |
¯®«¥ ¯à®¬¥¦ãâ®ç®£® ¡ãä¥à ¨ 㪠§ ® ¨¬ï ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* ¨ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë; ¥á«¨ ä ©« ¥ § ¤ ¸â ᪨, |
â® ¢®§¢à é ¥âáï ®è¨¡ª 3 (¥¨§¢¥áâ ï ä ©«®¢ ï á¨á⥬ ). |
¬¥ç ¨ï: |
* ਠãᯥ让 § £à㧪¥ ᪨ ¢á¥ ®ª ¨§¢¥é îâáï ® ¥®¡å®¤¨¬®á⨠|
¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1). |
* ਠ§ £à㧪¥ á¨á⥬ áç¨âë¢ ¥â ᪨ ¨§ ä ©« default.skn |
à ¬¤¨áª¥. |
* ®«ì§®¢ â¥«ì ¬®¦¥â ¨§¬¥ïâì ᪨ áâ â¨ç¥áª¨, ᮧ¤ ¢ ᢮© |
default.skn, ¨«¨ ¤¨ ¬¨ç¥áª¨ á ¯®¬®éìî ¯à¨«®¦¥¨ï desktop. |
====================================================================== |
============ ãªæ¨ï 49 - Advanced Power Management (APM). =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 49 - ®¬¥à äãªæ¨¨ |
* dx = ®¬¥à äãªæ¨¨ APM ( «®£ ax ¢ ᯥæ¨ä¨ª 樨) |
* bx, cx = ¯ à ¬¥âàë äãªæ¨¨ APM |
®§¢à é ¥¬®¥ § 票¥: |
* 16-¡¨âë¥ à¥£¨áâàë ax, bx, cx, dx, si, di ¨ ä« £ CF |
ãáâ ®¢«¥ë ¢ ᮮ⢥âá⢨¨ ᮠᯥæ¨ä¨ª 樥© APM |
* áâ à訥 ¯®«®¢¨ë 32-¡¨âëå ॣ¨áâ஢ eax, ebx, ecx, |
edx, esi, edi à §àãè îâáï |
¬¥ç ¨ï: |
* ¯¥æ¨ä¨ª æ¨ï APM 1.2 ®¯¨áë¢ ¥âáï ¢ ¤®ªã¬¥â¥ |
"Advanced Power Management (APM) BIOS Specification" |
(Revision 1.2), ¤®áâ㯮¬ |
http://www.microsoft.com/whdc/archive/amp_12.mspx; |
ªà®¬¥ ⮣®, ® ¢ª«îç¥ ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). |
====================================================================== |
================= ãªæ¨ï 50 - ãáâ ®¢ª ä®à¬ë ®ª . ================= |
====================================================================== |
¡ëçë¥ ®ª ¯à¥¤áâ ¢«ïîâ ᮡ®© ¯àאַ㣮«ì¨ª¨. ¯®¬®éìî í⮩ äãªæ¨¨ |
®ªã ¬®¦® ¯à¨¤ âì ¯à®¨§¢®«ìãî ä®à¬ã. ®à¬ § ¤ ¸âáï ¡®à®¬ â®ç¥ª |
¢ãâਠ®¡à ¬«ïî饣® ¯àאַ㣮«ì¨ª , ¯à¨ ¤«¥¦ é¨å ®ªã. ®«®¦¥¨¥ ¨ |
à §¬¥àë ®¡à ¬«ïî饣® ¯àאַ㣮«ì¨ª § ¤ îâáï äãªæ¨¥© 0 ¨ ¨§¬¥ïîâáï |
äãªæ¨¥© 67. |
--------------- áâ ®¢ª ¤ ëå á ¨ä®à¬ 樥© ® ä®à¬¥ --------------- |
à ¬¥âàë: |
* eax = 50 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä®à¬ë (¬ áᨢ ¡ ©â 0/1) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------------ áâ ®¢ª ¬ áèâ ¡ ¤ ëå ä®à¬ë ------------------- |
à ¬¥âàë: |
* eax = 50 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx § ¤ ¸â ¬ áèâ ¡: ª ¦¤ë© ¡ ©â ¤ ëå ®¯à¥¤¥«ï¥â |
(2^scale)*(2^scale) ¯¨ªá¥«¥© |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* áèâ ¡ ¯® 㬮«ç ¨î à ¢¥ 0 (¬ áèâ ¡¨àãî騩 ¬®¦¨â¥«ì 1). ᫨ ¢ |
¤ ëå ä®à¬ë ®¤¨ ¡ ©â ᮮ⢥âáâ¢ã¥â ®¤®¬ã ¯¨ªá¥«î, â® ¬ áèâ ¡ |
¬®¦® ¥ ãáâ ¢«¨¢ âì. |
* ¡®§ 稬 xsize = è¨à¨ ®ª (¢ ¯¨ªá¥«ïå), ysize = ¢ëá®â ; |
®¡à â¨â¥ ¢¨¬ ¨¥, çâ® ®¨ ¥¤¨¨æã ¡®«ìè¥, 祬 ãáâ ¢«¨¢ ¥¬ë¥ |
äãªæ¨ï¬¨ 0, 67. |
* ® ®¯à¥¤¥«¥¨î ¬ áèâ ¡ xsize ¨ ysize ¤®«¦ë ¤¥«¨âìáï 2^scale. |
* ©â ¤ ëå ¯® ᬥ饨î a ¤®«¦¥ ¡ëâì 0/1 ¨ |
®¯à¥¤¥«ï¥â ¯à¨ ¤«¥¦®áâì ®ªã ª¢ ¤à â á® áâ®à®®© 2^scale |
(¯à¨ scale=0 ¯®«ãç ¥¬ ¯¨ªá¥«ì) ¨ ª®®à¤¨ â ¬¨ «¥¢®£® ¢¥à奣® 㣫 |
(a mod (xsize shr scale), a div (xsize shr scale)) |
* §¬¥à ¤ ëå: (xsize shr scale)*(ysize shr scale). |
* ë¥ ¤®«¦ë ¯à¨áãâá⢮¢ âì ¢ ¯ ¬ï⨠¨ ¥ ¬¥ïâìáï |
¯®á«¥ ãáâ ®¢ª¨ ä®à¬ë. |
* ¨á⥬ ¯à®á¬ âਢ ¥â ¤ ë¥ ® ä®à¬¥ ¯à¨ ª ¦¤®© ¯¥à¥à¨á®¢ª¥ ®ª |
äãªæ¨¥© 0. |
* 맮¢ ¯®¤äãªæ¨¨ 0 á ã«¥¢ë¬ 㪠§ ⥫¥¬ ¯à¨¢®¤¨â ª ¢®§¢à âã |
ª ¯àאַ㣮«ì®© ä®à¬¥. |
====================================================================== |
===================== ãªæ¨ï 51 - ᮧ¤ âì ¯®â®ª. ==================== |
====================================================================== |
à ¬¥âàë: |
* eax = 51 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = ¤à¥á â®çª¨ ¢å®¤ ¯®â®ª ( ç «ìë© eip) |
* edx = 㪠§ ⥫ì áâíª ¯®â®ª ( ç «ìë© esp) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (¢ á¨á⥬¥ ᫨誮¬ ¬®£® ¯®â®ª®¢) |
* ¨ ç¥ eax = TID - ¨¤¥â¨ä¨ª â®à ¯®â®ª |
====================================================================== |
= ãªæ¨ï 52, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ª®ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤¢®©®¥ á«®¢® ª®ä¨£ãà 樨 |
¬¥ç ¨ï: |
* «®¢® ª®ä¨£ãà 樨 ¬®¦® ãáâ ®¢¨âì ¯®¤äãªæ¨¥© 2. |
* ¤à® ¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥ãî. |
¥®áâì í⮩ ¯¥à¥¬¥®© ¨ à ¡®â îé¨å á ¥© ¯®¤äãªæ¨© 0 ¨ 2 |
¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©. |
====================================================================== |
======= ãªæ¨ï 52, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì «®ª «ìë© IP- ¤à¥á. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = IP- ¤à¥á (4 ¡ ©â ) |
¬¥ç ¨ï: |
* ®ª «ìë© IP- ¤à¥á ãáâ ¢«¨¢ ¥âáï ¯®¤äãªæ¨¥© 3. |
====================================================================== |
ãªæ¨ï 52, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì ª®ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤¢®©®¥ á«®¢® ª®ä¨£ãà 樨; ¥á«¨ ¬« ¤è¨¥ 7 ¡¨â ®¡à §ãîâ |
ç¨á«® 3, íâ® ¢®á¯à¨¨¬ ¥âáï ª ª § ¯à®á [¯¥à¥-]¨¨æ¨ «¨§ æ¨î |
Ethernet-ª àâë, ¢ ¯à®â¨¢®¬ á«ãç ¥ Ethernet ¢ëª«îç ¥âáï |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¥ § ¯à®è¥ Ethernet-¨â¥à䥩á, â® ¢®§¢à é ¥âáï eax=2, |
® íâ® ¬®¦¥â ¨§¬¥¨âìáï ¢ ¡ã¤ãé¨å ¢¥àá¨ïå ï¤à |
* ¥á«¨ § ¯à®è¥ Ethernet-¨â¥à䥩á, â® eax=0 ®§ ç ¥â ®è¨¡ªã |
(®âáãâá⢨¥ Ethernet-ª àâë), ¥ã«¥¢®¥ § 票¥ - ãᯥå |
¬¥ç ¨ï: |
* «®¢® ª®ä¨£ãà 樨 ¬®¦® ¯à®ç¨â âì ¯®¤äãªæ¨¥© 0. |
* ¤à® ¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥ãî. |
¥®áâì í⮩ ¯¥à¥¬¥®©, ¯®¤äãªæ¨¨ 0 ¨ ç á⨠¯®¤äãªæ¨¨ 2, |
ãáâ ¢«¨¢ î饩 íâã ¯¥à¥¬¥ãî, ¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©. |
====================================================================== |
====== ãªæ¨ï 52, ¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì «®ª «ìë© IP- ¤à¥á. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = IP- ¤à¥á (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=3, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ¢¥àá¨ïå |
¬¥ç ¨ï: |
* ®ª «ìë© IP- ¤à¥á ¬®¦® ¯®«ãç¨âì ¯®¤äãªæ¨¥© 1. |
====================================================================== |
= ãªæ¨ï 52, ¯®¤äãªæ¨ï 6 - ¤®¡ ¢¨âì ¤ ë¥ ¢ á⥪ ¢å®¤®© ®ç¥à¥¤¨. = |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* edx = à §¬¥à ¤ ëå |
* esi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª |
* eax = 0 - ãá¯¥è® |
¬¥ç ¨ï: |
* â äãªæ¨ï ¯à¥¤ § ç¥ â®«ìª® ¤«ï ¬¥¤«¥ëå á¥â¥¢ëå ¤à ©¢¥à®¢ |
(PPP, SLIP). |
* §¬¥à ¤ ëå ¥ ¤®«¦¥ ¯à¥¢®á室¨âì 1500 ¡ ©â, |
å®âï ¯à®¢¥à®ª ª®à४â®á⨠¥ ¤¥« ¥âáï. |
====================================================================== |
====================== ãªæ¨ï 52, ¯®¤äãªæ¨ï 8 ====================== |
============= à®ç¨â âì ¤ ë¥ ¨§ á¥â¥¢®© ®ç¥à¥¤¨ ¢ë¢®¤ . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* esi = 㪠§ â¥«ì ¡ãä¥à à §¬¥à®¬ 1500 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (¢ ⥪ã饩 ॠ«¨§ 樨 |
«¨¡® 0 = ¥â ¤ ëå, «¨¡® 1500) |
* ¤ ë¥ áª®¯¨à®¢ ë ¢ ¡ãä¥à |
¬¥ç ¨ï: |
* â äãªæ¨ï ¯à¥¤ § ç¥ â®«ìª® ¤«ï ¬¥¤«¥ëå á¥â¥¢ëå ¤à ©¢¥à®¢ |
(PPP, SLIP). |
====================================================================== |
=========== ãªæ¨ï 52, ¯®¤äãªæ¨ï 9 - ¯®«ãç¨âì gateway IP. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = gateway IP (4 ¡ ©â ) |
====================================================================== |
========= ãªæ¨ï 52, ¯®¤äãªæ¨ï 10 - ¯®«ãç¨âì ¬ áªã ¯®¤á¥â¨. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¬ ᪠¯®¤á¥â¨ |
====================================================================== |
========= ãªæ¨ï 52, ¯®¤äãªæ¨ï 11 - ãáâ ®¢¨âì gateway IP. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = gateway IP (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=11, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ॠ«¨§ æ¨ïå |
====================================================================== |
======== ãªæ¨ï 52, ¯®¤äãªæ¨ï 12 - ãáâ ®¢¨âì ¬ áªã ¯®¤á¥â¨. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¬ ᪠¯®¤á¥â¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=12, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ¢¥àá¨ïå |
====================================================================== |
============ ãªæ¨ï 52, ¯®¤äãªæ¨ï 13 - ¯®«ãç¨âì DNS IP. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = DNS IP (4 ¡ ©â ) |
====================================================================== |
=========== ãªæ¨ï 52, ¯®¤äãªæ¨ï 14 - ãáâ ®¢¨âì DNS IP. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = DNS IP (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=14, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ á«¥¤ãîé¨å ¢¥àá¨ïå |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 0 - ®âªàëâì UDP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = «®ª «ìë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* edx = 㤠«¸ë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* esi = 㤠«¸ë© IP |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï |
* eax = åí¤« ᮪¥â (¥ª®â®à®¥ ç¨á«®, ®¤®§ ç® ¨¤¥â¨ä¨æ¨àãî饥 |
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥè®; |
ebx à §àãè ¥âáï |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 1 - § ªàëâì UDP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¥¢¥àë© åí¤« |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ § ªàë¢ ¥â ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª |
¯à¨ ¥£® § ¢¥à襨¨. ç áâ®áâ¨, ¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª |
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª à¥áãàᮢ. |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ ¤¥« ¥â ¯à®¢¥à®ª ª®à४â®áâì |
(¥¤¨á⢥®¥, çâ® ¢®§¢à é ¥âáï ®è¨¡ª , - ¯®¯ë⪠§ ªàëâì |
¥®âªàëâë© á®ª¥â á ª®à४âë¬ åí¤«®¬). |
====================================================================== |
============== ãªæ¨ï 53, ¯®¤äãªæ¨ï 2 - ®¯à®á ᮪¥â . ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯®«ãç¥ëå ¡ ©â |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ஢¥àª¨ ª®à४â®á⨠¥ ¤¥« ¥âáï. |
====================================================================== |
======== ãªæ¨ï 53, ¯®¤äãªæ¨ï 3 - ¯à®ç¨â âì ¡ ©â ¨§ ᮪¥â . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¥â ¯à¨ïâëå ¤ ëå: eax=0, bl=0, |
¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï |
* ¥á«¨ ¡ë«¨ ¯à¨ïâë¥ ¤ ë¥: eax=ç¨á«® ®áâ ¢è¨åáï ¡ ©â |
(¢®§¬®¦®, 0), bl=¯à®ç¨â ë© ¡ ©â, ¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï |
¬¥ç ¨ï: |
* ஢¥àª¨ ª®à४â®á⨠¥ ¯à®¨§¢®¤¨âáï. |
====================================================================== |
========== ãªæ¨ï 53, ¯®¤äãªæ¨ï 4 - § ¯¨á âì ¢ UDP-᮪¥â. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0xffffffff - ¥¢¥àë© åí¤« |
* eax = 0xffff - ¥¤®áâ â®ç® ¯ ¬ï⨠|
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ஢¥àª ¯à ¢¨«ì®áâì åí¤« ¬¨¨¬ «ì - ¨áª«îç îâáï ⮫쪮 |
¥ ®ç¥ì ¥¯à ¢¨«ìë¥ ¥®âªàëâë¥ åí¤«ë. |
* ¨á«® ¡ ©â ¤«ï § ¯¨á¨ ¥ ¬®¦¥â ¯à¥¢ëè âì 1500-28, å®âï |
ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ¥ ¤¥« ¥âáï. |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 5 - ®âªàëâì TCP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = «®ª «ìë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* edx = 㤠«¸ë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* esi = 㤠«¸ë© IP |
* edi = ०¨¬ ®âªàëâ¨ï: SOCKET_PASSIVE=0 ¨«¨ SOCKET_ACTIVE=1 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï |
* eax = åí¤« ᮪¥â (¥ª®â®à®¥ ç¨á«®, ®¤®§ ç® ¨¤¥â¨ä¨æ¨àãî饥 |
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥè®; |
ebx à §àãè ¥âáï |
====================================================================== |
====== ãªæ¨ï 53, ¯®¤äãªæ¨ï 6 - ¯®«ãç¨âì á®áâ®ï¨¥ TCP-᮪¥â . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = áâ âãá ᮪¥â : ®¤® ¨§ |
* TCB_LISTEN = 1 |
* TCB_SYN_SENT = 2 |
* TCB_SYN_RECEIVED = 3 |
* TCB_ESTABLISHED = 4 |
* TCB_FIN_WAIT_1 = 5 |
* TCB_FIN_WAIT_2 = 6 |
* TCB_CLOSE_WAIT = 7 |
* TCB_CLOSING = 8 |
* TCB_LAST_ASK = 9 |
* TCB_TIME_WAIT = 10 |
* TCB_CLOSED = 11 |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ஢¥à®ª ª®à४â®á⨠¥ ¯à®¨§¢®¤¨âáï. |
====================================================================== |
========== ãªæ¨ï 53, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ TCP-᮪¥â. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0xffffffff - ®è¨¡ª |
* eax = 0xffff - ¥¤®áâ â®ç® ¯ ¬ï⨠|
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ஢¥àª ¯à ¢¨«ì®áâì åí¤« ¬¨¨¬ «ì - ¨áª«îç îâáï ⮫쪮 |
¥ ®ç¥ì ¥¯à ¢¨«ìë¥ ¥®âªàëâë¥ åí¤«ë. |
* ¨á«® ¡ ©â ¤«ï § ¯¨á¨ ¥ ¬®¦¥â ¯à¥¢ëè âì 1500-40, |
å®âï ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ¥ ¤¥« ¥âáï. |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 8 - § ªàëâì TCP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¥¢¥àë© åí¤« |
* eax = 0xffff - ¥¤®áâ â®ç® ¯ ¬ï⨠¤«ï ¯ ª¥â § ªàëâ¨ï ᮪¥â |
* eax = 0 - ãá¯¥è® |
* ¢® ¬®£¨å á«ãç ïå eax à §àãè ¥âáï (¢®§¢à é ¥âáï १ã«ìâ â äãªæ¨¨ |
queue) - ¢¨¤¨¬®, íâ® ¡ £, ª®â®àë© ¡ã¤¥â ¨á¯à ¢«¥ |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ § ªàë¢ ¥â ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª |
¯à¨ ¥£® § ¢¥à襨¨. ç áâ®áâ¨, ¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª |
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª à¥áãàᮢ. |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ ¤¥« ¥â ¯à®¢¥à®ª ª®à४â®áâì |
(¥¤¨á⢥®¥, çâ® ¢®§¢à é ¥âáï ®è¨¡ª , - ¯®¯ë⪠§ ªàëâì |
¥®âªàëâë© á®ª¥â á ª®à४âë¬ åí¤«®¬). |
====================================================================== |
== ãªæ¨ï 53, ¯®¤äãªæ¨ï 9 - ¯à®¢¥à¨âì, ᢮¡®¤¥ «¨ «®ª «ìë© ¯®àâ. = |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à «®ª «ì®£® ¯®àâ (¨á¯®«ì§ãîâáï ⮫쪮 ¬« ¤è¨¥ 16 ¡¨â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¯®à⠨ᯮ«ì§ã¥âáï |
* eax = 1 - ¯®àâ ᢮¡®¤¥ |
* ebx à §àãè ¥âáï |
====================================================================== |
ãªæ¨ï 53, ¯®¤äãªæ¨ï 255 - ®â« ¤®ç ï ¨ä®à¬ æ¨ï á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 255 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ § ¯à 訢 ¥¬®© ¨ä®à¬ 樨 (ᬮâਠ¨¦¥) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = § ¯à®è¥ ï ¨ä®à¬ æ¨ï |
* ebx à §àãè ¥âáï |
®§¬®¦ë¥ § 票ï ecx: |
* 100: ¤«¨ ®ç¥à¥¤¨ 0 (empty queue) |
* 101: ¤«¨ ®ç¥à¥¤¨ 1 (ip-out queue) |
* 102: ¤«¨ ®ç¥à¥¤¨ 2 (ip-in queue) |
* 103: ¤«¨ ®ç¥à¥¤¨ 3 (net1out queue) |
* 200: ç¨á«® í«¥¬¥â®¢ ¢ â ¡«¨æ¥ ARP |
* 201: à §¬¥à â ¡«¨æë ARP (¢ í«¥¬¥â å) (20 ¢ ⥪ã饩 ¢¥àᨨ) |
* 202: ¯à®ç¨â âì í«¥¬¥â edx â ¡«¨æë ARP ¢® ¢à¥¬¥ë© ¡ãä¥à, ®âªã¤ |
¡¥àãâ ¨ä®à¬ æ¨î 5 ¯®á«¥¤ãîé¨å ⨯®¢; |
¢ í⮬ á«ãç ¥ eax ¥®¯à¥¤¥«¸ |
* 203: IP- ¤à¥á, § ¯®¬¥ë© ⨯®¬ 202 |
* 204: áâ à襥 dword MAC- ¤à¥á , § ¯®¬¥®£® ⨯®¬ 202 |
* 205: ¬« ¤è¥¥ word MAC- ¤à¥á , § ¯®¬¥®£® ⨯®¬ 202 |
* 206: á«®¢® áâ âãá , § ¯®¬¥®¥ ⨯®¬ 202 |
* 207: á«®¢® ttl, § ¯®¬¥®¥ ⨯®¬ 202 |
* 2: ®¡é¥¥ ç¨á«® ¯®«ãç¥ëå IP-¯ ª¥â®¢ |
* 3: ®¡é¥¥ ç¨á«® ¯¥à¥¤ ëå IP-¯ ª¥â®¢ |
* 4: ®¡é¥¥ ç¨á«® ᤠ¬¯«¥ëå ¯®«ãç¥ëå ¯ ª¥â®¢ |
* 5: ®¡é¥¥ ç¨á«® ¯®«ãç¥ëå ARP-¯ ª¥â®¢ |
* 6: áâ âãá ¤à ©¢¥à ¯ ª¥â®¢, 0=¥ ªâ¨¢¥, |
¥ã«¥¢®¥ § 票¥= ªâ¨¢¥ |
====================================================================== |
======== ãªæ¨ï 55, ¯®¤äãªæ¨ï 0 - § £à㧨âì ¤ ë¥ ¤«ï SB16. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 55 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ (ª®¯¨àã¥âáï 64 ª¨«®¡ ©â , ¨á¯®«ì§ã¥âáï |
á⮫쪮, ᪮«ìª® ãáâ ®¢«¥® ¯®¤äãªæ¨¥© 2) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®à¬ â ¨ à §¬¥à ¤ ëå ãáâ ¢«¨¢ îâáï ¯®¤äãªæ¨¥© 2. |
====================================================================== |
==== ãªæ¨ï 55, ¯®¤äãªæ¨ï 1 - ç âì ¯à®¨£àë¢ âì ¤ ë¥ SB16. === |
====================================================================== |
à ¬¥âàë: |
* eax = 55 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤ ë¥ ¤®«¦ë ¡ëâì § £àã¦¥ë ¯®¤äãªæ¨¥© 0 ¨ |
®¯à¥¤¥«¸ ¨å ä®à¬ â ¯®¤äãªæ¨¥© 2. |
* ãªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥¨¥, ª®£¤ ç «®áì ¯à®¨£àë¢ ¨¥ ¤ ëå; |
¯®á«¥ í⮣® ¯à®¨£àë¢ ¨¥ ¨¤¸â ¥§ ¢¨á¨¬® ®â ¯à¨«®¦¥¨ï (¨ ¢®®¡é¥ |
¥ âॡã¥â § £à㧪¨ ¯à®æ¥áá®à ). |
* ।¢ à¨â¥«ì® ¤®«¦ë ¡ëâì ®¯à¥¤¥«¥ë ¡ §®¢ë© ¯®àâ SB16 |
(¯®¤äãªæ¨¥© 4 äãªæ¨¨ 21) ¨ ª « DMA |
(¯®¤äãªæ¨¥© 10 äãªæ¨¨ 21). |
====================================================================== |
====== ãªæ¨ï 55, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì ä®à¬ â ¤ ëå SB16. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 55 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - ãáâ ®¢¨âì à §à冷áâì |
* edx = 1 - 8¡¨â ¬®® |
* edx = 2 - 8¡¨â áâ¥à¥® |
* ecx = 1 - ãáâ ®¢¨âì à §¬¥à ¤ ëå |
* edx = à §¬¥à ¢ ¡ ©â å |
* ecx = 2 - ãáâ ®¢¨âì ç áâ®â㠯ந£àë¢ ¨ï |
* edx = ç áâ®â |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ਠ§ £à㧪¥ á¨á⥬ë ãáâ ¢«¨¢ îâáï á«¥¤ãî騥 ¯ à ¬¥âàë |
¯® 㬮«ç ¨î: à §à冷áâì - 8 ¡¨â ¬®®, à §¬¥à - 64 ¡, |
ç áâ®â 44100 æ. ¥¬ ¥ ¬¥¥¥ ४®¬¥¤ã¥âáï  ãáâ ¢«¨¢ âì |
¥®¡å®¤¨¬ë¥ § 票ï, ¯®áª®«ìªã ®¨ ¬®£«¨ ¡ëâì ¯¥à¥ãáâ ®¢«¥ë |
ª ª®©-¨¡ã¤ì ¯à®£à ¬¬®©. |
====================================================================== |
====================== ãªæ¨ï 55, ¯®¤äãªæ¨ï 55 ===================== |
========== ç âì ¯à®¨£àë¢ âì ¤ ë¥ ¢áâ஥®¬ ᯨª¥à¥. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 55 - ®¬¥à äãªæ¨¨ |
* ebx = 55 - ®¬¥à ¯®¤äãªæ¨¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 55 - ®è¨¡ª (ᯨª¥à ®âª«îç¸ ¨«¨ § ïâ) |
ë¥ - íâ® ¬ áᨢ í«¥¬¥â®¢ ¯¥à¥¬¥®© ¤«¨ë. |
®à¬ â ª ¦¤®£® í«¥¬¥â ®¯à¥¤¥«ï¥âáï ¯¥à¢ë¬ ¡ ©â®¬: |
* 0 = ª®¥æ ¤ ëå |
* 1..0x80 = § ¤ ¸â ¤«¨â¥«ì®áâì §¢ãç ¨ï ¢ á®âëå ¤®«ïå ᥪã¤ë |
®âë, ®¯à¥¤¥«ï¥¬®© ¥¯®á।áâ¢¥ë¬ § 票¥¬ ç áâ®âë |
* á«¥¤ãî饥 á«®¢® (2 ¡ ©â ) ᮤ¥à¦¨â ¤¥«¨â¥«ì ç áâ®âë; |
ç áâ®â ®¯à¥¤¥«ï¥âáï ª ª 1193180/divider |
* 0x81 = invalid |
* 0x82..0xFF = ®â , ®¯à¥¤¥«ï¥¬ ï ®ªâ ¢®© ¨ ®¬¥à®¬: |
* ¤«¨â¥«ì®áâì ¢ á®âëå ¤®«ïå ᥪã¤ë = (¯¥à¢ë© ¡ ©â)-0x81 |
* ¯à¨áãâáâ¢ã¥â ¥é¸ ®¤¨ ¡ ©â; |
* (¢â®à®© ¡ ©â)=0xFF - ¯ 㧠|
* ¨ ç¥ ® ¨¬¥¥â ¢¨¤ a*0x10+b, £¤¥ b=®¬¥à ®âë ¢ ®ªâ ¢¥ ®â 1 |
¤® 12, a=®¬¥à ®ªâ ¢ë (áç¨â ï á 0) |
¬¥ç ¨ï: |
* ¨é ¨¥ ᯨª¥à®¬ ¬®¦¥â ¡ëâì § ¯à¥é¥®/à §à¥è¥® ¯®¤äãªæ¨¥© 8 |
äãªæ¨¨ 18. |
* ãªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥¨¥, á®®¡é¨¢ ªã¤ á«¥¤ã¥â ¨ä®à¬ æ¨î |
® § ¯à®á¥. ¬® ¯à®¨£àë¢ ¨¥ ¨¤¸â ¥§ ¢¨á¨¬® ®â ¯à®£à ¬¬ë. |
* ë¥ ¤®«¦ë á®åà ïâìáï ¢ ¯ ¬ï⨠¯® ªà ©¥© ¬¥à¥ |
¤® ª®æ ¯à®¨£àë¢ ¨ï. |
====================================================================== |
============= ãªæ¨ï 56 - § ¯¨á âì ä ©« ¦¸á⪨© ¤¨áª. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 56 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
* ecx = à §¬¥à ¤ ëå ¤«ï § ¯¨á¨ (¢ ¡ ©â å) |
* edx = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
* esi = 㪠§ â¥«ì ¯ãâì (ASCIIZ-áâபã) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ï äãªæ¨ï ¯à¥¤¯®« £ ¥â, çâ® ¢® ¢à¥¬ï ¥¸ ¢ë§®¢ ®¤¨¬ |
¯à¨«®¦¥¨¥¬ ¨ª ª®¥ ¤à㣮¥ ¯à¨«®¦¥¨¥ ¥ à ¡®â ¥â |
á ¦¸á⪨¬ ¤¨áª®¬. |
* ãâì ª ä ©«ã - ASCIIZ-áâப , ª®â®à ï ¬®¦¥â ¡ëâì ¯ãá⮩ |
(¥á«¨ ä ©« ᮧ¤ ¸âáï ¢ ª®à¥¢®¬ ª â «®£¥) ¨«¨ ¨¬¥âì ä®à¬ â |
/d1/d2/.../dn, £¤¥ ¢á¥ ¨¬¥ ¯ ¯®ª ¤®«¦ë ¨¬¥âì ä®à¬ â 8+3, â.¥. |
8 ᨬ¢®«®¢ ¨¬¥¨ ¨ 3 ᨬ¢®« à áè¨à¥¨ï ¡¥§ à §¤¥«¨â¥«ï, |
¯à¨ ¥®¡å®¤¨¬®á⨠¤®¯®«¥ë¥ ¯à®¡¥« ¬¨; |
¢á¥ ¡ãª¢ë ¤®«¦ë ¡ëâì § £« ¢ë¥. |
* ¬ï ª ä ©«ã â ª¦¥ ¤®«¦® ¨¬¥âì ä®à¬ â 8+3. |
====================================================================== |
============== ãªæ¨ï 58 - à ¡®â á ä ©«®¢®© á¨á⥬®©. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª |
* +8: dword: à §¬¥à |
* +12 = +0xC: dword: 㪠§ â¥«ì ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¯ ¬ïâì ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã « â¨áª¨å ¡ãª¢, |
àãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì § £« ¢ë¬¨. |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD/x = /HARDDISK/x - ãáâ ॢ訩 ¢ ਠ⠤®áâ㯠ª ¦¸á⪮¬ã ¤¨áªã |
(¢ í⮬ á«ãç ¥ ¡ § ®¯à¥¤¥«ï¥âáï ¯®¤äãªæ¨¥© 7 äãªæ¨¨ 21), |
x - ®¬¥à à §¤¥« (áç¨â ï á 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ãáâனá⢠¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
¬¥ç ¨ï: |
* ¯¥à¢ëå ¤¢ãå á«ãç ïå ¤®¯ã᪠¥âáï ¨á¯®«ì§®¢ ¨¥ FIRST ¢¬¥áâ® 1, |
SECOND ¢¬¥áâ® 2, ® ¨á¯®«ì§®¢ âì íâã ¢®§¬®¦®áâì |
¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï. |
* ª« ¤ë¢ ¥âáï ®£à ¨ç¥¨¥ n<=39. |
* ¬¥ ¯ ¯®ª ¨ ä ©« dir1,...,dirn,file ¤®«¦ë ¡ëâì ¢ ä®à¬ ⥠8.3: |
¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ ¥ ¡®«¥¥ 3 ᨬ¢®«®¢. |
¢®áâ®¢ë¥ ¯à®¡¥«ë ¨£®à¨àãîâáï. àã£¨å ¯à®¡¥«®¢ ¡ëâì ¥ ¤®«¦®. |
᫨ ¨¬ï § ¨¬ ¥â ஢® 8 ᨬ¢®«®¢, â®çªã ¬®¦® ®¯ãáâ¨âì |
(å®âï ¯®«ì§®¢ âìáï í⨬ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ |
¡ã¤ã騥 à áè¨à¥¨ï). |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
ਬ¥àë: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/1/menuet/pics/tanzania.bmp',0 |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 1 - ¯¥à¥§ ¯¨áì ä ©« |
* ¯®¤äãªæ¨ï 2 - 㤠«¥¨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 3 - § ¯¨áì ¤ ëå ¢ áãé¥áâ¢ãî騩 ä ©« |
* ¯®¤äãªæ¨ï 4 - ᮧ¤ ¨¥ ¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 5 - ¯¥à¥¨¬¥®¢ ¨¥/¯¥à¥¬¥é¥¨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠|
* ¯®¤äãªæ¨ï 15 - ¯®«ã票¥ ¨ä®à¬ 樨 ® ä ©«®¢®© á¨á⥬¥ |
* ¯®¤äãªæ¨ï 16 - § ¯ã᪠¯à¨«®¦¥¨ï |
====================================================================== |
========== ãªæ¨ï 58, ¯®¤äãªæ¨ï 0 - ¯à®ç¨â âì ä ©«/¯ ¯ªã. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 0 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ç¨á«® ¡«®ª®¢ ¤«ï ç⥨ï |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = à §¬¥à ä ©« (¢ ¡ ©â å) ¨«¨ |
-1=0xffffffff, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â. |
* â äãªæ¨ï ãáâ ५ , ¤«ï ç⥨ï ä ©«®¢ ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 0 |
äãªæ¨¨ 70, ¤«ï çâ¥¨ï ¯ ¯®ª - ¯®¤äãªæ¨î 1 äãªæ¨¨ 70. |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ᮤ¥à¦¨¬®¥ ¯ ¯ª¨. § ä ©«®¢ëå á¨á⥬ |
¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 FAT. ®à¬ â FAT-¯ ¯ª¨ ®¯¨á ¢ «î¡®© |
¤®ªã¬¥â 樨 ¯® FAT. |
* §¬¥à ¯ ¯ª¨ ®¯à¥¤¥«ï¥âáï ¯® à §¬¥àã 楯®çª¨ ª« áâ¥à®¢ ¢ FAT. |
* ᫨ ä ©« ª®ç¨«áï à ìè¥, 祬 ¡ë« ¯à®ç¨â ¯®á«¥¤¨© § ¯à®è¥ë© |
¡«®ª, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥à¸â |
eax=6 (EOF). |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ª®à¥¢ë¥ ¯ ¯ª¨ /rd/1,/fd/x,/hd[n]/x, ® |
¢ ¯¥à¢ëå ¤¢ãå á«ãç ïå ⥪ãé ï ॠ«¨§ æ¨ï ¥ á«¥¤ã¥â |
ãáâ ®¢«¥ë¬ ¯à ¢¨« ¬: |
¤«ï /rd/1: |
* ¥á«¨ 㪠§ ® 0 ¡«®ª®¢ ¤«ï ç⥨ï, áç¨â ¥âáï, |
çâ® § ¯à 訢 ¥âáï 1; |
* ¥á«¨ § ¯à 訢 ¥âáï ¡®«ìè¥ 14 ¡«®ª®¢ ¨«¨ ç «ìë© ¡«®ª |
¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï eax=5 (not found) ¨ ebx=-1; |
* à §¬¥à ª®à¥¢®£® ª â «®£ à ¬¤¨áª = 14 ¡«®ª®¢, |
0x1C00=7168 ¡ ©â; ® ¢®§¢à é ¥âáï ebx=0 |
(§ ¨áª«î票¥¬ á«ãç ï ¯à¥¤ë¤ã饣® ¯ãªâ ); |
* ª ª ¨ áâà ®, ¬®¦® ¯à®ç¨â âì 14-© ¡«®ª (â ¬, ¢®®¡é¥ £®¢®àï, |
¬ãá®à - ¯®¬¨ î, áç¸â ¢¥¤¸âáï á 0); |
* ¥á«¨ ¡ë« § ¯à®è¥ å®âï ¡ë ®¤¨ ¡«®ª á ®¬¥à®¬, ¥ ¬¥ì訬 14, |
â® ¢®§¢à é ¥âáï eax=6(EOF); ¨ ç¥ eax=0. |
«ï /fd/x: |
* ¥á«¨ ç «ìë© ¡«®ª ¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï |
eax=5 (not found) ¨ ebx=0; |
* ªáâ ⨠£®¢®àï, ä®à¬ â FAT12 ¤®¯ã᪠¥â ¤¨áª¥âë á à §¬¥à®¬ |
ª®à¥¢®£® ª â «®£ ¬¥ìè¥ ¨«¨ ¡®«ìè¥ 14 ¡«®ª®¢; |
* ¯à®¢¥àª¨ ¤«¨ë ¥ ¤¥« ¥âáï; |
* ¥á«¨ 㤠«®áì ¯à®ç¨â âì ¤ ë¥ á ¤¨áª¥âë, ¢®§¢à é ¥âáï |
eax=0,ebx=0; ¢ ¯à®â¨¢®¬ á«ãç ¥ eax=10 (access denied), ebx=-1. |
* ãªæ¨ï ®¡à ¡ âë¢ ¥â ç⥨¥ á¯¥æ¨ «ìëå ¯ ¯®ª /,/rd,/fd,/hd[n]; |
® १ã«ìâ â ¥ ᮮ⢥âáâ¢ã¥â ®¦¨¤ ¥¬®¬ã |
(¯® à ¡®â¥ á ®¡ëç묨 ä ©« ¬¨/¯ ¯ª ¬¨), ¥ á«¥¤ã¥â ãáâ ®¢«¥ë¬ |
¯à ¢¨« ¬, ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à ¨ ¯®â®¬ã |
¥ ®¯¨áë¢ ¥âáï. «ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ |
¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 11 äãªæ¨¨ 18 ¨«¨ |
ç¨â ©â¥ ᮮ⢥âáâ¢ãî騥 ¯ ¯ª¨ ¯®¤äãªæ¨¥© 1 äãªæ¨¨ 70. |
====================================================================== |
============ ãªæ¨ï 58, ¯®¤äãªæ¨ï 1 - ¯¥à¥§ ¯¨á âì ä ©«. =========== |
====================================================================== |
᫨ ä ©« ¥ áãé¥áâ¢ã¥â, ® ᮧ¤ ¸âáï. |
᫨ ä ©« áãé¥áâ¢ã¥â, ® ¯¥à¥§ ¯¨áë¢ ¥âáï. |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 1 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï (ãáâ ¢«¨¢ ©â¥ ¢ 0) |
* +8: dword: ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* +12 = +0xC: dword: 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ , ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 2 äãªæ¨¨ 70. |
====================================================================== |
=========== ãªæ¨ï 58, ¯®¤äãªæ¨ï 2 - 㤠«¨âì ä ©«/¯ ¯ªã. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 2 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï |
* +8: dword: ¨£®à¨àã¥âáï |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* à¨ à ¡®â¥ á ¤¨áª¥â®© ¥ á«¥¤ã¥â 㤠«ïâì ¥¯ãáâãî ¯ ¯ªã. |
®¤ à ¡®âë á ¦¸á⪨¬ ¤¨áª®¬ ¥¯ãáâë¥ ¯ ¯ª¨ 㤠«ï¥â ª®à४⮠|
(â.¥. ४ãàᨢ® á® ¢á¥¬¨ ä ©« ¬¨ ¨ ¢«®¦¥ë¬¨ ¯ ¯ª ¬¨). |
¬¤¨áª ¯ ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥â. |
====================================================================== |
==== ãªæ¨ï 58, ¯®¤äãªæ¨ï 3 - § ¯¨áì ¤ ëå ¢ áãé¥áâ¢ãî騩 ä ©«. === |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 3 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ç «ì ï ¯®§¨æ¨ï ¢ ä ©«¥; -1 = ¤®¯¨áë¢ âì ¢ ª®¥æ |
* +8: dword: ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* +12 = +0xC: dword: 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¬¤¨áª ¨ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ îâ íâã äãªæ¨î, ® ⮫쪮 ¤«ï |
¦¸áâª¨å ¤¨áª®¢. |
* ©« ¤®«¦¥ 㦥 áãé¥á⢮¢ âì (¨ ç¥ ¢®§¢à é ¥âáï 5, not found). |
«ï ᮧ¤ ¨ï ä ©«®¢ ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 1. |
* ᫨ ç «ì ï ¯®§¨æ¨ï ¡®«ìè¥ à §¬¥à ä ©« , ¢®§¢à é ¥âáï |
eax=6(EOF). ᫨ ª®¥ç ï ¯®§¨æ¨ï ¡®«ìè¥ à §¬¥à ä ©« , |
ä ©« à áè¨àï¥âáï. |
* ®¤ ®¡à ¡®âª¨ § ¯¨á¨ ¤ ëå ¤«ï ¦¸á⪮£® ¤¨áª ¨â¥à¯à¥â¨àã¥â |
ã«¥¢®¥ § 票¥ ¯®«ï +8 ª ª 㪠§ ¨¥ ãá¥ç¥¨ï ä ©« ¤® à §¬¥à , |
㪠§ ®£® ¢ ¯®«¥ +4. ¤ ª® ª®¤ ®¡à ¡®âª¨ 58-© äãªæ¨¨ ¡«®ª¨àã¥â |
íâã ¢®§¬®¦®áâì ¤«ï ¯à¨«®¦¥¨©, áà §ã ¢®§¢à é ï ã¯à ¢«¥¨¥ |
(á eax=0) ¢ á«ãç ¥ ã«¥¢®£® à §¬¥à . |
====================================================================== |
============== ãªæ¨ï 58, ¯®¤äãªæ¨ï 4 - ᮧ¤ âì ¯ ¯ªã. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 4 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï |
* +8: dword: ¨£®à¨àã¥âáï |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¬¤¨áª ¨ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ îâ íâã äãªæ¨î, |
® ⮫쪮 ¤«ï ¦¸áâª¨å ¤¨áª®¢. |
====================================================================== |
== ãªæ¨ï 58, ¯®¤äãªæ¨ï 5 - ¯¥à¥¨¬¥®¢ âì/¯¥à¥¬¥áâ¨âì ä ©«/¯ ¯ªã. == |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 5 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï |
* +8: dword: ¨£®à¨àã¥âáï |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
* +20+n: (áà §ã ¯®á«¥ § ¢¥àè î饣® ã«¥¢®£® ᨬ¢®« ) ®¢®¥ |
ASCIIZ-¨¬ï, ¤®«¦® ç¨ âìáï á /hd/1, çâ® ¨â¥à¯à¥â¨àã¥âáï ª ª |
¦¸á⪨© ¤¨áª, 㪠§ ë© ¢ ¯¥à¢®¬ ¨¬¥¨ |
(¯¥à¥¬¥é¥¨¥ á ®¤®£® ¤¨áª ¤à㣮© ¥ ¯®¤¤¥à¦¨¢ ¥âáï) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¬¤¨áª ¨ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ îâ íâã äãªæ¨î, |
® ⮫쪮 ¤«ï ¦¸áâª¨å ¤¨áª®¢. |
* ᫨ ®¢®¥ ASCIIZ-¨¬ï á¨«ì® ¥¯à ¢¨«ì®¥, â.¥. ¥ ç¨ ¥âáï á |
/hd/1, /hd/first, /harddisk/1, /harddisk/first ¨«¨ ¯®á«¥ í⮣® |
ç « ¨¤¸â ¯à®¡¥« ¨«¨ ᨬ¢®« á ª®¤®¬ 0, â® äãªæ¨ï ¢®§¢à é ¥â, |
ª ª ¨ áâà ®, ª®¤ ®è¨¡ª¨ 4. â® ¥¤¨á⢥ ï äãªæ¨ï, ª®â®à ï |
¢®®¡é¥ ¢®§¢à é ¥â íâ®â ª®¤. |
====================================================================== |
========= ãªæ¨ï 58, ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 8 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ¨£®à¨àã¥âáï (ãáâ ¢«¨¢ ©â¥ ¢ 1) |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
(512 ¡ ©â) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ãáâனá⢠: ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã, |
®¤® ¨§ /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - ®¬¥à ãáâனá⢠: 1=IDE0, ..., 4=IDE3. |
¬¥áâ® æ¨äà ¤®¯ã᪠¥âáï, å®âï ¨ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠|
¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï, |
¨á¯®«ì§®¢ ¨¥ 'first','second','third','fourth'. |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ 㪠§ ® ¨¬ï ãáâனá⢠/hd/xxx, £¤¥ xxx ¥ 室¨âáï |
¢ ᯨ᪥ ¢ëè¥: |
* eax = ebx = 1 |
* ¥á«¨ 㪠§ ® ¥¯à ¢¨«ì®¥ ¨¬ï ãáâனá⢠|
(§ ¨áª«î票¥¬ ¯à¥¤ë¤ã饣® á«ãç ï): |
* eax = 5 |
* ebx ¥ ¬¥ï¥âáï |
* ¥á«¨ LBA-¤®áâ㯠§ ¯à¥é¸ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21: |
* eax = 2 |
* ebx à §àãè ¥âáï |
* ¤«ï à ¬¤¨áª : ¯®¯ë⪠çâ¥¨ï ¡«®ª § ¯à¥¤¥« ¬¨ à ¬¤¨áª |
(18*2*80 ¡«®ª®¢) ¯à¨¢®¤¨â ª |
* eax = 3 |
* ebx = 0 |
* ¯à¨ ãᯥ讬 ç⥨¨: |
* eax = ebx = 0 |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â; ç¨â ¥âáï ®¤¨ ¡«®ª. |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥, |
®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå. |
* ॡã¥âáï, çâ®¡ë ¡ë« à §à¥è¸ LBA-¤®áâ㯠ª ãáâனá⢠¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21. § âì íâ® ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 26. |
* LBA-ç⥨¥ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
* ãªæ¨ï áç¨âë¢ ¥â ¤ ë¥ ä¨§¨ç¥áª®£® ¦¸á⪮£® ¤¨áª ; |
¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨ ¬ ã¦ë ¤ ë¥ ª®ªà¥â®£® à §¤¥« , |
¯à¨¤¸âáï ®¯à¥¤¥«ïâì ç «ìë© á¥ªâ®à í⮣® à §¤¥« |
(«¨¡® ¯àï¬ãî ç¥à¥§ MBR, «¨¡® ¨§ à áè¨à¥®© áâàãªâãàë, |
¢®§¢à é ¥¬®© ⮩ ¦¥ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 18). |
* ãªæ¨ï ¥ ¯à®¢¥àï¥â ª®¤ ®è¨¡ª¨ ¦¸á⪮£® ¤¨áª , â ª çâ® § ¯à®á |
¥áãé¥áâ¢ãî饣® ᥪâ®à ¢á¸ à ¢® çâ®-â® ¯à®ç¨â ¥â |
(¢¥à®ï⥥ ¢á¥£®, 㫨, ® íâ® ®¯à¥¤¥«ï¥âáï ãáâனá⢮¬) ¨ |
íâ® ¡ã¤¥â áç¨â âìáï ãᯥ宬 (eax=0). |
====================================================================== |
= ãªæ¨ï 58, ¯®¤äãªæ¨ï 15 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 15 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï |
* +8: dword: ¨£®à¨àã¥âáï |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: ¨£®à¨àã¥âáï |
* +20 = +0x14: (¯à®¢¥àï¥âáï ⮫쪮 ¢â®à®© ᨬ¢®«, áà §ã ¯®á«¥ á«íè ) |
/rd=/RAMDISK ¨«¨ /hd=/HARDDISK |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¢â®à®© ᨬ¢®« ¥ ¯à¨ ¤«¥¦¨â ¬®¦¥áâ¢ã {'r','R','h','H'}: |
* eax = 3 |
* ebx = ecx = dword [fileinfo] = 0 |
* ¤«ï à ¬¤¨áª : |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ = 2847 |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à = 512 |
* ¤«ï ¦¸á⪮£® ¤¨áª : ¡ § ¨ à §¤¥« ®¯à¥¤¥«ïîâáï ¯®¤äãªæ¨ï¬¨ 7 ¨ 8 |
äãªæ¨¨ 21: |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à (¢ ¡ ©â å) |
¬¥ç ¨ï: |
* ¥ 㤨¢«ï©â¥áì áâà ®¬ã à ᯮ«®¦¥¨î 4-£® ¢®§¢à é ¥¬®£® |
¯ à ¬¥âà - ª®£¤ ¯¨á «áï íâ®â ª®¤, ¯à¨ á¨á⥬ëå ¢ë§®¢ å |
¯à¨«®¦¥¨î ¢®§¢à é «¨áì ⮫쪮 ॣ¨áâàë eax,ebx,ecx (¨§ |
pushad-áâàãªâãàë, ¯¥à¥¤ î饩áï ª ª à£ã¬¥â á¨á⥬®© äãªæ¨¨). |
¥¯¥àì íâ® ¨á¯à ¢«¥®, â ª çâ®, ¢®§¬®¦®, ¨¬¥¥â á¬ëá« ¢®§¢à é âì |
à §¬¥à ª« áâ¥à ¢ edx, ¯®ª íâã äãªæ¨î ¥ ç «¨ ¨á¯®«ì§®¢ âì. |
* ®®¡é¥-â® ¥é¸ áãé¥áâ¢ã¥â ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18, ¢®§¢à é îé ï |
¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. ® à áè¨à¥®© â ¡«¨æ¥ ¤¨áª®¢®© |
¯®¤á¨áâ¥¬ë ¬®¦® ®¯à¥¤¥«¨âì à §¬¥à ª« áâ¥à (â ¬ ® åà ¨âáï |
¢ ᥪâ®à å) ¨ ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ ¤«ï ¦¸áâª¨å ¤¨áª®¢. |
====================================================================== |
========== ãªæ¨ï 58, ¯®¤äãªæ¨ï 16 - § ¯ãáâ¨âì ¯à®£à ¬¬ã. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 16 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®«¥ ä« £®¢: |
* ¡¨â 0: § ¯ãáâ¨âì ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© |
* ®áâ «ìë¥ ¡¨âë § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
* +8: dword: 0 ¨«¨ 㪠§ ⥫ì ASCIIZ-áâபã á ¯ à ¬¥âà ¬¨ |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax > 0 - ¯à®£à ¬¬ § £à㦥 , eax ᮤ¥à¦¨â PID |
* eax < 0 - ¯à®¨§®è« ®è¨¡ª , -eax ᮤ¥à¦¨â |
ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ , ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 7 äãªæ¨¨ 70. |
* ®¬ ¤ ï áâப ¤®«¦ § ª 稢 âìáï ᨬ¢®«®¬ á ª®¤®¬ 0 |
(ASCIIZ-áâப ); ãç¨âë¢ îâáï «¨¡® ¢á¥ ᨬ¢®«ë ¤® § ¢¥àè î饣® ã«ï |
¢ª«îç¨â¥«ì®, «¨¡® ¯¥à¢ë¥ 256 ᨬ¢®«®¢, ¢ § ¢¨á¨¬®á⨠®â ⮣®, |
çâ® ¬¥ìè¥. |
* ᫨ ¯à®æ¥áá § ¯ã᪠¥âáï ª ª ®â« ¦¨¢ ¥¬ë©, ® ᮧ¤ ¸âáï |
¢ § ¬®à®¦¥®¬ á®áâ®ï¨¨; ¤«ï § ¯ã᪠¨á¯®«ì§ã©â¥ |
¯®¤äãªæ¨î 5 äãªæ¨¨ 69. |
====================================================================== |
=== ãªæ¨ï 59 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ¯®á«¥¤¨å á¨á⥬ëå ¢ë§®¢ å. == |
====================================================================== |
®«ãç ¥â ¤ ë¥ ® ¢á¥å á¨á⥬ëå ¢ë§®¢ å ¢á¥å ¯à®æ¥áᮢ. |
à ¬¥âàë: |
* eax = 59 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¡é¥¥ ç¨á«® á¨á⥬ëå ¢ë§®¢®¢, |
ᤥ« ëå á ¬®¬¥â § £à㧪¨ á¨á⥬ë (¯® ¬®¤ã«î 2^32) |
* ebx = 0 |
®à¬ â ¨ä®à¬ 樨 ®¡ ®¤®¬ ¢ë§®¢¥: (à §¬¥à = 0x40 = 64 ¡ ©â ) |
* +0: dword: PID ¯à®æ¥áá /¯®â®ª |
* +4: 7*dword: ¬ãá®à |
* +32 = +0x20: dword: § 票¥ edi ¯à¨ ¢ë§®¢¥ |
* +36 = +0x24: dword: esi |
* +40 = +0x28: dword: ebp |
* +44 = +0x2C: dword: 㪠§ ⥫ì áâíª ®¡à ¡®â稪 ï¤à |
* +48 = +0x30: dword: ebx |
* +52 = +0x34: dword: edx |
* +56 = +0x38: dword: ecx |
* +60 = +0x3C: dword: eax (=®¬¥à á¨á⥬®© äãªæ¨¨) |
¬¥ç ¨ï: |
* ãªæ¨ï ¨á¯®«ì§ã¥âáï ⮫쪮 ¢ ¯à¨«®¦¥¨¨ systrace. |
®¢®«ì® âà㤮 ¯à¥¤áâ ¢¨âì á¨âã æ¨î, ¢ ª®â®à®© íâ® ¯à¨«®¦¥¨¥ |
¨«¨ íâ äãªæ¨ï ¤¥©áâ¢¨â¥«ì® ¯®«¥§ë, ¢®â ¢á¥ á¨áâ¥¬ë¥ ¢ë§®¢ë |
¤«ï ¯®¤¤¥à¦ª¨ í⮩ äãªæ¨¨ ¥áª®«ìª® § ¬¥¤«ïîâáï |
(å®âï ¨ ¥ ¬®£®)... |
* á¢ï§¨ á í⨬ ¥áâì ¯à¥¤«®¦¥¨¥ ¯®¤¤¥à¦ªã í⮩ äãªæ¨¨ |
¨§ ï¤à ã¡à âì ᮢᥬ, ¢¬¥áâ¥ á ¯à¨«®¦¥¨¥¬ systrace. |
* ä®à¬ æ¨ï ® á¨á⥬ëå ¢ë§®¢ å á®åà ï¥âáï ¢ |
á¨á⥬®¬ ª®«ì楢®¬ ¡ãä¥à¥ 0x10 ¢å®¤®¢. |
â äãªæ¨ï ¯à®áâ® ª®¯¨àã¥â 㪠§ ë© ®¡ê¸¬ ¤ ëå |
¨§ 㯮¬ïã⮣® ¡ãä¥à ¯® 㪠§ ®¬ã ¤à¥áã. |
* ª®© ¨§ ¢å®¤®¢ ¢ ¡ãä¥à¥ ᮮ⢥âáâ¢ã¥â ¯®á«¥¤¥¬ã ¢ë§®¢ã, |
¬®¦® ®¯à¥¤¥«¨âì ¯® § 票î eax, ¨¬¥®, |
¢å®¤ (eax and 0xF) (¯® ᬥ饨î (eax and 0xF)*0x40). |
* ⥪ã饩 ॠ«¨§ 樨 ¢®§¬®¦ë ।ª® ¢áâà¥ç î騥áï |
¯à®¡«¥¬ë à áá¨åந§ 樨, ª®£¤ ® ¥ª®â®àëå ¢ë§®¢ å |
¨ä®à¬ æ¨ï ãáâ ॢ ¥â. |
* ®¤ á¨áâ¥¬ë© ¡ãä¥à ¢ë¤¥«¥ áâà ¨æ , 4¡. |
§¬¥à ¢å®¤ = 64 ¡ ©â . |
®ç¥¬ã ¨á¯®«ì§ã¥âáï ⮫쪮 16 ¢å®¤®¢ - ¥¯®ïâ®. |
* 票¥ esp ¢ ¬®¬¥â á¨á⥬®£® ¢ë§®¢ |
í⮩ äãªæ¨¥© 㧠âì ¥«ì§ï. |
* ஢¥àª¨ ª®à४â®á⨠edx ¢ ⥪ã饩 ॠ«¨§ 樨 ¥ ¤¥« ¥âáï. |
====================================================================== |
=========== ãªæ¨ï 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC ¯à¨¬¥ï¥âáï ¤«ï ¯®áë«®ª á®®¡é¥¨© ®â ®¤®£® ¯à®æ¥áá /¯®â®ª |
¤à㣮¬ã. ਠí⮬ á«¥¤ã¥â ¯à¥¤¢ à¨â¥«ì® ¤®£®¢®à¨âìáï ® ⮬, ª ª |
¨â¥à¯à¥â¨à®¢ âì ª®ªà¥â®¥ á®®¡é¥¨¥. |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ®¡« áâì ¤«ï ¯®«ã票ï IPC --------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¯à¨¸¬¨ª®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¢á¥£¤ ãá¯¥è® |
®à¬ â IPC-¡ãä¥à : |
* +0: dword: ¥á«¨ §¤¥áì ¥ 0, â® ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬; |
¡«®ª¨àã©â¥/à §¡«®ª¨àã©â¥ ¡ãä¥à, ª®£¤ ¢ë á ¨¬ ªâ¨¢® à ¡®â ¥â¥ |
¨ ¢ ¬ ¤®, çâ®¡ë ¨§¢¥ ¥ ¨§¬¥ï«¨áì ¤ ë¥ ¡ãä¥à |
(¥ ¯®áâ㯠«¨ ®¢ë¥ á®®¡é¥¨ï) |
* +4: dword: § ïâ® ¬¥áâ ¢ ¡ãä¥à¥ (¢ ¡ ©â å) |
* +8: ¯¥à¢®¥ á®®¡é¥¨¥ |
* +8+n: ¢â®à®¥ á®®¡é¥¨¥ |
* ... |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: PID ¯à®æ¥áá /¯®â®ª , ¯®á« ¢è¥£® á®®¡é¥¨¥ |
* +4: dword: ¤«¨ á®®¡é¥¨ï (¥ áç¨â ï íâ®â § £®«®¢®ª) |
* +8: n*byte: ¤ ë¥ á®®¡é¥¨ï |
--------------- ®¤äãªæ¨ï 2 - ¯®á« âì á®®¡é¥¨¥ IPC. ---------------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¨¨æ¨ â®à®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = PID ¯à¨¸¬¨ª |
* edx = 㪠§ â¥«ì ¤ ë¥ á®®¡é¥¨ï |
* esi = ¤«¨ á®®¡é¥¨ï (¢ ¡ ©â å) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯à¨¸¬¨ª ¥ ®¯à¥¤¥«¨« ¡ãä¥à ¤«ï IPC-á®®¡é¥¨© |
(¬®¦¥â ¡ëâì, ¥é¸ ¥ ãᯥ«, ¬®¦¥â ¡ëâì, íâ® ¥ â®â ¯®â®ª, |
ª®â®àë© ã¦¥) |
* eax = 2 - ¯à¨¸¬¨ª § ¡«®ª¨à®¢ « IPC-¡ãä¥à; |
¯®¯à®¡ã©â¥ ¥¬®£® ¯®¤®¦¤ âì |
* eax = 3 - ¯¥à¥¯®«¥¨¥ IPC-¡ãä¥à ¯à¨¸¬¨ª |
* eax = 4 - ¯à®æ¥áá /¯®â®ª á â ª¨¬ PID ¥ áãé¥áâ¢ã¥â |
¬¥ç ¨ï: |
* ¨á⥬ áà §ã ¯®á«¥ § ¯¨á¨ IPC-á®®¡é¥¨ï ¢ ¡ãä¥à ¯®áë« ¥â |
¯®â®ªã-¯à¨¸¬¨ªã ᮡë⨥ á ª®¤®¬ 7 (á¬. ª®¤ë ᮡë⨩). |
====================================================================== |
=== ãªæ¨ï 61 - ¯®«ãç¨âì ¯ à ¬¥âàë ¤«ï ¯àאַ£® ¤®áâ㯠ª £à 䨪¥. === |
====================================================================== |
à®£à ¬¬¥ ¤®áâã¯ë ¤ ë¥ £à ä¨ç¥áª®£® íªà (®¡« áâì ¯ ¬ïâ¨, ª®â®à ï |
ᮡá⢥® ¨ ®â®¡à ¦ ¥â ᮤ¥à¦¨¬®¥ íªà ) ¯àï¬ãî ¡¥§ ¢ë§®¢®¢ |
á¨á⥬ëå äãªæ¨© ç¥à¥§ ᥫ¥ªâ®à gs: |
mov eax, [gs:0] |
¯®¬¥áâ¨â ¢ eax ¯¥à¢ë© dword ¡ãä¥à , ᮤ¥à¦ 騩 ¨ä®à¬ æ¨î ® 梥⥠|
«¥¢®© ¢¥à奩 â®çª¨ (¨, ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
mov [gs:0], eax |
¯à¨ à ¡®â¥ ¢ ०¨¬ å VESA c LFB |
ãáâ ®¢¨â 梥⠫¥¢®© ¢¥à奩 â®çª¨ |
(¨ ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
«ï ¨â¥à¯à¥â 樨 ¤ ëå £à ä¨ç¥áª®£® íªà âॡã¥âáï § ¨¥ |
¥ª®â®àëå ¯ à ¬¥â஢, ª®â®àë¥ ¢®§¢à é îâáï í⮩ äãªæ¨¥©. |
¬¥ç ¨ï: |
* à ¬¥âàë £à 䨪¨ ®ç¥ì ।ª® ¬¥ïîâáï ¯à¨ à ¡®â¥ á¨á⥬ë, |
¨¬¥®, ⮫쪮 ¢ á«ãç ïå, ª®£¤ ¯®«ì§®¢ ⥫ì à ¡®â ¥â |
á ¯à®£à ¬¬®© VRR. |
* ਠ¨§¬¥¥¨¨ ¢¨¤¥®à¥¦¨¬ á¨á⥬ ¯¥à¥à¨á®¢ë¢ ¥â ¢á¥ ®ª |
(ᮡë⨥ á ª®¤®¬ 1) ¨ ¯¥à¥à¨á®¢ë¢ ¥â ä® (ᮡë⨥ 5). |
⨠¦¥ ᮡëâ¨ï ¯à®¨á室ïâ ¨ ¢ ¤à㣨å á«ãç ïå, |
ª®â®àë¥ ¢áâà¥ç îâáï § ç¨â¥«ì® ç é¥, 祬 ¨§¬¥¥¨¥ ¢¨¤¥®à¥¦¨¬ . |
* à¨ à ¡®â¥ ¢ ¢¨¤¥®à¥¦¨¬ å á LFB ᥫ¥ªâ®à gs 㪠§ë¢ ¥â |
ᮡá⢥® LFB, â ª çâ® ç⥨¥/§ ¯¨áì ¯® gs ¯à¨¢®¤ïâ |
¥¯®á।á⢥® ª ¨§¬¥¥¨î ᮤ¥à¦¨¬®£® íªà . à¨ à ¡®â¥ ¢ |
¢¨¤¥®à¥¦¨¬ å ¡¥§ LFB gs 㪠§ë¢ ¥â ¥ª®â®àãî ®¡« áâì ¤ ëå |
ï¤à , ¯à¨ç¸¬ ¢á¥ äãªæ¨¨ ¢ë¢®¤ íªà ¤®¡à®á®¢¥áâ® ¢ë¯®«ïîâ |
¤¢®©ãî à ¡®âã ¯® § ¯¨á¨ ¥¯®á।á⢥® íªà ¨ ¯® § ¯¨á¨ |
¢ íâ®â ¡ãä¥à. १ã«ìâ ⥠¯à¨ ç⥨¨ ᮤ¥à¦¨¬®£® í⮣® ¡ãä¥à |
१ã«ìâ âë ᮮ⢥âáâ¢ãîâ ᮤ¥à¦¨¬®¬ã íªà |
(á, ¢®®¡é¥ £®¢®àï, ¡®«ì訬 æ¢¥â®¢ë¬ à §à¥è¥¨¥¬), |
§ ¯¨áì ¨£®à¨àã¥âáï. |
᪫î票¥¬ ï¥âáï ०¨¬ 320*200, ¤«ï ª®â®à®£® ¢ £« ¢®¬ 横«¥ |
á¨á⥬®£® ¯®â®ª ¢ë¯®«ï¥âáï ®¡®¢«¥¨¥ íªà ¢ ᮮ⢥âá⢨¨ |
á ¤¢¨¦¥¨ï¬¨ ªãàá®à ¬ëè¨. |
------------------------- §à¥è¥¨¥ íªà -------------------------- |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [à §à¥è¥¨¥ ¯® ®á¨ x]*65536 + [à §à¥è¥¨¥ ¯® ®á¨ y] |
¬¥ç ¨ï: |
* ®¦® ¨á¯®«ì§®¢ âì äãªæ¨î 14 á ãç¸â®¬ ⮣®, çâ® ® ¢®§¢à é ¥â |
à §¬¥àë 1 ¬¥ìè¥. â® ¯®«®áâìî íª¢¨¢ «¥âë© á¯®á®¡. |
------------------------ ¨á«® ¡¨â ¯¨ªá¥«ì ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡¨â ¯¨ªá¥«ì (24 ¨«¨ 32) |
------------------------ ¨á«® ¡ ©â áâபã ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡ ©â, ª®â®à®¥ § ¨¬ ¥â ®¤ áâப à §¢¸à⪨ |
(£®à¨§®â «ì ï «¨¨ï íªà ¥) |
====================================================================== |
===== ãªæ¨ï 62, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ¢¥àá¨î PCI-¨â¥à䥩á . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥é¸; ¨ ç¥ |
* ah.al = ¢¥àá¨ï PCI-¨â¥à䥩á (ah=¢¥àá¨ï, al=¯®¤¢¥àá¨ï) |
* áâ à襥 á«®¢® eax ®¡ã«¥® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥è¸ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ ax ¥®¯à¥¤¥«¥®. |
====================================================================== |
==== ãªæ¨ï 62, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì ®¬¥à ¯®á«¥¤¥© PCI-è¨ë. === |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥é¸; ¨ ç¥ |
* al = ®¬¥à ¯®á«¥¤¥© PCI-è¨ë; ®á⠢訥áï ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥è¸ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ al ¥®¯à¥¤¥«¥®. |
====================================================================== |
====================== ãªæ¨ï 62, ¯®¤äãªæ¨ï 2 ====================== |
== ®«ãç¨âì ¬¥å ¨§¬ ®¡à é¥¨ï ª ª®ä¨£ãà 樮®¬ã ¯à®áâà áâ¢ã PCI. = |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥é¸; ¨ ç¥ |
* al = ¬¥å ¨§¬ (1 ¨«¨ 2); ¯à®ç¨¥ ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥è¸ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ®¡à é¥¨ï ¢ë¡¨à ¥âáï ¢ ᮮ⢥âá⢨¨ |
á å à ªâ¥à¨á⨪ ¬¨ ®¡®à㤮¢ ¨ï. |
* ®¤äãªæ¨¨ çâ¥¨ï ¨ § ¯¨á¨ ¢â®¬ â¨ç¥áª¨ à ¡®â îâ |
á ¢ë¡à ë¬ ¬¥å ¨§¬®¬. |
====================================================================== |
======== ãªæ¨ï 62, ¯®¤äãªæ¨¨ 4,5,6 - ¯à®ç¨â âì PCI-ॣ¨áâà. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 4 - ç¨â âì ¡ ©â |
* bl = 5 - ç¨â âì á«®¢® |
* bl = 6 - ç¨â âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì ç¸âë¬ ¤«ï bl=5, |
¤¥«¨âìáï 4 ¤«ï bl=6) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥é¸ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë); ¨ ç¥ |
* al/ax/eax (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â ¤ ë¥; |
®áâ ¢è ïáï ç áâì ॣ¨áâà eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥è¸ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
======= ãªæ¨ï 62, ¯®¤äãªæ¨¨ 8,9,10 - § ¯¨á âì ¢ PCI-ॣ¨áâà. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 8 - ¯¨á âì ¡ ©â |
* bl = 9 - ¯¨á âì á«®¢® |
* bl = 10 - ¯¨á âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì ç¸âë¬ ¤«ï bl=9, |
¤¥«¨âìáï 4 ¤«ï bl=10) |
* dl/dx/edx (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â |
¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥é¸ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë) |
* eax = 0 - ãá¯¥è® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥è¸ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown; |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
================ ãªæ¨ï 63 - à ¡®â á ¤®áª®© ®â« ¤ª¨. =============== |
====================================================================== |
®áª ®â« ¤ª¨ ¯à¥¤áâ ¢«ï¥â ᮡ®© á¨áâ¥¬ë© ¡ãä¥à ( 512 ¡ ©â), |
¢ ª®â®àë© «î¡ ï ¯à®£à ¬¬ ¬®¦¥â § ¯¨á âì (¢®®¡é¥ £®¢®àï, ¯à®¨§¢®«ìë¥) |
¤ ë¥ ¨ ¨§ ª®â®à®£® ¤àã£ ï ¯à®£à ¬¬ ¬®¦¥â í⨠¤ ë¥ ¯à®ç¨â âì. |
áâì ᮣ« 襨¥, ¢ ᮮ⢥âá⢨¨ á ª®â®àë¬ § ¯¨áë¢ ¥¬ë¥ ¤ ë¥ - |
⥪áâ®¢ë¥ áâப¨, ¨â¥à¯à¥â¨àã¥¬ë¥ ª ª ®â« ¤®çë¥ á®®¡é¥¨ï ® 室¥ |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë. ¤à® ¢ ®¯à¥¤¥«¸ëå á¨âã æ¨ïå â ª¦¥ § ¯¨áë¢ ¥â |
¤®áªã ®â« ¤ª¨ ᢥ¤¥¨ï ® ¢ë¯®«¥¨¨ ¥ª®â®àëå äãªæ¨©; |
¯® ᮣ« 襨î á®®¡é¥¨ï ï¤à ç¨ îâáï á ¯à¥ä¨ªá "K : ". |
«ï ¯à®á¬®âà ¤®áª¨ ®â« ¤ª¨ ᮧ¤ ® ¯à¨«®¦¥¨¥ board, |
ª®â®à®¥ áç¨âë¢ ¥â ¤ ë¥ ¨§ ¡ãä¥à ¨ ®â®¡à ¦ ¥â ¨å ¢ ᢮¸¬ ®ª¥. board |
¯®¨¬ ¥â ¯®á«¥¤®¢ ⥫ì®áâì ª®¤®¢ 13,10 ª ª ¯¥à¥å®¤ ®¢ãî áâபã. |
¨¬¢®« á ã«¥¢ë¬ ª®¤®¬ ¢ ª®æ¥ áâப¨ ¥ ®¡ï§ ⥫¥, ® ¨ ¥ ¬¥è ¥â. |
á¢ï§¨ á ¯®ï¢«¥¨¥¬ ®â« ¤ç¨ª 楮áâì ¤®áª¨ ®â« ¤ª¨ ¥áª®«ìª® |
ᨧ¨« áì, ¯®áª®«ìªã ®â« ¤ç¨ª ¯®§¢®«ï¥â ¯®«®áâìî ª®â஫¨à®¢ âì 室 |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë, ¯à¨ç¸¬ ¤«ï í⮣® ¥ âॡã¥âáï ¨ª ª¨å ãᨫ¨© |
á® áâ®à®ë á ¬®© ¯à®£à ¬¬ë. ¥¬ ¥ ¬¥¥¥ ¢® ¬®£¨å á«ãç ïå |
¤®áª ®â« ¤ª¨ ¯à®¤®«¦ ¥â ®áâ ¢ âìáï ¯®«¥§®©. |
---------------------------- ¯¨áì ¡ ©â ---------------------------- |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ¡ ©â ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ©â § ¯¨áë¢ ¥âáï ¢ ¡ãä¥à. «¨ ¡ãä¥à - 512 ¡ ©â. |
ਠ¯¥à¥¯®«¥¨¨ ¡ãä¥à ¢á¥ ¯®«ãç¥ë¥ ¤ ë¥ â¥àïîâáï |
¨ § ¯®«¥¨¥ ç¨ ¥âáï ᮢ á ã«ï. |
* «ï ¢ë¢®¤ ¤®áªã ®â« ¤ª¨ ¡®«¥¥ á«®¦ëå ®¡ê¥ªâ®¢ (áâப, ç¨á¥«) |
¤®áâ â®ç® í⮩ äãªæ¨¨, ¢ë§ë¢ ¥¬®© ¢ 横«¥. ®¦® ¥ ¯¨á âì |
¢àãçãî ᮮ⢥âáâ¢ãî騩 ª®¤, ¢®á¯®«ì§®¢ âìáï ä ©«®¬ debug.inc, |
¢å®¤ï騬 ¢ ¤¨áâਡã⨢. |
---------------------------- ⥨¥ ¡ ©â ---------------------------- |
¡¨à ¥â ¡ ©â ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ebx = 0 - ¡ãä¥à ¯ãáâ |
* eax = ¡ ©â, ebx = 1 - ¡ ©â ãá¯¥è® ¯à®ç¨â |
====================================================================== |
========== ãªæ¨ï 64 - ¯¥à¥à á¯à¥¤¥«¨âì ¯ ¬ïâì ¯à¨«®¦¥¨ï. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 64 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = ®¢ë© à §¬¥à ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥¤®áâ â®ç® ¯ ¬ï⨠|
¬¥ç ¨ï: |
* ¤ ë© ¬®¬¥â íâ äãªæ¨ï ï¥âáï ¥¤¨áâ¢¥ë¬ á।á⢮¬ ¤«ï |
¤¨ ¬¨ç¥áª®£® ¢ë¤¥«¥¨ï/®á¢®¡®¦¤¥¨ï ¯ ¬ï⨠¯à¨«®¦¥¨ï. |
====================================================================== |
================= ãªæ¨ï 66 - à ¡®â á ª« ¢¨ âãன. ================= |
====================================================================== |
¥¦¨¬ ¢¢®¤ ¢«¨ï¥â १ã«ìâ âë çâ¥¨ï ª« ¢¨è äãªæ¨¥© 2. |
ਠ§ £à㧪¥ ¯à®£à ¬¬ë ¤«ï ¥¸ ãáâ ¢«¨¢ ¥âáï ASCII-०¨¬ ¢¢®¤ . |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ०¨¬ ¢¢®¤ á ª« ¢¨ âãàë. --------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ०¨¬: |
* 0 = ®¡ëçë© (ASCII-ᨬ¢®«ë) |
* 1 = ᪠ª®¤ë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
--------- ®¤äãªæ¨ï 2 - ¯®«ãç¨âì ०¨¬ ¢¢®¤ á ª« ¢¨ âãàë. ---------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ã騩 ०¨¬ |
------- ®¤äãªæ¨ï 3 - ¯®«ãç¨âì á®áâ®ï¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è. -------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡¨â®¢ ï ¬ ᪠: |
* ¡¨â 0 (¬ ᪠1): «¥¢ë© Shift ¦ â |
* ¡¨â 1 (¬ ᪠2): ¯à ¢ë© Shift ¦ â |
* ¡¨â 2 (¬ ᪠4): «¥¢ë© Ctrl ¦ â |
* ¡¨â 3 (¬ ᪠8): ¯à ¢ë© Ctrl ¦ â |
* ¡¨â 4 (¬ ᪠0x10): «¥¢ë© Alt ¦ â |
* ¡¨â 5 (¬ ᪠0x20): ¯à ¢ë© Alt ¦ â |
* ¡¨â 6 (¬ ᪠0x40): CapsLock ¢ª«îç¸ |
* ¡¨â 7 (¬ ᪠0x80): NumLock ¢ª«îç¸ |
* ¡¨â 8 (¬ ᪠0x100): ScrollLock ¢ª«îç¸ |
* ¯à®ç¨¥ ¡¨âë á¡à®è¥ë |
----- ®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ®¡é¥á¨á⥬ãî "£®àïçãî ª« ¢¨èã". ----- |
¦ ⨨ "£®àï祩 ª« ¢¨è¨" ¨§¢¥é îâáï ⮫쪮 ¯à¨«®¦¥¨ï, |
ãáâ ®¢¨¢è¨¥ ¥¸; ªâ¨¢®¥ ¯à¨«®¦¥¨¥ (ª ª®â®à®¬ã ¯®áâ㯠¥â |
¢¥áì ®à¬ «ìë© ¢¢®¤) â ª¨å ª« ¢¨è ¥ ¯®«ãç ¥â. |
§¢¥é¥¨¥ § ª«îç ¥âáï ¢ ¯®á뫪¥ ᮡëâ¨ï á ª®¤®¬ 2. |
à®ç¨â âì "£®àïçãî ª« ¢¨èã" ¬®¦® â ª ¦¥, ª ª ¨ ®¡ëçãî, - |
äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl § ¤ ¸â ᪠ª®¤ ª« ¢¨è¨; |
¨á¯®«ì§ã©â¥ cl=0 ¤«ï § ¤ ¨ï ª®¬¡¨ 権 ⨯ Ctrl+Shift |
* edx = 0xXYZ § ¤ ¸â ¢®§¬®¦ë¥ á®áâ®ï¨ï ã¯à ¢«ïîé¨å ª« ¢¨è: |
* Z (¬« ¤è¨¥ 4 ¡¨â ) § ¤ ¸â á®áâ®ï¨¥ ª« ¢¨è LShift ¨ RShift: |
* 0 = ¨ ®¤ ¨§ ª« ¢¨è ¥ ¤®«¦ ¡ëâì ¦ â ; |
* 1 = ஢® ®¤ ¨§ ª« ¢¨è ¤®«¦ ¡ëâì ¦ â ; |
* 2 = ®¡¥ ª« ¢¨è¨ ¤®«¦ë ¡ëâì ¦ âë; |
* 3 = ¤®«¦ ¡ëâì ¦ â LShift, ® ¥ RShift; |
* 4 = ¤®«¦ ¡ëâì ¦ â RShift, ® ¥ LShift |
* Y - «®£¨ç® ¤«ï LCtrl ¨ RCtrl; |
* X - «®£¨ç® ¤«ï LAlt ¨ RAlt |
®§¢à é ¥¬®¥ § 票¥: |
* eax=0 - ãá¯¥è® |
* eax=1 - ᫨誮¬ ¬®£® "£®àïç¨å ª« ¢¨è" (¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 256) |
¬¥ç ¨ï: |
* ®àïç ï ª« ¢¨è ¬®¦¥â áà ¡ âë¢ âì «¨¡® ¯à¨ ¦ ⨨, |
«¨¡® ¯à¨ ®â¯ã᪠¨¨. ª ª®¤ ®â¯ã᪠¨ï ª« ¢¨è¨ 128 ¡®«ìè¥, |
祬 ᪠ª®¤ ¦ â¨ï (â.¥. ãáâ ®¢«¥ áâ à訩 ¡¨â). |
* ¥áª®«ìª® ¯à¨«®¦¥¨© ¬®£ãâ ãáâ ®¢¨âì ®¤ã ¨ âã ¦¥ ª®¬¡¨ æ¨î; |
® ¦ ⨨ â ª®© ª®¬¡¨ 樨 ¡ã¤ãâ ¨§¢¥é âìáï ¢á¥ â ª¨¥ ¯à¨«®¦¥¨ï. |
------ ®¤äãªæ¨ï 5 - 㤠«¨âì ãáâ ®¢«¥ãî "£®àïçãî ª« ¢¨èã". ------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ᪠ª®¤ ª« ¢¨è¨ ¨ edx = 0xXYZ â ª¨¥ ¦¥, ª ª ¨ ¢ ¯®¤äãªæ¨¨ 4 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥â â ª®© £®àï祩 ª« ¢¨è¨ |
¬¥ç ¨ï: |
* ਠ§ ¢¥à襨¨ ¯à®æ¥áá /¯®â®ª 㤠«ïîâáï ¢á¥ ãáâ ®¢«¥ë¥ ¨¬ |
£®àï稥 ª« ¢¨è¨. |
* 맮¢ äãªæ¨¨ ¥ ¢«¨ï¥â ¤à㣨¥ ¯à¨«®¦¥¨ï. |
᫨ ¤à㣮¥ ¯à¨«®¦¥¨¥ ®¯à¥¤¥«¨«® íâã ¦¥ ª®¬¡¨ æ¨î, |
®® ¯®-¯à¥¦¥¬ã ¡ã¤¥â ¯®«ãç âì 㢥¤®¬«¥¨ï. |
====================================================================== |
============ ãªæ¨ï 67 - ¨§¬¥¨âì ¯®«®¦¥¨¥/à §¬¥àë ®ª . =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 67 - ®¬¥à äãªæ¨¨ |
* ebx = ®¢ ï x-ª®®à¤¨ â ®ª |
* ecx = ®¢ ï y-ª®®à¤¨ â ®ª |
* edx = ®¢ë© x-à §¬¥à ®ª |
* esi = ®¢ë© y-à §¬¥à ®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* 票¥ -1 ¤«ï ¯ à ¬¥âà ®§ ç ¥â "¥ ¨§¬¥ïâì"; ¯à¨¬¥à, ¤«ï |
¯¥à¥¬¥é¥¨ï ®ª ¡¥§ ¨§¬¥¥¨ï à §¬¥à®¢ ¬®¦® 㪠§ âì edx=esi=-1. |
* ।¢ à¨â¥«ì® ®ª® ¤®«¦® ¡ëâì ®¯à¥¤¥«¥® äãªæ¨¥© 0. |
¦¥ § ¤ ¸â ç «ìë¥ ª®®à¤¨ âë ¨ à §¬¥àë ®ª . |
* §¬¥àë ®ª ¯®¨¬ îâáï ¢ á¬ëá«¥ äãªæ¨¨ 0, â.¥. |
®¤¨ ¯¨ªá¥«ì ¬¥ìè¥, 祬 ॠ«ìë¥ à §¬¥àë. |
* 맮¢ äãªæ¨¨ ¤«ï ¬ ªá¨¬¨§¨à®¢ ëå ®ª® ¯à®áâ® ¨£®à¨àã¥âáï. |
* «ï ®ª® ᮮ⢥âáâ¢ãîé¨å á⨫¥© ¯®«®¦¥¨¥ ¨/¨«¨ à §¬¥àë ¬®£ãâ ¡ëâì |
¨§¬¥¥ë ¯®«ì§®¢ ⥫¥¬; ⥪ã騥 ¯®«®¦¥¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì |
¯®«ãç¥ë ¢ë§®¢®¬ äãªæ¨¨ 9. |
* ãªæ¨ï ¯®áë« ¥â ®ªã ᮡë⨥ ¯¥à¥à¨á®¢ª¨ (á ª®¤®¬ 1). |
====================================================================== |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì áç¸â稪 ¯¥à¥ª«î票© § ¤ ç. == |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯¥à¥ª«î票© § ¤ ç á ¬®¬¥â § £à㧪¨ á¨á⥬ë |
(¯® ¬®¤ã«î 2^32) |
====================================================================== |
====================== ãªæ¨ï 68, ¯®¤äãªæ¨ï 1 ====================== |
============ ¥à¥ª«îç¨âìáï á«¥¤ãî騩 ¯®â®ª ¢ë¯®«¥¨ï. ============ |
====================================================================== |
ãªæ¨ï § ¢¥àè ¥â ⥪ã騩 ª¢ ⠢६¥¨, ¢ë¤¥«¥ë© ¯®â®ªã, |
¨ ¯¥à¥ª«îç ¥âáï á«¥¤ãî騩. |
( ª®© ¯®â®ª ª ª®£® ¯à®æ¥áá ¡ã¤¥â á«¥¤ãî騬, ¯à¥¤áª § âì ¥«ì§ï). |
®§¤¥¥, ª®£¤ ¤® ⥪ã饣® ¯®â®ª ¤®©¤¸â ®ç¥à¥¤ì, |
¢ë¯®«¥¨¥ ¢®§®¡®¢¨âáï. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
=============== ãªæ¨ï 68, ¯®¤äãªæ¨ï 2 - ªíè + rdpmc. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = âॡ㥬®¥ ¤¥©á⢨¥: |
* ecx = 0 - à §à¥è¨âì ¢ë¯®«¥¨¥ ¨áâàãªæ¨¨ rdpmc |
(ReaD Performance-Monitoring Counters) |
* ecx = 1 - 㧠âì, ¢ª«îç¸/¢ëª«îç¥ ªíè |
* ecx = 2 - ¢ª«îç¨âì ªíè |
* ecx = 3 - ¢ëª«îç¨âì ªíè |
®§¢à é ¥¬®¥ § 票¥: |
* ¤«ï ecx=0: |
* eax = § 票¥ cr4 |
* ¤«ï ecx=1: |
* eax = (cr0 and 0x60000000): |
* eax = 0 - ªíè ¢ª«îç¸ |
* eax <> 0 - ªíè ¢ëª«îç¥ |
* ¤«ï ecx=2 ¨ ecx=3: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 3 - ¯à®ç¨â âì MSR-ॣ¨áâà. ========= |
====================================================================== |
MSR = Model Specific Register; ¯®«ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à |
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥â 樨 ¯® ¯à®æ¥áá®àã ( ¯à¨¬¥à, IA-32 Intel |
Architecture Software Developer's Manual, Volume 3, Appendix B); |
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮¸ ¯®¤¬®¦¥á⢮ MSR-ॣ¨áâ஢. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx ¨£®à¨àã¥âáï |
* edx = ¤à¥á MSR |
®§¢à é ¥¬®¥ § 票¥: |
* ebx:eax = áâ à訩:¬« ¤è¨© dword १ã«ìâ â |
¬¥ç ¨ï: |
* ª § ¨¥ ¢ ecx ¥áãé¥áâ¢ãî饣® ¨«¨ ¥à¥ «¨§®¢ ®£® ¤«ï ¤ ®£® |
¯à®æ¥áá®à MSR ¯®¢«¥ç¸â ¨áª«î票¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ì¸â ¯®â®ª. |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬, |
ª®¬ ¤®© cpuid. ç¥ ¢®§¨ª¥â 㦥 ¤à㣮¥ ¨áª«î票¥ ¢ ï¤à¥, |
ª®â®à®¥ ¢á¸ à ¢® ¯à¨¡ì¸â ¯®â®ª. |
====================================================================== |
========= ãªæ¨ï 68, ¯®¤äãªæ¨ï 4 - § ¯¨á âì ¢ MSR-ॣ¨áâà. ========= |
====================================================================== |
MSR = Model Specific Register; ¯®«ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à |
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥â 樨 ¯® ¯à®æ¥áá®àã ( ¯à¨¬¥à, IA-32 Intel |
Architecture Software Developer's Manual, Volume 3, Appendix B); |
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮¸ ¯®¤¬®¦¥á⢮ MSR-ॣ¨áâ஢. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx ¨£®à¨àã¥âáï |
* edx = ¤à¥á MSR |
* esi:edi = áâ à訩:¬« ¤è¨© dword |
®§¢à é ¥¬®¥ § 票¥: |
* ebx:eax = ª®¯¨ï esi:edi |
¬¥ç ¨ï: |
* ª § ¨¥ ¢ ecx ¥áãé¥áâ¢ãî饣® ¨«¨ ¥à¥ «¨§®¢ ®£® ¤«ï ¤ ®£® |
¯à®æ¥áá®à MSR ¯®¢«¥ç¸â ¨áª«î票¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ì¸â ¯®â®ª. |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬, |
ª®¬ ¤®© cpuid. ç¥ ¢®§¨ª¥â 㦥 ¤à㣮¥ ¨áª«î票¥ ¢ ï¤à¥, |
ª®â®à®¥ ¢á¸ à ¢® ¯à¨¡ì¸â ¯®â®ª. |
====================================================================== |
======= ãªæ¨ï 68, ¯®¤äãªæ¨ï 5 - ¢ë¤¥«¨âì 䨧¨ç¥áªãî ¯ ¬ïâì. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = à §¬¥à (¢ ¡ ©â å) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 䨧¨ç¥áª¨© ¤à¥á ¢ë¤¥«¥®© ¯ ¬ï⨠|
¬¥ç ¨ï: |
* ¡ëçë¥ ¯à¨«®¦¥¨ï ¥ ¤®«¦ë ¨á¯®«ì§®¢ âì íâã äãªæ¨î, ® |
¯à¥¤ § ç¥ ¤«ï á«ãç ï, ª®£¤ ¯à¨ à ¡®â¥ á ª ª¨¬-«¨¡® |
ãáâனá⢮¬ âॡã¥âáï à §¬¥áâ¨âì ¤ ë¥ ¯® ¨§¢¥á⮬ã 䨧¨ç¥áª®¬ã |
¤à¥áã. ( áãé®áâ¨, íâ äãªæ¨ï à §à ¡ âë¢ « áì ¤«ï AC97WAV.) |
* ¨á«® ¡«®ª®¢ 䨧¨ç¥áª®© ¯ ¬ï⨠®£à ¨ç¥® (ª®áâ ⮩ 24, |
¯à¨ç¸¬ íâ ª®áâ â ¢ª«îç ¥â ¨ ¥áª®«ìª® ¡«®ª®¢ ¯ ¬ï⨠|
¤«ï ¤®¡®á⥩ ï¤à ). |
* ᢮¡®¤¨âì ¢ë¤¥«¥ãî â ª¨¬ ®¡à §®¬ ¯ ¬ïâì ¬®¦® |
¯®¤äãªæ¨¥© 6, ª®¯¨à®¢ ¨¥¬ ¤ ëå â㤠/®¡à â® |
§ ¨¬ îâáï ¯®¤äãªæ¨¨ 7 ¨ 8. |
====================================================================== |
====== ãªæ¨ï 68, ¯®¤äãªæ¨ï 6 - ®á¢®¡®¤¨âì 䨧¨ç¥áªãî ¯ ¬ïâì. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 䨧¨ç¥áª¨© ¤à¥á ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¡ëçë¥ ¯à¨«®¦¥¨ï ¥ ¤®«¦ë ¨á¯®«ì§®¢ âì íâã äãªæ¨î, ® |
¯à¥¤ § ç¥ ¤«ï á«ãç ï, ª®£¤ ¯à¨ à ¡®â¥ á ª ª¨¬-«¨¡® |
ãáâனá⢮¬ âॡã¥âáï à §¬¥áâ¨âì ¤ ë¥ ¯® ¨§¢¥á⮬ã 䨧¨ç¥áª®¬ã |
¤à¥áã. ( áãé®áâ¨, íâ äãªæ¨ï à §à ¡ âë¢ « áì ¤«ï AC97WAV.) |
* ¬ïâì ¤®«¦ ¡ëâì à ¥¥ ¢ë¤¥«¥ ¯®¤äãªæ¨¥© 5. |
====================================================================== |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¤ ë¥ ¢ 䨧¨ç¥áªãî ¯ ¬ïâì. == |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 䨧¨ç¥áª¨© ¤à¥á |
* edx = 㪠§ â¥«ì ¤ ë¥ (¢ ¯à¨«®¦¥¨¨) |
* esi = à §¬¥à ¤ ëå (¢ ¡ ©â å) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¡ëçë¥ ¯à¨«®¦¥¨ï ¥ ¤®«¦ë ¨á¯®«ì§®¢ âì íâã äãªæ¨î, ® |
¯à¥¤ § ç¥ ¤«ï á«ãç ï, ª®£¤ ¯à¨ à ¡®â¥ á ª ª¨¬-«¨¡® |
ãáâனá⢮¬ âॡã¥âáï à §¬¥áâ¨âì ¤ ë¥ ¯® ¨§¢¥á⮬ã 䨧¨ç¥áª®¬ã |
¤à¥áã. ( áãé®áâ¨, íâ äãªæ¨ï à §à ¡ âë¢ « áì ¤«ï AC97WAV.) |
* ¨ ¯ §® 䨧¨ç¥áª¨å ¤à¥á®¢ ¤®«¦¥ «¥¦ âì ¢ãâà¨ à ¥¥ ¢ë¤¥«¥®£® |
¯®¤äãªæ¨¥© 5 ¡«®ª 䨧¨ç¥áª®© ¯ ¬ïâ¨. |
* ஢¥à®ª ª®à४â®á⨠¥ ¯à®¨§¢®¤¨âáï. |
====================================================================== |
== ãªæ¨ï 68, ¯®¤äãªæ¨ï 8 - ¯à®ç¨â âì ¤ ë¥ ¨§ 䨧¨ç¥áª®© ¯ ¬ïâ¨. = |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 䨧¨ç¥áª¨© ¤à¥á |
* edx = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¤ ëå (¢ ¯à¨«®¦¥¨¨) |
* esi = à §¬¥à ¤ ëå (¢ ¡ ©â å) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¡ëçë¥ ¯à¨«®¦¥¨ï ¥ ¤®«¦ë ¨á¯®«ì§®¢ âì íâã äãªæ¨î, ® |
¯à¥¤ § ç¥ ¤«ï á«ãç ï, ª®£¤ ¯à¨ à ¡®â¥ á ª ª¨¬-«¨¡® |
ãáâனá⢮¬ âॡã¥âáï à §¬¥áâ¨âì ¤ ë¥ ¯® ¨§¢¥á⮬ã 䨧¨ç¥áª®¬ã |
¤à¥áã. ( áãé®áâ¨, íâ äãªæ¨ï à §à ¡ âë¢ « áì ¤«ï AC97WAV.) |
* ¨ ¯ §® 䨧¨ç¥áª¨å ¤à¥á®¢ ¤®«¦¥ «¥¦ âì ¢ãâà¨ à ¥¥ ¢ë¤¥«¥®£® |
¯®¤äãªæ¨¥© 5 ¡«®ª 䨧¨ç¥áª®© ¯ ¬ïâ¨. |
* ஢¥à®ª ª®à४â®á⨠¥ ¯à®¨§¢®¤¨âáï. |
====================================================================== |
======================== ãªæ¨ï 69 - ®â« ¤ª . ======================= |
====================================================================== |
à®æ¥áá ¬®¦¥â § £à㧨âì ¤à㣮© ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© ãáâ ®¢ª®© |
ᮮ⢥âáâ¢ãî饣® ¡¨â ¯à¨ ¢ë§®¢¥ ¯®¤äãªæ¨¨ 16 äãªæ¨¨ 58 |
¨«¨ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 70. |
¯à®æ¥áá ¬®¦¥â ¡ëâì ⮫쪮 ®¤¨ ®â« ¤ç¨ª; ®¤¨ ¯à®æ¥áá ¬®¦¥â |
®â« ¦¨¢ âì ¥áª®«ìª® à §ëå. ¨á⥬ 㢥¤®¬«ï¥â ®â« ¤ç¨ª ® ᮡëâ¨ïå, |
¯à®¨á室ïé¨å á ®â« ¦¨¢ ¥¬ë¬ ¯à®æ¥áᮬ. ®®¡é¥¨ï § ¯¨áë¢ îâáï ¢ ¡ãä¥à, |
®¯à¥¤¥«¸ë© ¯®¤äãªæ¨¥© 0. |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: ª®¤ á®®¡é¥¨ï |
* +4: dword: PID ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* +8: ¬®£ãâ ¯à¨áãâá⢮¢ âì ¤®¯®«¨â¥«ìë¥ ¤ ë¥, |
®¯à¥¤¥«ï¥¬ë¥ ª®¤®¬ á®®¡é¥¨ï |
®¤ë á®®¡é¥¨©: |
* 1 = ¨áª«î票¥ |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ¸âáï dword-®¬¥à ¨áª«î票ï |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
* 2 = ¯à®æ¥áá § ¢¥à訫áï |
* ¯à¨å®¤¨â ¯à¨ «î¡®¬ § ¢¥à襨¨: ª ª ç¥à¥§ á¨á⥬ãî äãªæ¨î -1, |
â ª ¨ ¯à¨ "㡨©á⢥" «î¡ë¬ ¤à㣨¬ ¯à®æ¥áᮬ |
(¢ ⮬ ç¨á«¥ á ¬¨¬ ®â« ¤ç¨ª®¬) |
* 3 = ®â« ¤®ç®¥ ¨áª«î票¥ int 1 = #DB |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ¸âáï dword-®¡à § ॣ¨áâà DR6: |
* ¡¨âë 0-3: ¢ë¯®«¥® ãá«®¢¨¥ ᮮ⢥âáâ¢ãî饩 â®çª¨ ®áâ ®¢ |
(ãáâ ®¢«¥®© ¯®¤äãªæ¨¥© 9) |
* ¡¨â 14: ¨áª«î票¥ ¯à®¨§®è«® ¨§-§ ०¨¬ |
¯®è £®¢®© âà áá¨à®¢ª¨ (ãáâ ®¢«¥ ä« £ TF) |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
ਠ§ ¢¥à襨¨ ®â« ¤ç¨ª ¯à¨¡¨¢ îâáï ¢á¥ ®â« ¦¨¢ ¥¬ë¥ ¯à®æ¥ááë. |
᫨ ®â« ¤ç¨ª í⮣® ¥ å®ç¥â, ® ¤®«¦¥ ¯à¥¤¢ à¨â¥«ì® ®âª«îç¨âìáï |
¯®¤äãªæ¨¥© 3. |
ᥠ¯®¤äãªæ¨¨ ¯à¨¬¥¨¬ë ⮫쪮 ª ¯à®æ¥áá ¬/¯®â®ª ¬, § ¯ãé¥ë¬ |
¨§ ⥪ã饣® äãªæ¨¥© 58 ¨«¨ 70 á ãáâ ®¢«¥ë¬ ä« £®¬ ®â« ¤ª¨. |
â« ¤ª ¬®£®¯®â®çëå ¯à®£à ¬¬ ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
®«ë© ᯨ᮪ ¯®¤äãªæ¨©: |
* ¯®¤äãªæ¨ï 0 - ®¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨© |
* ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 5 - ¢®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 6 - ¯à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 9 - ãáâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 0 ====================== |
========= ¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨©. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì |
®à¬ â ®¡« á⨠¤ ëå: |
* +0: dword: N = à §¬¥à ¡ãä¥à (¥ áç¨â ï í⮣® § £®«®¢ª ) |
* +4: dword: § ïâ® ¢ ¡ãä¥à¥ |
* +8: N*byte: ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯®«¥ à §¬¥à ®âà¨æ ⥫ì®, ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬ |
¨ ¯à¨ ¯®áâ㯫¥¨¨ ®¢®£® á®®¡é¥¨ï á¨á⥬ ¡ã¤¥â ¦¤ âì. |
«ï á¨åந§ 樨 ®¡à ¬«ï©â¥ ¢áî à ¡®âã á ¡ãä¥à®¬ ®¯¥à æ¨ï¬¨ |
¡«®ª¨à®¢ª¨/à §¡«®ª¨à®¢ª¨ |
neg [bufsize] |
* ë¥ ¢ ¡ãä¥à¥ âà ªâãîâáï ª ª ¬ áᨢ í«¥¬¥â®¢ ¯¥à¥¬¥®© ¤«¨ë - |
á®®¡é¥¨©. ®à¬ â á®®¡é¥¨ï 㪠§ ¢ ®¡é¥¬ ®¯¨á ¨¨. |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 1 ====================== |
========= ®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ : (FPU ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï) |
* +0: dword: eip |
* +4: dword: eflags |
* +8: dword: eax |
* +12 = +0xC: dword: ecx |
* +16 = +0x10: dword: edx |
* +20 = +0x14: dword: ebx |
* +24 = +0x18: dword: esp |
* +28 = +0x1C: dword: ebp |
* +32 = +0x20: dword: esi |
* +36 = +0x24: dword: edi |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ¢®§¢à é ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 2 ====================== |
======== áâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 1. |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ãáâ ¢«¨¢ ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
== ãªæ¨ï 69, ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . = |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá ¡ë« ¯à¨®áâ ®¢«¥, ® ¢®§®¡®¢«ï¥â ¢ë¯®«¥¨¥. |
====================================================================== |
==== ãªæ¨ï 69, ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à ¯à®æ¥áá |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 5 ====================== |
============ ®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 6 ====================== |
============= à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ç¨â âì |
* esi = ¤à¥á ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* edi = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
ãªæ¨ï 69, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ¯¨á âì |
* esi = ¤à¥á ¯ ¬ï⨠¢ ®â« ¦¨¢ ¥¬®¬ ¯à®æ¥áᥠ|
* edi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====== ãªæ¨ï 69, ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ãªæ¨ï «®£¨ç ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18 á ¤¢ã¬ï ®â«¨ç¨ï¬¨: |
âॡã¥âáï ¢ë¯®«¥¨¥ ¯¥à¢®£® § ¬¥ç ¨ï ¨ ¯à¨¨¬ ¥âáï PID, |
¥ ®¬¥à á«®â . |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 9 ====================== |
============= áâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* dl = ¨¤¥ªá â®çª¨ ®áâ ®¢ , ®â 0 ¤® 3 ¢ª«îç¨â¥«ì® |
* dh = ä« £¨: |
* ¥á«¨ áâ à訩 ¡¨â á¡à®è¥ - ãáâ ®¢¨âì â®çªã ®áâ ®¢ : |
* ¡¨âë 0-1 - ãá«®¢¨¥: |
* 00 = â®çª ®áâ ®¢ ¢ë¯®«¥¨¥ |
* 01 = â®çª ®áâ ®¢ § ¯¨áì |
* 11 = â®çª ®áâ ®¢ ç⥨¥/§ ¯¨áì |
* ¡¨âë 2-3 - ¤«¨ ; ¤«ï â®ç¥ª ®áâ ®¢ ¨á¯®«¥¨¥ ¤®«¦® ¡ëâì |
00, ¢ ¯à®â¨¢®¬ á«ãç ¥ ®¤® ¨§ |
* 00 = ¡ ©â |
* 01 = á«®¢® |
* 11 = ¤¢®©®¥ á«®¢® |
* esi = ¤à¥á â®çª¨ ®áâ ®¢ ; ¤®«¦¥ ¡ëâì ¢ë஢¥ |
ᮮ⢥âá⢥® ¤«¨¥ (â.¥. ¤®«¦¥ ¡ëâì ç¸âë¬ ¤«ï |
â®ç¥ª ®áâ ®¢ á«®¢®, ªà ⥠4 ¤«ï ¤¢®©®£® á«®¢ ) |
* ¥á«¨ áâ à訩 ¡¨â ãáâ ®¢«¥ - á¡à®á¨âì â®çªã ®áâ ®¢ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª ¢® ¢å®¤ëå ¤ ëå |
* eax = 2 - (§ १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï |
¢ ⥪ã饩 ॠ«¨§ 樨) á í⨬ ¨¤¥ªá®¬ 㦥 ãáâ ®¢«¥ |
£«®¡ «ì ï â®çª ®áâ ®¢ |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ¯¯ à âë¥ â®çª¨ ®áâ ®¢ ॠ«¨§ãîâáï ç¥à¥§ DRx-ॣ¨áâàë |
¯à®æ¥áá®à , ®âáî¤ ¢á¥ ®£à ¨ç¥¨ï. |
* ãªæ¨ï ¬®¦¥â ¯¥à¥ãáâ ®¢¨âì à ¥¥ ãáâ ®¢«¥ãî ¥© ¦¥ |
â®çªã ®áâ ®¢ (¨ª ª ¥ á®®¡é ï ®¡ í⮬). |
¥¤¨â¥ ᯨ᮪ ãáâ ®¢«¥ëå â®ç¥ª ®áâ ®¢ ¢ ®â« ¤ç¨ª¥. |
* à ¡ âë¢ ¨¥ â®çª¨ ®áâ ®¢ § ª«îç ¥âáï ¢ £¥¥à¨à®¢ ¨¨ |
®â« ¤®ç®£® ¨áª«î票ï #DB, ® ª®â®à®¬ á¨á⥬ á®®¡é ¥â ®â« ¤ç¨ªã. |
* ®çª ®áâ ®¢ § ¯¨áì ¨ ç⥨¥/§ ¯¨áì áà ¡ âë¢ ¥â ¯®á«¥ |
¢ë¯®«¥¨ï ¢ë§¢ ¢è¥© ¥¸ ¨áâàãªæ¨¨. |
====================================================================== |
= ãªæ¨ï 70 - à ¡®â á ä ©«®¢®© á¨á⥬®© á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬¸. = |
====================================================================== |
à ¬¥âàë: |
* eax = 70 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ᬥ饨¥ ¢ ä ©«¥ |
* +8: dword: áâ à訩 dword ᬥ饨ï (¤®«¦¥ ¡ëâì 0) ¨«¨ ¯®«¥ ä« £®¢ |
* +12 = +0xC: dword: à §¬¥à |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâà㠡㪢. ãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì |
§ ¯¨á ë ¢ ª®¤¨à®¢ª¥ cp866 (DOS). |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ¦¸á⪨¬ ¤¨áª ¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª CD IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave) |
ਬ¥àë: |
* '/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/2/menuet/pics/tanzania.bmp',0 |
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« |
* ¯®¤äãªæ¨ï 1 - ç⥨¥ ¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 2 - ᮧ¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« |
* ¯®¤äãªæ¨ï 5 - ¯®«ã票¥ âਡã⮢ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 6 - ãáâ ®¢ª âਡã⮢ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë |
«ï CD-¯à¨¢®¤®¢ ¢ á¢ï§¨ á ¯¯ à â묨 ®£à ¨ç¥¨ï¬¨ ¤®áâã¯ë |
⮫쪮 ¯®¤äãªæ¨¨ 0,1,5 ¨ 7, ¢ë§®¢ ¤àã£¨å ¯®¤äãªæ¨© § ¢¥àè¨âáï |
®è¨¡ª®© á ª®¤®¬ 2. |
====================================================================== |
= ãªæ¨ï 70, ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬¸. = |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 0 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®§¨æ¨ï ¢ ä ©«¥ (¢ ¡ ©â å) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ® ¯®¤ áâ à訩 dword ¯®§¨æ¨¨) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ç¨â âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® ¯à®ç¨â ëå ¡ ©â ¨«¨ |
-1=0xffffffff, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* ᫨ ä ©« ª®ç¨«áï à ìè¥, 祬 ¡ë« ¯à®ç¨â ¯®á«¥¤¨© § ¯à®è¥ë© |
¡«®ª, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥à¸â |
eax=6 (EOF). |
* ãªæ¨ï ¥ ¯®§¢®«ï¥â ç¨â âì ¯ ¯ª¨ |
(¢¥à¸âáï eax=10, access denied). |
====================================================================== |
= ãªæ¨ï 70, ¯®¤äãªæ¨ï 1 - ç⥨¥ ¯ ¯ª¨ á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬¸. = |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 1 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨¤¥ªá ç «ì®£® ¡«®ª (áç¨â ï á 0) |
* +8: dword: ¯®«¥ ä« £®¢: |
* ¡¨â 0 (¬ ᪠1): ¢ ª ª®¬ ä®à¬ ⥠¢®§¢à é âì ¨¬¥ , |
0=ANSI, 1=UNICODE |
* ¯à®ç¨¥ ¡¨âë § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®á⨠|
* +12 = +0xC: dword: ᪮«ìª® ¡«®ª®¢ ç¨â âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë |
¤ ë¥, à §¬¥à ¡ãä¥à ¤®«¦¥ ¡ëâì ¥ ¬¥ìè¥ 32 + [+12]*560 ¡ ©â |
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® ä ©«®¢, ¨ä®à¬ æ¨ï ® ª®â®àëå ¡ë« § ¯¨á ¢ ¡ãä¥à, |
¨«¨ -1=0xffffffff, ¥á«¨ ¯ ¯ª ¥ ©¤¥ |
âàãªâãà ¡ãä¥à : |
* +0: 32*byte: § £®«®¢®ª |
* +32 = +0x20: n1*byte: ¡«®ª á ¨ä®à¬ 樥© ® ä ©«¥ 1 |
* +32+n1: n2*byte: ¡«®ª á ¨ä®à¬ 樥© ® ä ©«¥ 2 |
* ... |
âàãªâãà § £®«®¢ª : |
* +0: dword: ¢¥àá¨ï áâàãªâãàë (⥪ãé ï ¢¥àá¨ï = 1) |
* +4: dword: ª®«¨ç¥á⢮ à §¬¥é¸ëå ¡«®ª®¢; ¥ ¡®«ìè¥, 祬 § ¯à®è¥® |
¢ ¯®«¥ +12 ¨ä®à¬ 樮®© áâàãªâãàë; ¬®¦¥â ¡ëâì ¬¥ìè¥, |
¥á«¨ ¢ ¯ ¯ª¥ ª®ç¨«¨áì ä ©«ë (â® ¦¥ á ¬®¥, çâ® ¨ ¢ ebx) |
* +8: dword: ®¡é¥¥ ç¨á«® ä ©«®¢ ¢ ¯ ¯ª¥ |
* +12 = +0xC: 20*byte: § १¥à¢¨à®¢ ® (㫨) |
âàãªâãà ¡«®ª ¤ ëå ¢å®¤ ª â «®£ (): |
* +0: dword: âਡãâë ä ©« : |
* ¡¨â 0 (¬ ᪠1): ä ©« ⮫쪮 ¤«ï ç⥨ï |
* ¡¨â 1 (¬ ᪠2): ä ©« ï¥âáï áªàëâë¬ |
* ¡¨â 2 (¬ ᪠4): ä ©« ï¥âáï á¨áâ¥¬ë¬ |
* ¡¨â 3 (¬ ᪠8): íâ® ¥ ä ©«, ¬¥âª ⮬ |
( § ¤ ®¬ à §¤¥«¥ ¢áâà¥ç ¥âáï ¥ ¡®«¥¥ ®¤®£® à § ¨ |
⮫쪮 ¢ ª®à¥¢®© ¯ ¯ª¥) |
* ¡¨â 4 (¬ ᪠0x10): íâ® ¯ ¯ª |
* ¡¨â 5 (¬ ᪠0x20): ä ©« ¥ à娢¨à®¢ «áï - ¬®£¨¥ ¯à®£à ¬¬ë |
à娢 樨 ¨¬¥îâ ®¯æ¨î, ¯® ª®â®à®© à娢¨àãîâáï ⮫쪮 ä ©«ë |
á ãáâ ®¢«¥ë¬ í⨬ ¡¨â®¬, ¯®á«¥ 祣® íâ®â ¡¨â á¡à áë¢ ¥âáï - |
íâ® ¬®¦¥â ¡ëâì ¯®«¥§® ¤«ï ¢â®¬ â¨ç¥áª®£® ᮧ¤ ¨ï |
backup- à娢®¢, ¨¡® ¯à¨ § ¯¨á¨ ¡¨â ®¡ëç® ãáâ ¢«¨¢ ¥âáï |
(¥ ¢ Kolibri, ¯à ¢¤ ) |
* +4: byte: ⨯ ¤ ëå ¨¬¥¨: |
(ᮢ¯ ¤ ¥â á ¡¨â®¬ 0 ä« £®¢ ¨ä®à¬ 樮®© áâàãªâãàë) |
* 0 = ASCII = 1-¡ ©â®¥ ¯à¥¤áâ ¢«¥¨¥ ª ¦¤®£® ᨬ¢®« |
* 1 = UNICODE = 2-¡ ©â®¥ ¯à¥¤áâ ¢«¥¨¥ ª ¦¤®£® ᨬ¢®« |
* +5: 3*byte: § १¥à¢¨à®¢ ® (㫨) |
* +8: 4*byte: ¢à¥¬ï ᮧ¤ ¨ï ä ©« |
* +12 = +0xC: 4*byte: ¤ â ᮧ¤ ¨ï ä ©« |
* +16 = +0x10: 4*byte: ¢à¥¬ï ¯®á«¥¤¥£® ¤®áâ㯠(ç⥨¥ ¨«¨ § ¯¨áì) |
* +20 = +0x14: 4*byte: ¤ â ¯®á«¥¤¥£® ¤®áâ㯠|
* +24 = +0x18: 4*byte: ¢à¥¬ï ¯®á«¥¤¥© ¬®¤¨ä¨ª 樨 |
* +28 = +0x1C: 4*byte: ¤ â ¯®á«¥¤¥© ¬®¤¨ä¨ª 樨 |
* +32 = +0x20: qword: à §¬¥à ä ©« ¢ ¡ ©â å (¤® 16777216 ¡) |
* +40 = +0x28: ¨¬ï |
* ¤«ï ä®à¬ â ASCII: ¬ ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ 263 ᨬ¢®« |
(263 ¡ ©â ), ¡ ©â ¯®á«¥ ¨¬¥¨ ¨¬¥¥â § 票¥ 0 |
* ¤«ï ä®à¬ â UNICODE: ¬ ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ 259 ᨬ¢®«®¢ |
(518 ¡ ©â), ¤¢ ¡ ©â ¯®á«¥ ¨¬¥¨ ¨¬¥îâ § 票¥ 0 |
®à¬ ⠢६¥¨: |
* +0: byte: ᥪã¤ë |
* +1: byte: ¬¨ãâë |
* +2: byte: ç áë |
* +3: byte: § १¥à¢¨à®¢ ® (0) |
* ¯à¨¬¥à, 23.59.59 § ¯¨áë¢ ¥âáï ª ª (¢ hex) 3B 3B 17 00 |
®à¬ â ¤ âë: |
* +0: byte: ¤¥ì |
* +1: byte: ¬¥áïæ |
* +2: word: £®¤ |
* ¯à¨¬¥à, 25.11.1979 § ¯¨áë¢ ¥âáï ª ª (¢ hex) 19 0B BB 07 |
¬¥ç ¨ï: |
* ᫨ ¢ ¯à¨áãâáâ¢ã¥â ¨¬ï ¢ ASCII, â® ¤«¨ á®áâ ¢«ï¥â |
304 ¡ ©â , ¥á«¨ ¢ UNICODE - 560 ¡ ©â. 票¥ ¤«¨ë ¢ëà ¢¥® |
楫®¥ ªà ⮥ 16 ¡ ©â |
(¤«ï ãáª®à¥¨ï ®¡à ¡®âª¨ ¢ ªíè-¯ ¬ï⨠CPU). |
* ¥à¢ë© ᨬ¢®« ¯®á«¥ ¨¬¥¨ ã«¥¢®© (ASCIIZ-áâப ). «ì¥©è¨¥ |
¤ ë¥ á®¤¥à¦ â ¬ãá®à. |
* ᫨ ä ©«ë ¢ ¯ ¯ª¥ ª®ç¨«¨áì à ìè¥, 祬 ¡ë«® ¯à®ç¨â ® |
§ ¯à®è¥®¥ ª®«¨ç¥á⢮, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, |
¯®á«¥ 祣® ¢¥à¸â eax=6 (EOF). |
* î¡ ï ¯ ¯ª ¤¨áª¥, ªà®¬¥ ª®à¥¢®©, ᮤ¥à¦¨â ¤¢ á¯¥æ¨ «ìëå |
¢å®¤ "." ¨ "..", ¨¤¥â¨ä¨æ¨àãîé¨å ᮮ⢥âá⢥® á ¬ã ¯ ¯ªã ¨ |
த¨â¥«ìáªãî ¯ ¯ªã. |
* ãªæ¨ï ¯®§¢®«ï¥â â ª¦¥ ç¨â âì ¢¨àâã «ìë¥ ¯ ¯ª¨ "/", "/rd", |
"/fd", "/hd[n]", ¯à¨ í⮬ âਡãâë ¯®¤¯ ¯®ª ¯®« £ îâáï à ¢ë¬¨ |
0x10, ¢à¥¬¥ ¨ ¤ âë ®¡ã«¥ë. «ìâ¥à â¨¢ë© á¯®á®¡ ¯®«ã票ï |
¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ - ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18. |
====================================================================== |
====================== ãªæ¨ï 70, ¯®¤äãªæ¨ï 2 ====================== |
======== ®§¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬¸. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 2 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0) |
¬¥ç ¨ï: |
* ᫨ ä ©« á â ª¨¬ ¨¬¥¥¬ ¥ áãé¥á⢮¢ «, ® ᮧ¤ ¸âáï; ¥á«¨ |
áãé¥á⢮¢ «, â® ¯¥à¥§ ¯¨áë¢ ¥âáï. |
* ᫨ ᢮¡®¤®£® ¬¥áâ ¤¨áª¥ ¥¤®áâ â®ç®, â® äãªæ¨ï § ¯¨è¥â, |
᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥à¸â ª®¤ ®è¨¡ª¨ 8. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à¸âáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
=== ãªæ¨ï 70, ¯®¤äãªæ¨ï 5 - ¯®«ã票¥ ¨ä®à¬ 樨 ® ä ©«¥/¯ ¯ª¥. === |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 5 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
(40 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
ä®à¬ æ¨ï ® ä ©«¥ ¢®§¢à é ¥âáï ¢ ä®à¬ ⥠|
(¡«®ª ¤ ëå ¢å®¤ ª â «®£ ), 㪠§ ®¬ ¢ ®¯¨á ¨¨ |
¯®¤äãªæ¨¨ 1, ® ¡¥§ ¨¬¥¨ ä ©« |
(â® ¥áâì ¯¥à¢ë¥ 40 = 0x28 ¡ ©â). |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ìë¥ ¯ ¯ª¨ ⨯ /, /rd ¨ |
ª®à¥¢ë¥ ¯ ¯ª¨ ⨯ /rd/1. |
====================================================================== |
===== ãªæ¨ï 70, ¯®¤äãªæ¨ï 6 - ãáâ ®¢ª âਡã⮢ ä ©« /¯ ¯ª¨. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 6 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à á âਡãâ ¬¨ (32 ¡ ©â ) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
âਡãâë ä ©« - ¯¥à¢ë¥ 32 ¡ ©â ¢ (¡«®ª¥ ¤ ëå ¢å®¤ ª â «®£ ), |
ä®à¬ â ª®â®à®£® 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 1 |
(â® ¥áâì ¡¥§ ¨¬¥¨ ¨ à §¬¥à ä ©« ). âਡãâ ä ©«/¯ ¯ª /¬¥âª ⮬ |
(¡¨âë 3,4 ¢ dword'¥ +0) ¥ ¬¥ï¥âáï. |
©â +4 (ä®à¬ â ¨¬¥¨) ¨£®à¨àã¥âáï. |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ìë¥ ¯ ¯ª¨ ⨯ /, /rd ¨ |
ª®à¥¢ë¥ ¯ ¯ª¨ ⨯ /rd/1. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à¸âáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
============ ãªæ¨ï 70, ¯®¤äãªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 7 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®«¥ ä« £®¢: |
* ¡¨â 0: § ¯ãáâ¨âì ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© |
* ®áâ «ìë¥ ¡¨âë § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
* +8: dword: 0 ¨«¨ 㪠§ ⥫ì ASCIIZ-áâபã á ¯ à ¬¥âà ¬¨ |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬¸ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax > 0 - ¯à®£à ¬¬ § £à㦥 , eax ᮤ¥à¦¨â PID |
* eax < 0 - ¯à®¨§®è« ®è¨¡ª , -eax ᮤ¥à¦¨â |
ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ®¬ ¤ ï áâப ¤®«¦ § ª 稢 âìáï ᨬ¢®«®¬ á ª®¤®¬ 0 |
(ASCIIZ-áâப ); ãç¨âë¢ îâáï «¨¡® ¢á¥ ᨬ¢®«ë ¤® § ¢¥àè î饣® ã«ï |
¢ª«îç¨â¥«ì®, «¨¡® ¯¥à¢ë¥ 256 ᨬ¢®«®¢, ¢ § ¢¨á¨¬®á⨠®â ⮣®, |
çâ® ¬¥ìè¥. |
* ᫨ ¯à®æ¥áá § ¯ã᪠¥âáï ª ª ®â« ¦¨¢ ¥¬ë©, ® ᮧ¤ ¸âáï |
¢ § ¬®à®¦¥®¬ á®áâ®ï¨¨; ¤«ï § ¯ã᪠¨á¯®«ì§ã©â¥ |
¯®¤äãªæ¨î 5 äãªæ¨¨ 69. |
====================================================================== |
=== ãªæ¨ï 71, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì § £®«®¢®ª ®ª ¯à®£à ¬¬ë. == |
====================================================================== |
à ¬¥âàë: |
* eax = 71 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤à¥á áâப¨ § £®«®¢ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* âப § £®«®¢ª ¤®«¦ ¡ëâì ¢ ä®à¬ ⥠ASCIIZ. § £®«®¢ª¥ |
®â®¡à ¦ ¥âáï ¥ ¡®«¥¥ 255 ᨬ¢®«®¢ ¥§ ¢¨á¨¬® ®â ¯®«®© ¤«¨ë |
áâப¨. |
* ⮡ë ã¡à âì § £®«®¢®ª, ¯¥à¥¤ ©â¥ NULL ¢ ecx. |
====================================================================== |
========== ãªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«¥¨¥ ¯®â®ª /¯à®æ¥áá ========= |
====================================================================== |
à ¬¥âàë: |
* eax = -1 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â ¨ § 票ï, ¨ ã¯à ¢«¥¨ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá  ¥ ᮧ¤ ¢ « ¯®â®ª®¢, â® ã ¥£® ¥áâì ⮫쪮 |
®¤¨ ¯®â®ª, § ¢¥à襨¥ ª®â®à®£® ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* ᫨ ⥪ã騩 ¯®â®ª - ¯®á«¥¤¨© ¢ ¯à®æ¥áá¥, â® ¥£® § ¢¥à襨¥ |
â ª¦¥ ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* â äãªæ¨ï § ¢¥àè ¥â ⥪ã騩 ¯®â®ª. à㣮© ¯®â®ª ¬®¦® ¯à¨¡¨âì |
¢ë§®¢®¬ ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18. |
====================================================================== |
=========================== ¯¨á®ª ᮡë⨩ =========================== |
====================================================================== |
ç¥à¥¤®¥ ᮡë⨥ ¬®¦® ¯®«ãç¨âì ¢ë§®¢®¬ ®¤®© ¨§ äãªæ¨© 10 |
(®¦¨¤ âì ᮡëâ¨ï), 11 (¯à®¢¥à¨âì ¡¥§ ®¦¨¤ ¨ï), 23 |
(®¦¨¤ âì ¢ â¥ç¥¨¥ § ¤ ®£® ¢à¥¬¥¨). |
⨠äãªæ¨¨ ¢®§¢à é îâ ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î íâ® ¯¥à¢ë¥ âà¨, 祣® |
¢¯®«¥ ¤®áâ â®ç® ¤«ï ¬®£¨å ¯à¨«®¦¥¨©. |
®¤ë ᮡë⨩: |
* 1 = á®®¡é¥¨¥ ® ¯¥à¥à¨á®¢ª¥ (á¡à áë¢ ¥âáï ¯à¨ ¢ë§®¢¥ äãªæ¨¨ 0) |
* 2 = ¦ â ª« ¢¨è ª« ¢¨ âãॠ(¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® |
ªâ¨¢®) ¨«¨ ¦ â "£®àïç ï ª« ¢¨è "; |
á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ ª« ¢¨è¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 2 |
* 3 = ¦ â ª®¯ª , ®¯à¥¤¥«¸ ï à ¥¥ äãªæ¨¥© 8 (¨«¨ ª®¯ª |
§ ªàëâ¨ï, ᮧ¤ ï ¥ï¢® äãªæ¨¥© 0; ª®¯ª ¬¨¨¬¨§ 樨 |
®¡à ¡ âë¢ ¥âáï á¨á⥬®© ¨ ® ¥© á®®¡é¥¨ï ¥ ¯à¨å®¤¨â; |
¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® ªâ¨¢®; á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ |
ª®¯ª¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 17) |
* 4 = § १¥à¢¨à®¢ ® (¢ ⥪ã饩 ॠ«¨§ 樨 ¨ª®£¤ ¥ ¯à¨å®¤¨â ¤ ¦¥ |
¯à¨ à §¬ ᪨஢ª¥ äãªæ¨¥© 40) |
* 5 = ¯¥à¥à¨á®¢ë¢ ¥âáï ä® à ¡®ç¥£® á⮫ (á¡à áë¢ ¥âáï |
¢â®¬ â¨ç¥áª¨ ¯®á«¥ ¯¥à¥à¨á®¢ª¨, â ª çâ® ¥á«¨ ¢® ¢à¥¬ï ¯¥à¥à¨á®¢ª¨ |
ä® ¯à®£à ¬¬ ¥ ¦¤¸â ¨ ¥ ¯à®¢¥àï¥â ᮡëâ¨ï, â® í⮣® ᮡëâ¨ï |
® ¥ § ¬¥â¨â) |
* 6 = ᮡë⨥ ®â ¬ëè¨ (çâ®-â® á«ã稫®áì - ¦ ⨥ ª®¯ªã ¬ëè¨ |
¨«¨ ¯¥à¥¬¥é¥¨¥; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 7 = ¯à®¨§®è«® ᮡë⨥ IPC (ᬮâਠäãªæ¨î 60 - Inter Process |
Communication; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 8 = ¯à®¨§®è«® á¥â¥¢®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâà¨ à ¡®âã á á¥âìî) |
* 9 = ¯à®¨§®è«® ®â« ¤®ç®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâਠ®â« ¤®çãî ¯®¤á¨á⥬ã) |
* 16..31 = ¯à®¨§®è«® ᮡë⨥ á ᮮ⢥âáâ¢ãî騬 IRQ |
(16=IRQ0, 31=IRQ15) (á¡à áë¢ ¥âáï ¯à¨ áç¨âë¢ ¨¨ ¢á¥å ¤ ëå IRQ) |
====================================================================== |
==================== ®¤ë ®è¨¡®ª ä ©«®¢®© á¨á⥬ë ==================== |
====================================================================== |
* 0 = ãá¯¥è® |
* 1 = ¥ ®¯à¥¤¥«¥ ¡ § ¨/¨«¨ à §¤¥« ¦¸á⪮£® ¤¨áª (¯®¤äãªæ¨ï¬¨ |
7, 8 äãªæ¨¨ 21) |
* 2 = äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï ¤ ®© ä ©«®¢®© á¨á⥬ë |
* 3 = ¥¨§¢¥áâ ï ä ©«®¢ ï á¨á⥬ |
* 4 = ¢®§¢à é ¥âáï ⮫쪮 äãªæ¨¥© rename ¯à¨ ¯¥à¥¤ ç¥ á¨«ì® |
¥¢¥à®£® ¯ à ¬¥âà ¨ ¨ª ª ¥ ᮮ⢥âáâ¢ã¥â ®¯¨á ¨î |
¢ ¨á室¨ª å ï¤à "partition not defined at hd" |
* 5 = ä ©« ¥ ©¤¥ |
* 6 = ä ©« § ª®ç¨«áï |
* 7 = 㪠§ â¥«ì ¢¥ ¯ ¬ï⨠¯à¨«®¦¥¨ï |
* 8 = ¤¨áª § ¯®«¥ |
* 9 = â ¡«¨æ FAT à §àãè¥ |
* 10 = ¤®áâ㯠§ ¯à¥é¸ |
* 11 = ®è¨¡ª ãáâனá⢠|
ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª: |
* 30 = 0x1E = ¥¤®áâ â®ç® ¯ ¬ï⨠|
* 31 = 0x1F = ä ©« ¥ ï¥âáï ¨á¯®«¨¬ë¬ |
* 32 = 0x20 = ᫨誮¬ ¬®£® ¯à®æ¥áᮢ |
/kernel/branches/gfx_kernel/docs/sysfuncs.txt |
---|
0,0 → 1,4423 |
SYSTEM FUNCTIONS of OS Kolibri 0.5.8.1 |
Number of the function is located in the register eax. |
The call of the system function is executed by "int 0x40" command. |
All registers except explicitly declared in the returned value, |
including eflags, are preserved. |
====================================================================== |
============== Function 0 - define and draw the window. ============== |
====================================================================== |
Defines an application window. Draws a frame of the window, header and |
working area. For windows with skin defines standard buttons for close |
and minimize. |
Parameters: |
* eax = 0 - function number |
* ebx = [coordinate on axis x]*65536 + [size on axis x] |
* ecx = [coordinate on axis y]*65536 + [size on axis y] |
* edx = 0xXYRRGGBB, where: |
* Y = style of the window: |
* Y=0 - type I - window of the fixed size |
* Y=1 - only define window area, draw nothing |
* Y=2 - type II - window of the variable size |
* Y=3 - window with skin |
* other possible values (from 4 up to 15) are reserved, |
function call with such Y is ignored |
* RR, GG, BB = accordingly red, green, blue components of a color |
of the working area of the window (are ignored for style Y=2) |
* X = DCBA (bits) |
* A = 1 - window has caption; for style Y=3 caption string |
must be passed in edi, for other styles use |
subfunction 1 of function 71 |
* B = 1 - coordinates of all graphics primitives are relative to |
window client area |
* C is reserved (set to 0) |
* D = 0 - normal filling of the working area, 1 - gradient |
The following parameters are intended for windows |
of a type I and II, and ignored for styles Y=1,3: |
* esi = 0xXYRRGGBB - color of the header |
* RR, GG, BB define color |
* Y=0 - usual window, Y=1 - unmovable window |
* X defines a gradient of header: X=0 - no gradient, |
X=8 - usual gradient, |
for windows of a type II X=4 - negative gradient |
* other values of X and Y are reserved |
* edi = 0x00RRGGBB - color of the frame |
Returned value: |
* function does not return value |
Remarks: |
* Position and sizes of the window are installed by the first |
call of this function and are ignored at subsequent; to change |
position and/or sizes of already created window use function 67. |
* For windows with style Y=3 and caption (A=1) caption string is set |
by the first call of this function and is ignored at subsequent |
(strictly speaking, is ignored after a call to subfunction 2 |
of function 12 - end redraw); to change caption of already created |
window use subfunction 1 of function 71. |
* If the window has appropriate styles, position and/or sizes can be |
changed by user. Current position and sizes can be obtained |
by function 9. |
* The window must fit on the screen. If the transferred |
coordinates and sizes do not satisfy to this condition, |
appropriate coordinate (or, probably, both) is considered as zero, |
and if also it does not help, the appropriate size |
(or, probably, both) is installed in a size of the screen. |
Further we shall designate xpos,ypos,xsize,ysize - values |
transmitted in ebx,ecx. The coordinates are resulted concerning |
the left upper corner of the window, which, thus, is set as (0,0), |
coordinates of the right lower corner essence (xsize,ysize). |
* The sizes of the window are understood in sence of coordinates |
of the right lower corner. This concerns all other functions too. |
It means, that the real sizes are on 1 pixel more. |
* The window of type I looks as follows: |
* draw external frame of color indicated in edi, 1 pixel in width |
* draw header - rectangle with the left upper corner (1,1) and |
right lower (xsize-1,min(25,ysize)) color indicated in esi |
(taking a gradient into account) |
* if ysize>=26, fill the working area of the window - |
rectangle with the left upper corner (1,21) and right lower |
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color |
indicated in edx (taking a gradient into account) |
* if A=1 and caption has been already set by subfunction 1 |
of function 71, it is drawn in the corresponding place of header |
* The window of style Y=1 looks as follows: |
* completely defined by the application |
* The window of type II looks as follows: |
* draw external frame of width 1 pixel with the "shaded" color |
edi (all components of the color decrease twice) |
* draw intermediate frame of width 3 pixels with color edi |
* draw internal frame of width 1 pixel with the "shaded" color edi |
* draw header - rectangle with the left upper corner (4,4) |
and right lower (xsize-4,min(20,ysize)) color, indicated in esi |
(taking a gradient into account) |
* if ysize>=26, fill the working area of the window - |
rectangle with the left upper corner (5,20) and right lower |
(xsize-5,ysize-5) with color indicated in edx |
(taking a gradient into account) |
* if A=1 and caption has been already set by subfunction 1 |
of function 71, it is drawn in the corresponding place of header |
* The skinned window looks as follows: |
* draw external frame of width 1 pixel |
with color 'outer' from the skin |
* draw intermediate frame of width 3 pixel |
with color 'frame' from the skin |
* draw internal frame of width 1 pixel |
with color 'inner' from the skin |
* draw header (on bitmaps from the skin) in a rectangle |
(0,0) - (xsize,_skinh-1) |
* if ysize>=26, fill the working area of the window - |
rectangle with the left upper corner (5,_skinh) and right lower |
(xsize-5,ysize-5) with color indicated in edx |
(taking a gradient into account) |
* define two standard buttons: for close and minimize |
(see function 8) |
* if A=1 and edi contains (nonzero) pointer to caption string, |
it is drawn in place in header defined in the skin |
* value _skinh is accessible as the result of call |
subfunction 4 of function 48 |
====================================================================== |
================ Function 1 - put pixel in the window. =============== |
====================================================================== |
Parameters: |
* eax = 1 - function number |
* ebx = x-coordinate (relative to the window) |
* ecx = y-coordinate (relative to the window) |
* edx = 0x00RRGGBB - color of a pixel |
edx = 0x01xxxxxx - invert color of a pixel |
(low 24 bits are ignored) |
Returned value: |
* function does not return value |
====================================================================== |
============ Function 2 - get the code of the pressed key. =========== |
====================================================================== |
Takes away the code of the pressed key from the buffer. |
Parameters: |
* eax = 2 - function number |
Returned value: |
* if the buffer is empty, function returns eax=1 |
* if the buffer is not empty, function returns al=0, |
ah=code of the pressed key, high word of eax is zero |
* if there is "hotkey", function returns al=2, |
ah=scancode of the pressed key (0 for control keys), |
high word of eax contains a status of control keys at the moment |
of pressing a hotkey |
Remarks: |
* There is a common system buffer of the pressed keys |
by a size of 120 bytes, organized as queue. |
* There is one more common system buffer on 120 "hotkeys". |
* If the application with the inactive window calls this function, |
the buffer of the pressed keys is considered to be empty. |
* By default this function returns ASCII-codes; to switch |
to the scancodes mode (and back) use function 66. |
However, hotkeys are always notificated as scancodes. |
* To find out, what keys correspond to what codes, start |
the application keyascii and scancode. |
* Scancodes come directly from keyboard and are fixed; |
ASCII-codes turn out with usage of the conversion tables, |
which can be set by subfunction 2 of function 21 |
and get by subfunction 2 of function 26. |
* As a consequence, ASCII-codes take into account current |
keyboard layout (rus/en) as opposed to scancodes. |
* This function notifies only about those hotkeys, which were |
defined by this thread by subfunction 4 of function 66. |
====================================================================== |
==================== Function 3 - get system time. =================== |
====================================================================== |
Parameters: |
* eax = 3 - function number |
Returned value: |
* eax = 0x00SSMMHH, where HH:MM:SS = Hours:Minutes:Seconds |
* each item is BCD-number, for example, |
for time 23:59:59 function returns 0x00595923 |
Remarks: |
* See also subfunction 9 of function 26 - get time from |
the moment of start of the system; it is more convenient, because |
returns simply DWORD-value of the time counter. |
* System time can be set by function 22. |
====================================================================== |
============ Function 4 - draw text string in the window. ============ |
====================================================================== |
Parameters: |
* eax = 4 - function number |
* ebx = [coordinate on axis x]*65536 + [coordinate on axis y] |
* ecx = 0xX0RRGGBB, where |
* RR, GG, BB specify text color |
* X specifies the used font: 0=system monospaced, |
1=system font of variable width |
* edx = pointer to the beginning of the string |
* esi = length of the string, must not exceed 255 |
Returned value: |
* function does not return value |
Remarks: |
* Function outputs either first (esi and 0xFF) characters or |
all characters before (but not including) terminating zero |
(for ASCIIZ-strings) depending on what occurs first. |
* First system font is read out at loading from the file char.mt, |
second - from char2.mt. |
* Both fonts have height 9 pixels, width of the monospaced font |
is equal to 6 pixels. |
====================================================================== |
========================= Function 5 - delay. ======================== |
====================================================================== |
Delays execution of the program on the given time. |
Parameters: |
* eax = 5 - function number |
* ebx = time in the 1/100 of second |
Returned value: |
* function does not return value |
Remarks: |
* Passing ebx=0 does not transfer control to the next process |
and does not make any operations at all. If it is really required |
to transfer control to the next process (to complete a current |
time slice), use subfunction 1 of function 68. |
* At current implementation there will be an immediate return from |
the function, if the addition of ebx with current value of |
time counter will call 32-bit overflow. |
====================================================================== |
============== Function 6 - read the file from ramdisk. ============== |
====================================================================== |
Parameters: |
* eax = 6 - function number |
* ebx = pointer to the filename |
* ecx = number of start block, beginning from 1; |
ecx=0 - read from the beginning of the file (same as ecx=1) |
* edx = number of blocks to read; |
edx=0 - read one block (same as edx=1) |
* esi = pointer to memory area for the data |
Returned value: |
* eax = file size in bytes, if the file was successfully read |
* eax = -1, if the file was not found |
Remarks: |
* This function is out-of-date; function 70 allows |
to fulfil the same operations with the extended possibilities. |
* Block = 512 bytes. |
* For reading all file you can specify the certainly large value |
in edx, for example, edx = -1; but in this case be ready that |
the program will "fall", if the file will appear too large and can |
not be placed in the program memory. |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
=============== Function 7 - draw image in the window. =============== |
====================================================================== |
Paramters: |
* eax = 7 - function number |
* ebx = pointer to the image in the format BBGGRRBBGGRR... |
* ecx = [size on axis x]*65536 + [size on axis y] |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates of the image are coordinates of the upper left corner |
of the image relative to the window. |
* Size of the image in bytes is 3*xsize*ysize. |
====================================================================== |
=============== Function 8 - define/delete the button. =============== |
====================================================================== |
Parameters for button definition: |
* eax = 8 - function number |
* ebx = [coordinate on axis x]*65536 + [size on axis x] |
* ecx = [coordinate on axis y]*65536 + [size on axis y] |
* edx = 0xXYnnnnnn, where: |
* nnnnnn = identifier of the button |
* high (31st) bit of edx is cleared |
* if 30th bit of edx is set - do not draw the button |
* if 29th bit of edx is set - do not draw a frame |
at pressing the button |
* esi = 0x00RRGGBB - color of the button |
Parameters for button deleting: |
* eax = 8 - function number |
* edx = 0x80nnnnnn, where nnnnnn - identifier of the button |
Returned value: |
* function does not return value |
Remarks: |
* Sizes of the button must be more than 0 and less than 0x8000. |
* For windows with skin definition of the window |
(call of 0th function) creates two standard buttons - |
for close of the window with identifier 1 and |
for minimize of the window with identifier 0xffff. |
* The creation of two buttons with same identifiers is admitted. |
* The button with the identifier 0xffff at pressing is interpreted |
by the system as the button of minimization, the system handles |
such pressing independently, not accessing to the application. |
In rest it is usual button. |
* Total number of buttons for all applications is limited to 4095. |
====================================================================== |
============ Function 9 - information on execution thread. =========== |
====================================================================== |
Parameters: |
* eax = 9 - function number |
* ebx = pointer to 1-Kb buffer |
* ecx = number of the slot of the thread |
ecx = -1 - get information on the current thread |
Returned value: |
* eax = maximum number of the slot of a thread |
* buffer pointed to by ebx contains the following information: |
* +0: dword: usage of the processor (how many time units |
per second leaves on execution of this thread) |
* +4: word: position of the window of thread in the window stack |
* +6: word: (has no relation to the specified thread) |
number of the thread slot, which window has in the window stack |
position ecx |
* +8: word: reserved |
* +10 = +0xA: 11 bytes: name of the process |
(name of corresponding executable file in the format 8+3) |
* +21 = +0x15: byte: alignment, this byte preserves |
* +22 = +0x16: dword: address of the process in memory |
* +26 = +0x1A: dword: size of used memory - 1 |
* +30 = +0x1E: dword: identifier (PID/TID) |
* +34 = +0x22: dword: coordinate of the thread window on axis x |
* +38 = +0x26: dword: coordinate of the thread window on axis y |
* +42 = +0x2A: dword: size of the thread window on axis x |
* +46 = +0x2E: dword: size of the thread window on axis y |
* +50 = +0x32: word: status of the thread slot: |
* 0 = thread is running |
* 1 = thread is suspended |
* 2 = thread is suspended while waiting for event |
* 3 = thread is terminating as a result of call to function -1 |
or under duress as a result of call to subfunction 2 |
of function 18 or termination of the system |
* 4 = thread is terminating as a result of exception |
* 5 = thread waits for event |
* 9 = requested slot is free, all other information on the slot |
is not meaningful |
Remarks: |
* Slots are numbered starting from 1. |
* Returned value is not a total number of threads, because there |
can be free slots. |
* When process is starting, system automatically creates |
execution thread. |
* Function gives information on the thread. Each process has |
at least one thread. One process can create many threads, |
in this case each thread has its own slot and the fields |
+10, +22, +26 in these slots coincide. |
Applications have no common way to define whether two threads |
belong to one process. |
* The active window - window on top of the window stack - |
receives the messages on a keyboard input. For such window |
the position in the window stack coincides with returned value. |
* Slot 1 corresponds to special system thread, for which: |
* the window is in the bottom of the window stack, the fields |
+4 and +6 contain value 1 |
* name of the process - "OS/IDLE" (supplemented by spaces) |
* address of the process in memory is 0, size of used memory is |
16 Mb (0x1000000) |
* PID=1 |
* coordinates and sizes of the window are by convention set to 0 |
* status of the slot is always 0 (running) |
* the execution time adds of time leaving on operations itself |
and idle time in waiting for interrupt (which can be got by call |
to subfunction 4 of function 18). |
* Beginning from slot 2, the normal applications are placed. |
* The normal applications are placed in memory at the address |
0x10000000 (kernel constand 'std_application_base_address'). |
There is no intersection, as each process has its own page table. |
* At creation of the thread it is assigned the slot |
in the system table and identifier (Process/Thread IDentifier = |
PID/TID), which do not vary with time for given thread. |
After completion of the thread its slot can be anew used |
for another thread. The thread identifier can not be assigned |
to other thread even after completion of this thread. |
Identifiers, assigned to new threads, grow monotonously. |
* If the thread has not yet defined the window by call to |
function 0, the position and the sizes |
of its window are considered to be zero. |
* At the moment only the part of the buffer by a size |
52 = 0x34 bytes is used. Nevertheless it is recommended to use |
1-Kb buffer for the future compatibility, in the future |
some fields can be added. |
====================================================================== |
==================== Function 10 - wait for event. =================== |
====================================================================== |
If the message queue is empty, waits for appearance of the message |
in queue. In this state thread does not consume CPU time. |
Then reads out the message from queue. |
Parameters: |
* eax = 10 - function number |
Returned value: |
* eax = event (see the list of events) |
Remarks: |
* Those events are taken into account only which enter into |
a mask set by function 40. By default it is |
redraw, key and button events. |
* To check, whether there is a message in queue, use function 11. |
To wait for no more than given time, use function 23. |
====================================================================== |
=============== Function 11 - check for event, no wait. ============== |
====================================================================== |
If the message queue contains event, function reads out |
and return it. If the queue is empty, function returns 0. |
Parameters: |
* eax = 11 - function number |
Returned value: |
* eax = 0 - message queue is empty |
* else eax = event (see the list of events) |
Remarks: |
* Those events are taken into account only, which enter into |
a mask set by function 40. By default it is |
redraw, key and button events. |
* To wait for event, use function 10. |
To wait for no more than given time, use function 23. |
====================================================================== |
=============== Function 12 - begin/end window redraw. =============== |
====================================================================== |
------------ Subfunction 1 - begin redraw of the window. ------------- |
Parameters: |
* eax = 12 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* function does not return value |
------------- Subfunction 2 - end redraw of the window. -------------- |
Parameters: |
* eax = 12 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* function does not return value |
Remarks: |
* Subfunction 1 deletes all buttons defined with |
function 8, they must be defined again. |
====================================================================== |
============ Function 13 - draw a rectangle in the window. =========== |
====================================================================== |
Parameters: |
* eax = 13 - function number |
* ebx = [coordinate on axis x]*65536 + [size on axis x] |
* ecx = [coordinate on axis y]*65536 + [size on axis y] |
* edx = color 0xRRGGBB or 0x80RRGGBB for gradient fill |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates are understood as coordinates of the left upper corner |
of a rectangle relative to the window. |
====================================================================== |
=================== Function 14 - get screen size. =================== |
====================================================================== |
Parameters: |
* eax = 14 - function number |
Returned value: |
* eax = [xsize]*65536 + [ysize], where |
* xsize = x-coordinate of the right lower corner of the screen = |
horizontal size - 1 |
* ysize = y-coordinate of the right lower corner of the screen = |
vertical size - 1 |
Remarks: |
* See also subfunction 5 of function 48 - get sizes of |
working area of the screen. |
====================================================================== |
== Function 15, subfunction 1 - set a size of the background image. == |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 1 - subfunction number |
* ecx = width of the image |
* edx = height of the image |
Returned value: |
* function does not return value |
Remarks: |
* There is no checks for correctness. The setting of too large |
values will result that the background will contain data abroad |
of buffer for the background image. Buffer size = 0x160000-0x10, |
that corresponds to maximum size 800*600. (800*600*3=0x15F900) |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get size of the background image - |
subfunction 1 of function 39. |
====================================================================== |
=== Function 15, subfunction 2 - put pixel on the background image. == |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 2 - subfunction number |
* ecx = offset |
* edx = color of a pixel 0xRRGGBB |
Returned value: |
* function does not return value |
Remarks: |
* Offset for a pixel with coordinates (x,y) is calculated as |
(x+y*xsize)*3. |
* If the given offset exceeds 0x160000-16 = 1.375 Mb - 16 bytes, |
the call is ignored. |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get pixel on the background image - |
subfunction 2 of function 39. |
====================================================================== |
=========== Function 15, subfunction 3 - redraw background. ========== |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* function does not return value |
====================================================================== |
== Function 15, subfunction 4 - set drawing mode for the background. = |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 4 - subfunction number |
* ecx = drawing mode: |
* 1 = tile |
* 2 = stretch |
Returned value: |
* function does not return value |
Remarks: |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get drawing mode of the background - |
subfunction 4 of function 39. |
====================================================================== |
===================== Function 15, subfunction 5 ===================== |
============ Put block of pixels on the background image. ============ |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 5 - subfunction number |
* ecx = pointer to the data in the format BBGGRRBBGGRR... |
* edx = offset in data of the background image |
* esi = size of data in bytes = 3 * number of pixels |
Returned value: |
* function does not return value |
Remarks: |
* If the block gets out abroad 0x160000-16 = 1.375 Mb - 16 bytes, |
the call is ignored. |
* Color of each pixel is stored as 3-bytes value BBGGRR. |
* Pixels of the background image are written sequentially |
from left to right, from up to down. |
* Offset of pixel with coordinates (x,y) is (x+y*xsize)*3. |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
====================================================================== |
=============== Function 16 - save ramdisk on a floppy. ============== |
====================================================================== |
Parameters: |
* eax = 16 - function number |
* ebx = 1 or ebx = 2 - on which floppy save |
Returned value: |
* eax = 0 - success |
* eax = 1 - error |
====================================================================== |
======= Function 17 - get the identifier of the pressed button. ====== |
====================================================================== |
Takes away the code of the pressed button from the buffer. |
Parameters: |
* eax = 17 - function number |
Returned value: |
* if the buffer is empty, function returns eax=1 |
* if the buffer is not empty, function returns al=0, |
high 24 bits of eax contain button identifier (in particular, ah |
contains low byte of the identifier; if all buttons have |
the identifier less than 256, ah is enough to distinguish). |
Remarks: |
* "Buffer" keeps only one button, at pressing the new button the |
information about old is lost. |
* The call of this function by an application with inactive window |
will return answer "buffer is empty". |
====================================================================== |
============ Function 18, subfunction 1 - system shutdown. =========== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* function always return eax = 0 as tag of success |
Remarks: |
* On the last step menu of exit from the system appears and waits |
response of the user. |
* See also subfunction 9, system shutdown with |
the parameter to force the choice in the exit menu. |
====================================================================== |
= Function 18, subfunction 2 - terminate process/thread by the slot. = |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 2 - subfunction number |
* ecx = number of the slot of process/thread |
Returned value: |
* function does not return value |
Remarks: |
* It is impossible to terminate system thread OS/IDLE (with |
number of the slot 1), |
it is possible to terminate any normal process/thread. |
* See also subfunction 18 - terminate |
process/thread by the identifier. |
====================================================================== |
===================== Function 18, subfunction 3 ===================== |
============= Make active the window of the given thread. ============ |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 3 - subfunction number |
* ecx = number of the thread slot |
Returned value: |
* function does not return value |
Remarks: |
* If correct, but nonexistent slot is given, |
some window is made active. |
* To find out, which window is active, use subfunction 7. |
====================================================================== |
===================== Function 18, subfunction 4 ===================== |
=========== Get counter of idle time units per one second. =========== |
====================================================================== |
Idle time units are units, in which the processor stands idle |
in waiting for interrupt (in the command 'hlt'). |
Parameters: |
* eax = 18 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = value of the counter of idle time units per one second |
====================================================================== |
========== Function 18, subfunction 5 - get CPU clock rate. ========== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 5 - subfunction number |
Returned value: |
* eax = clock rate (modulo 2^32 clock ticks = 4GHz) |
====================================================================== |
Function 18, subfunction 6 - save ramdisk to the file on hard drive. |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 6 - subfunction number |
* ecx defines path to the file: |
* 1 = in the folder "/KOLIBRI" |
* 2 = in the root folder |
* 3 = edx points to the path (names of folders in the format 8+3, |
divided by '/') |
Returned value: |
* eax = 0 - success |
* else eax = error code of the file system |
Çàìå÷àíèÿ: |
* Filename is fixed, "menuet.img" (global kernel variable |
'image_save' from 'preboot.inc') |
* Drive and partition are defined by subfunction 7 |
and subfunction 8 of function 21. |
* All folders in the given path must exist, otherwise function |
returns value 5, "file not found". |
====================================================================== |
=========== Function 18, subfunction 7 - get active window. ========== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = number of the active window |
(number of the slot of the thread with active window) |
Remarks: |
* Active window is at the top of the window stack and receives |
messages on all keyboard input. |
* To make a window active, use subfunction 3. |
====================================================================== |
== Function 18, subfunction 8 - disable/enable the internal speaker. = |
====================================================================== |
If speaker sound is disabled, all calls to subfunction 55 of |
function 55 are ignored. If speaker sound is enabled, |
they are routed on builtin speaker. |
------------------- Subsubfunction 1 - get status. ------------------- |
Parameters: |
* eax = 18 - function number |
* ebx = 8 - subfunction number |
* ecx = 1 - number of the subsubfunction |
Returned value: |
* eax = 0 - speaker sound is enabled; 1 - disabled |
----------------- Subsubfunction 2 - toggle status. ------------------ |
Toggles states of disable/enable. |
Parameters: |
* eax = 18 - function number |
* ebx = 8 - subfunction number |
* ecx = 2 - number of the subsubfunction |
Returned value: |
* function does not return value |
====================================================================== |
== Function 18, subfunction 9 - system shutdown with the parameter. == |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 9 - subfunction number |
* ecx = parameter: |
* 1 = on the last step of shutdown save ramdisk on a floppy and |
then show the exit menu and request further operations |
from the user |
* 2 = turn off computer |
* 3 = reboot computer |
* 4 = restart the kernel from the file 'kernel.mnt' on ramdisk |
Returned value: |
* at incorrect ecx the registers do not change (i.e. eax=18) |
* by correct call function always returns eax=0 |
as the tag of success |
Remarks: |
* Do not rely on returned value by incorrect call, it can be |
changed in future versions of the kernel. |
* It is possible to use subfunction 1, that on the last step |
the user makes choice himself. |
* It is not recommended to use value ecx=1 (to not irritate the user |
with excessive questions); to save ramdisk on a floppy use |
function 16 (which admits specification, on which floppy to |
write), and to shutdown with the exit menu use already mentioned |
subfunction 1. |
====================================================================== |
===== Function 18, subfunction 10 - minimize application window. ===== |
====================================================================== |
Minimizes the own window. |
Parameters: |
* eax = 18 - function number |
* ebx = 10 - subfunction number |
Returned value: |
* function does not return value |
Remarks: |
* The minimized window from the point of view of function 9 |
keeps position and sizes. |
* Restoring of an application window occurs at its activation by |
subfunction 3. |
* Usually there is no necessity to minimize/restire a window |
obviously: minimization of a window is carried out by the system |
at pressing the minimization button (for skinned windows |
it is defined automatically by function 0, |
for other windows it can be defined manually by function 8), |
restore of a window is done by the application '@panel'. |
====================================================================== |
Function 18, subfunction 11 - get information on the disk subsystem. |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 11 - subfunction number |
* ecx = type of the table: |
* 1 = short version, 10 bytes |
* 2 = full version, 65536 bytes |
* edx = pointer to the buffer (in the application) for the table |
Returned value: |
* function does not return value |
Format of the table: short version: |
* +0: byte: information about FDD's (drives for floppies), |
AAAABBBB, where AAAA gives type of the first drive, BBBB - |
of the second regarding to the following list: |
* 0 = there is no drive |
* 1 = 360Kb, 5.25'' |
* 2 = 1.2Mb, 5.25'' |
* 3 = 720Kb, 3.5'' |
* 4 = 1.44Mb, 3.5'' |
* 5 = 2.88Mb, 3.5'' (such drives are not used anymore) |
For example, for the standard configuration from one 1.44-drive |
here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B: |
the value is 24h. |
* +1: byte: information about hard disks and CD-drives, AABBCCDD, |
where AA corresponds to the controller IDE0, ..., DD - IDE3: |
* 0 = device is absent |
* 1 = hard drive |
* 2 = CD-drive |
For example, in the case HD on IDE0 and CD on IDE2 |
this field contains 48h. |
* +2: 4 db: number of the retrieved partitions on hard disks |
at accordingly IDE0,...,IDE3. |
If the hard disk on IDEx is absent, appropriate byte is zero, |
otherwise it shows number of the recognized partitions, which |
can be not presented (if the drive is not formatted or if |
the file system is not supported). Current version of the kernel |
supports only FAT16 and FAT32 for hard disks. |
* +6: 4 db: reserved |
Format of the table: full version: |
* +0: 10 db: same as for the short version |
* +10: 100 db: data for the first partition |
* +110: 100 db: data for the second partition |
* ... |
* +10+100*(n-1): 100 db: data for the last partition |
The partitions are located as follows: at first sequentially all |
recoginzed partitions on HD on IDE0 (if present), |
then on HD on IDE1 (if present) and so on up to IDE3. |
Format of the information about partition |
(at moment only FAT is supported): |
* +0: dword: first physical sector of the partition |
* +4: dword: last physical sector of the partition |
(belongs to the partition) |
* +8: dword: sectors per one copy of FAT |
* +12 = +0xC: dword: number of copies of FAT |
* +16 = +0x10: dword: number of sectors per cluster |
* +20 = +0x14: dword: bytes per sector; |
current implementation expects 0x200 = 512 in this field |
* +24 = +0x18: dword: first root cluster in FAT32, 0 for FAT16 |
* +28 = +0x1C: dword: first physical sector of FAT |
* +32 = +0x20: dword: first physical root sector for FAT16, |
ignored for FAT32 |
* +36 = +0x24: dword: number of root sectors for FAT16, |
0 for FAT32 |
* +40 = +0x28: dword: physical sector of the beginning of |
the data area |
* +44 = +0x2C: dword: maximum number of a cluster |
* +48 = +0x30: dword: physical sector of the information |
about the file system for FAT32, ignored for FAT16 |
* +52 = +0x34: dword: value used as boundary for special |
values in FAT |
* +56 = +0x38: dword: value used for bad clusters in FAT |
* +60 = +0x3C: dword: value used as the end marker for FAT chain |
* +64 = +0x40: dword: mask for FAT items |
* +68 = +0x44: byte: file system type: 16 èëè 32 |
* +69 = +0x45: 31 db: reserved |
Remarks: |
* The short table can be used for obtaining the information about |
available devices. |
* First two fields in the information about partition |
gives the parameters of partition, other - parameters of |
FAT file system. For other file systems (when they will be |
supported) specific for file system information will be, of |
course, another, but first two fields will have the same sense. |
====================================================================== |
========== Function 18, subfunction 13 - get kernel version. ========= |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 13 - subfunction number |
* ecx = pointer to the buffer (not less than 16 bytes), where |
the information will be placed |
Returned value: |
* function does not return value |
Structure of the buffer: |
db a,b,c,d for version a.b.c.d |
db UID_xxx: one of UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 |
db 'name',0 - ASCIIZ-string with the name |
For Kolibri 0.5.8.1 kernel: |
db 0,5,8,1 |
db 2 |
db 'Kolibri',0 |
====================================================================== |
======= Function 18, subfunction 14 - wait for screen retrace. ======= |
====================================================================== |
Waits for the beginning of retrace of the scanning ray of the screen |
monitor. |
Parameters: |
* eax = 18 - function number |
* ebx = 14 - subfunction number |
Returned value: |
* eax = 0 as the tag of success |
Remarks: |
* Function is intended only for active high-efficiency graphics |
applications; is used for smooth output of a graphics. |
====================================================================== |
== Function 18, subfunction 15 - center mouse cursor on the screen. == |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 15 - subfunction number |
Returned value: |
* eax = 0 as the tag of success |
====================================================================== |
========= Function 18, subfunction 16 - get size of free RAM. ======== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 16 - subfunction number |
Returned value: |
* eax = size of free memory in kilobytes |
====================================================================== |
======== Function 18, subfunction 17 - get full amount of RAM. ======= |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 17 - subfunction number |
Returned value: |
* eax = total size of existing memory in kilobytes |
====================================================================== |
===================== Function 18, subfunction 18 ==================== |
============= Terminate process/thread by the identifier. ============ |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 18 - subfunction number |
* ecx = identifer of process/thread (PID/TID) |
Returned value: |
* eax = 0 - success |
* eax = -1 - error (process is not found or is system) |
Remarks: |
* It is impossible to terminate system thread OS/IDLE (identifier |
1), it is possible to terminate any normal process/thread. |
* See also subfunction 2 - terminate |
process/thread by given slot. |
====================================================================== |
====================== Function 18, subfunction 19 ===================== |
======================= Get/set mouse features. ====================== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 19 - subfunction number |
* ecx = subsubfunction number |
ecx = 0 - get mouse speed |
Returned value: |
* eax = current mouse speed |
ecx = 1 - set mouse speed |
edx = selected value of speed |
Returned value: |
* function does not return value |
ecx = 2 - get mouse delay |
Returned value: |
* eax = current mouse delay |
ecx = 3 - set mouse delay |
edx = selected value of delay |
Returned value: |
* function does not return value |
ecx = 4 - set mouse pointer position |
edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
Returned value: |
* function does not return value |
Remarks: |
* Recommended speed of the mouse (in subfunction 1) from 1 up to 9. |
The installed value is not inspected by the code of a kernel, on this use |
cautiously, at incorrect value the cursor can "freeze". |
Speed of mouse can be regulated through the application SETUP. |
* Recommended delay of the mouse (in subfunction 3) = 10. Lower value |
is not handled COM by mice. At the very large values the movement of |
the mouse on 1 pixel is impossible and the cursor will jump |
on the value of the installed speed (subfunction 1). |
The installed value is not inspected by the code of a kernel. |
* In subfunction 4 the installed value is not inspected by |
the code of a kernel. Before usage it is necessary to find out current |
screen resolution and at installation of a position to watch, |
that the value of a position should do not fall outside |
the limits the screen. |
====================================================================== |
============ Function 19 - start application from ramdisk. =========== |
====================================================================== |
Parameters: |
* eax = 19 - function number |
* ebx = pointer to the application name in format similar |
to function 6 |
* ecx = 0 or ecx = pointer to command line parameters |
Returned value: |
* If eax > 0, then eax contains PID of the created process |
* If eax < 0, then -eax - file system error code |
Remarks: |
* This function is obsolete; use subfunction 7 of function 70. |
* Command line must be terminated by the character with the code 0 |
(ASCIIZ-string); function takes into account either all characters |
up to terminating zero inclusively or first 256 character |
regarding what is less. |
====================================================================== |
==================== Function 20 - MIDI interface. =================== |
====================================================================== |
----------------------- Subfunction 1 - reset ------------------------ |
Parameters: |
* eax = 20 - function number |
* ebx = 1 - subfunction number |
-------------------- Subfunction 2 - output byte --------------------- |
Parameters: |
* eax = 20 - function number |
* ebx = 2 - subfunction number |
* cl = byte for output |
Returned value (is the same for both subfunctions): |
* eax = 0 - success |
* eax = 1 - base port is not defined |
Remarks: |
* Previously the base port must be defined by |
subfunction 1 of function 21. |
====================================================================== |
======== Function 21, subfunction 1 - set MPU MIDI base port. ======== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 1 - subfunction number |
* ecx = number of base port |
Returned value |
* eax = 0 - success |
* eax = -1 - erratic number of a port |
Remarks: |
* Number of a port must satisfy to conditions 0x100<=ecx<=0xFFFF. |
* The installation of base is necessary for function 20. |
* To get base port use subfunction 1 of function 26. |
====================================================================== |
========== Function 21, subfunction 2 - set keyboard layout. ========= |
====================================================================== |
Keyboard layout is used to convert keyboard scancodes to ASCII-codes, |
which will be read by function 2. |
Parameters: |
* eax = 21 - function number |
* ebx = 2 - subfunction number |
* ecx = which layout to set: |
* 1 = normal layout |
* 2 = layout at pressed Shift |
* 3 = layout at pressed Alt |
* edx = pointer to layout - table of length 128 bytes |
Or: |
* ecx = 9 |
* dx = country identifier (1=eng, 2=fi, 3=ger, 4=rus) |
Returned value: |
* eax = 0 - success |
* eax = 1 - incorrect parameter |
Remarks: |
* If Alt is pressed, the layout with Alt is used; |
if Alt is not pressed, but Shift is pressed, |
the layout with Shift is used; |
if Alt and Shift are not pressed, but Ctrl is pressed, the normal |
layout is used and then from the code is subtracted 0x60; |
if no control key is pressed, the normal layout is used. |
* To get layout and country identifier use |
subfunction 2 of function 26. |
* Country identifier is global system variable, which is not used |
by the kernel itself; however the application '@panel' displays |
the corresponding icon. |
* The application @panel switches layouts on user request. |
====================================================================== |
============== Function 21, subfunction 3 - set CD base. ============= |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 3 - subfunction number |
* ecx = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Returned value: |
* eax = 0 |
Remarks: |
* CD base is used by function 24. |
* To get CD base use subfunction 3 of function 26. |
====================================================================== |
====== Function 21, subfunction 4 - set Sound Blaster base port. ===== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 4 - subfunction number |
* ecx = number of the base port |
Returned value: |
* eax = 0 - success |
* eax = -1 - erratic port number |
Remarks: |
* Number of the port must satisfy to conditions 0x100<=ecx<=0xFFFF. |
* The installation of the base is necessary for |
functions 25, 28, 55. |
* To get base port use subfunction 4 of function 26. |
====================================================================== |
========== Function 21, subfunction 5 - set system language. ========= |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 5 - subfunction number |
* ecx = system language (1=eng, 2=fi, 3=ger, 4=rus) |
Returned value: |
* eax = 0 |
Remarks: |
* System language is global system variable and is not used |
by the kernel itself, however application @panel draws the |
appropriate icon. |
* Function does not check for correctness, as the kernel does not |
use this variable. |
* To get system language use subfunction 5 of function 26. |
====================================================================== |
=========== Function 21, subfunction 6 - set WSS base port. ========== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 6 - subfunction number |
* ecx = base port |
Returned value: |
* eax = 0 - success |
* eax = -1 - erratic port number |
Remarks: |
* Port number must satisfy to condition 0x100<=ecx. |
* WSS base is used by function 27. |
* To get WSS base port use subfunction 6 of function 26. |
====================================================================== |
============== Function 21, subfunction 7 - set HD base. ============= |
====================================================================== |
The HD base defines hard disk to write with usage of obsolete |
file system functions and functions implicitly using the hard disk |
(such as subfunction 6 of function 18); |
at usage of function 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
these function set base themselves. |
Parameters: |
* eax = 21 - function number |
* ebx = 7 - subfunction number |
* ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Returned value: |
* eax = 0 |
Remarks: |
* Any application at any time can change the base. |
* Do not change base, when any application works with hard disk. |
If you do not want system bugs. |
* To get HD base use subfunction 7 of function 26. |
* It is also necessary to define used partition of hard disk by |
subfunction 8. |
====================================================================== |
========= Function 21, subfunction 8 - set used HD partition. ======== |
====================================================================== |
The HD partition defines partition of the hard disk to write with |
usage of obsolete file system functions and functions implicitly |
using the hard disk (such as subfunction 6 of function 18); |
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
these functions set base and partition themselves. |
Parameters: |
* eax = 21 - function number |
* ebx = 8 - subfunction number |
* ecx = HD partition (beginning from 1) |
Return value: |
* eax = 0 |
Remarks: |
* Any application at any time can change partition. |
* Do not change partition when any application works with hard disk. |
If you do not want system bugs. |
* To get used partition use subfunction 8 of function 26. |
* There is no correctness checks. |
* To get the number of partitions of a hard disk use |
subfunction 11 of function 18. |
* It is also necessary to define used HD base by subfunction 7. |
====================================================================== |
======== Function 21, subfunction 10 - set sound DMA channel. ======== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 10 - subfunction number |
* ecx = number of channel (from 0 up to 3 inclusively) |
Returned value: |
* eax = 0 - success |
* eax = -1 - incorrect channel number |
Remarks: |
* Number of DMA channel is used in subfunction 1 of function 55. |
* To get sound DMA channel use subfunction 10 of function 26. |
====================================================================== |
Function 21, subfunction 11 - enable/disable low-level access to HD. |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 11 - subfunction number |
* ecx = 0/1 - disable/enable |
Returned value: |
* eax = 0 |
Remarks: |
* Is used in LBA-read (subfunction 8 of function 58). |
* The current implementation uses only low bit of ecx. |
* To get current status use subfunction 11 of function 26. |
====================================================================== |
Function 21, subfunction 12 - enable/disable low-level access to PCI. |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 12 - subfunction number |
* ecx = 0/1 - disable/enable |
Returned value: |
* eax = 0 |
Remarks: |
* Is used in operations with PCI bus (function 62). |
* The current implementation uses only low bit of ecx. |
* To get current status use subfunction 12 of function 26. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 1 =========== |
======== Initialize + get information on the driver vmode.mdr. ======= |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 1 - number of the driver function |
* edx = pointer to 512-bytes buffer |
Returned value: |
* if driver is not loaded |
(never happens in the current implementation): |
* eax = -1 |
* ebx, ecx destroyed |
* if driver is loaded: |
* eax = 'MDAZ' (in fasm style, that is 'M' - low byte, 'Z' - high) |
- signature |
* ebx = current frequency of the scanning (in Hz) |
* ecx destroyed |
* buffer pointed to by edx is filled |
Format of the buffer: |
* +0: 32*byte: driver name, "Trans VideoDriver" |
(without quotes, supplemented by spaces) |
* +32 = +0x20: dword: driver version (version x.y is encoded as |
y*65536+x), for the current implementation is 1 (1.0) |
* +36 = +0x24: 7*dword: reserved (0 in the current implementation) |
* +64 = +0x40: 32*word: list of supported videomodes (each word |
is number of a videomode, after list itself there are zeroes) |
* +128 = +0x80: 32*(5*word): list of supported frequences of the |
scannings for videomodes: for each videomode listed in the |
previous field up to 5 supported frequences are given |
(unused positions contain zeroes) |
Remarks: |
* Function initializes the driver (if it is not initialized yet) |
and must be called first, before others (otherwise they will do |
nothing and return -1). |
* The current implementation supports only one frequency |
of the scanning on videomode. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 2 =========== |
================ Get information on current videomode. =============== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 2 - number of the driver function |
Returned value: |
* eax = -1 - driver is not loaded or not initialized; |
ebx,ecx are destroyed |
* eax = [width]*65536 + [height] |
* ebx = frequency of the vertical scanning (in Hz) |
* ecx = number of current videomode |
Remarks: |
* Driver must be initialized by call to |
driver function 1. |
* If only screen sizes are required, it is more expedient to use |
function 14 taking into account that it |
returns sizes on 1 less. |
====================================================================== |
=== Function 21, subfunction 13, subsubfunction 3 - set videomode. === |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 3 - number of the driver function |
* edx = [scanning frequency]*65536 + [videomode number] |
Returned value: |
* eax = -1 - driver is not loaded, not initialized or |
an error has occured |
* eax = 0 - success |
* ebx, ecx destroyed |
Remarks: |
* Driver must be initialized by driver function 1. |
* The videomode number and frequency must be in the table |
returned by driver function 1. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 4 =========== |
================== Return to the initial videomode. ================== |
====================================================================== |
Returns the screen to the videomode set at system boot. |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 4 - number of the driver function |
Returned value: |
* eax = -1 - driver is not loaded or not initialized |
* eax = 0 - success |
* ebx, ecx destroyed |
Remarks: |
* Driver must be initialized by call to driver function 1. |
====================================================================== |
============ Function 21, subfunction 13, subsubfunction 5 =========== |
===== Increase/decrease the size of the visible area of monitor. ===== |
====================================================================== |
Parameters: |
* eax = 21 - function number |
* ebx = 13 - subfunction number |
* ecx = 5 - number of the driver function |
* edx = 0/1 - decrease/increase horizontal size on 1 position |
* edx = 2/3 - is not supported in the current implementation; |
is planned as decrease/increase vertical size on 1 position |
Returned value: |
* eax = -1 - driver is not loaded or not initialized |
* eax = 0 - success |
* ebx, ecx destroyed |
Remarks: |
* Driver must be initialized by call to driver function 1. |
* Function influences only the physical size of the screen image; |
the logical size (number of pixels) does not change. |
====================================================================== |
================= Function 22 - set system date/time. ================ |
====================================================================== |
Parameters: |
* eax = 22 - function number |
* ebx = 0 - set time |
* ecx = 0x00SSMMHH - time in the binary-decimal code (BCD): |
* HH=hour 00..23 |
* MM=minute 00..59 |
* SS=second 00..59 |
* ebx = 1 - set date |
* ecx = 0x00DDMMYY - date in the binary-decimal code (BCD): |
* DD=day 01..31 |
* MM=month 01..12 |
* YY=year 00..99 |
* ebx = 2 - set day of week |
* ecx = 1 for Sunday, ..., 7 for Saturday |
* ebx = 3 - set alarm clock |
* ecx = 0x00SSMMHH |
Returned value: |
* eax = 0 - success |
* eax = 1 - incorrect parameter |
* eax = 2 - CMOS-battery was unloaded |
Remarks: |
* Value of installation of day of week seems to be doubtful, |
as it a little where is used |
(day of week can be calculated by date). |
* Alarm clock can be set on operation in the given time every day. |
But there is no existing system function to disable it. |
* Operation of alarm clock consists in generation IRQ8. |
* Generally CMOS supports for alarm clock set of value 0xFF |
as one of parameters and it means that the appropriate parameter |
is ignored. But current implementation does not allow this |
(will return 1). |
* Alarm clock is a global system resource; the set of |
an alarm clock cancels automatically the previous set. |
However, at moment no program uses it. |
====================================================================== |
============= Function 23 - wait for event with timeout. ============= |
====================================================================== |
If the message queue is empty, waits for new message in the queue, |
but no more than given time. Then reads out a message from the queue. |
Parameters: |
* eax = 23 - function number |
* ebx = timeout (in 1/100 of second) |
Returned value: |
* eax = 0 - the message queue is empty |
* otherwise eax = event (see the list of events) |
Remarks: |
* Only those events are taken into account, which enter into |
the mask set by function 40. By default it is |
redraw, key and button events. |
* To check for presence of a message in the queue use function 11. |
To wait without timeout use function 10. |
* Transmission ebx=0 results in immediate returning eax=0. |
* Current implementation returns immediately with eax=0, |
if the addition of ebx with the current value of time counter |
makes 32-bit overflow. |
====================================================================== |
======== Function 24, subfunction 1 - begin to play CD-audio. ======== |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 1 - subfunction number |
* ecx = 0x00FRSSMM, where |
* MM = starting minute |
* SS = starting second |
* FR = starting frame |
Returned value: |
* eax = 0 - success |
* eax = 1 - CD base is not defined |
Remarks: |
* Previously CD base must be defined by the call to |
subfunction 3 of function 21. |
* One second includes 75 frames, one minute includes 60 seconds. |
* The function is asynchronous (returns control, when play begins). |
====================================================================== |
======= Function 24, subfunction 2 - get information on tracks. ====== |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 2 - subfunction number |
* ecx = pointer to the buffer for the table |
(maximum 8*64h+4 bytes=100 tracks) |
Returned value: |
* eax = 0 - success |
* eax = 1 - CD base is not defined |
Remarks: |
* The format of the table with tracks information is the same as |
for ATAPI-CD command 43h (READ TOC), usual table (subcommand 00h). |
Function returns addresses in MSF. |
* Previously CD base port must be set by call to |
subfunction 3 of function 21. |
* Function returns information only about no more than 100 |
first tracks. In most cases it is enough. |
====================================================================== |
========== Function 24, subfunction 3 - stop play CD-audio. ========== |
====================================================================== |
Parameters: |
* eax = 24 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = 0 - success |
* eax = 1 - CD base is not defined |
Çàìå÷àíèÿ: |
* Previously CD base port must be defined by call to |
subfunction 3 of function 21. |
====================================================================== |
=================== Function 25 - set SBPro volume. ================== |
====================================================================== |
Parameters: |
* eax = 25 - function number |
* ebx = what to set: |
* 1 - set common volume |
* 2 - set CD-audio volume |
* cl = volume level: high 4 bits for the left column, |
low 4 bits for the right one |
Returned value: |
* eax = 0 - success |
* eax = 1 - SB base is not defined |
* eax = 2 - incorrect subfunction |
Remarks: |
* Previously SB base port must be defined by |
subfunction 4 of function 21. |
* See also function 28 which sets |
volume for the later standard SB16. |
====================================================================== |
======== Function 26, subfunction 1 - get MPU MIDI base port. ======== |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = port number |
Parameters: |
* To set base port use subfunction 1 of function 21. |
====================================================================== |
========== Function 26, subfunction 2 - get keyboard layout. ========= |
====================================================================== |
The keyboard layout is used to convert keyboard scancodes to |
ASCII-codes for function 2. |
Parameters: |
* eax = 26 - function number |
* ebx = 2 - subfunction number |
* ecx = what layout to get: |
* 1 = normal layout |
* 2 = layout with pressed Shift |
* 3 = layout with pressed Alt |
* edx = pointer to the 128-bytes buffer, where the layout will be |
copied |
Returned value: |
* function does not return value |
Or: |
* eax = 26 - function number |
* ebx = 2 - subfunction number |
* ecx = 9 |
Returned value: |
* eax = country identifier (1=eng, 2=fi, 3=ger, 4=rus) |
Remarks: |
* If Alt is pressed, the layout with Alt is used; |
if Alt is not pressed, but Shift is pressed, |
the layout with Shift is used; |
if Alt and Shift are not pressed, but Ctrl is pressed, the normal |
layout is used and then from the code is subtracted 0x60; |
if no control key is pressed, the normal layout is used. |
* To set layout and country identifier use |
subfunction 2 of function 21. |
* Country identifier is global system variable, which is not used |
by the kernel itself; however the application '@panel' displays |
the corresponding icon (using this function). |
* The application @panel switches layouts on user request. |
====================================================================== |
============== Function 26, subfunction 3 - get CD base. ============= |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Remarks: |
* CD base is used by function 24. |
* To set CD base use subfunction 3 of function 21. |
====================================================================== |
====== Function 26, subfunction 4 - get Sound Blaster base port. ===== |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = base port number |
Remarks: |
* Bae port is used by functions 25, 55. |
* To set base port use subfunction 4 of function 21. |
====================================================================== |
========== Function 26, subfunction 5 - get system language. ========= |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 5 - subfunction number |
Returned value: |
* eax = system language (1=eng, 2=fi, 3=ger, 4=rus) |
Remarks: |
* System language is global system variable and is not used |
by the kernel itself, however application @panel draws the |
appropriate icon (using this function). |
* To set system language use subfunction 5 of function 21. |
====================================================================== |
=========== Function 26, subfunction 6 - get WSS base port. ========== |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 6 - subfunction number |
Returned value: |
* eax = base port |
Remarks: |
* WSS base is used by function 27. |
* To set WSS base port use subfunction 6 of function 21. |
====================================================================== |
============== Function 26, subfunction 7 - get HD base. ============= |
====================================================================== |
The HD base defines hard disk to write with usage of obsolete |
file system functions and functions implicitly using the hard disk |
(such as subfunction 6 of function 18); |
at usage of function 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
these function set base themselves. |
Parameters: |
* eax = 26 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Remarks: |
* Any application in any time can change HD base. |
* To set base use subfunction 7 of function 21. |
* To get used partition of hard disk use subfunction 8. |
====================================================================== |
========= Function 26, subfunction 8 - get used HD partition. ======== |
====================================================================== |
The HD partition defines partition of the hard disk to write with |
usage of obsolete file system functions and functions implicitly |
using the hard disk (such as subfunction 6 of function 18); |
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
these functions set base and partition themselves. |
Parameters: |
* eax = 26 - function number |
* ebx = 8 - subfunction number |
Returned value: |
* eax = HD partition (beginning from 1) |
Remarks: |
* Any application in any time can change partition. |
* To set partition use subfunction 8 of function 21. |
* To get number of partitions on a hard disk use |
subfunction 11 of function 18. |
* To get base of used hard disk, use subfunction 7. |
====================================================================== |
=== Function 26, subfunction 9 - get the value of the time counter. == |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 9 - subfunction number |
Returned value: |
* eax = number of 1/100s of second, past from the system boot time |
Remarks: |
* Counter takes modulo 2^32, that correspond to a little more |
than 497 days. |
* To get system time use function 3. |
====================================================================== |
======== Function 26, subfunction 10 - get sound DMA channel. ======== |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 10 - subfunction number |
Returned value: |
* eax = number of the channel (from 0 to 3 inclusive) |
Remarks: |
* Number of the DMA channel is used by subfunction 1 of function 55. |
* To set the sound DMA channel use subfunction 10 of function 21. |
====================================================================== |
===================== Function 26, subfunction 11 ==================== |
========== Find out whether low-level HD access is enabled. ========== |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 11 - subfunction number |
Returned value: |
* eax = 0/1 - disabled/enabled |
Remarks: |
* Is used in LBA read (subfunction 8 of function 58). |
* To set current state use subfunction 11 of function 21. |
====================================================================== |
===================== Function 26, subfunction 12 ==================== |
========== Find out whether low-level PCI access is enabled. ========= |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 12 - subfunction number |
Returned value: |
* eax = 0/1 - disabled/enabled |
Remarks: |
* Is used by operations with PCI bus (function 62). |
* The current implementation uses only low bit of ecx. |
* To set the current state use subfunction 12 of function 21. |
====================================================================== |
======== Function 27 - set Windows Sound System (WSS) volume. ======== |
====================================================================== |
Parameters: |
* eax = 27 - function number |
* ebx = what to set: |
* 1 - set common volume |
* 2 - set Line In volume |
* cl = volume level (0x0=highest, 0x1F=lowest, |
if bit 0x80 is set=disable) |
Returned value: |
* eax = 0 - success |
* eax = 1 - WSS base is not defined |
* eax = 2 - incorrect subfunction |
Remarks: |
* Previously WSS base port must be defined by call to |
subfunction 6 of function 21. |
* Set of common volume is ignored (function simply returns eax=0). |
* Old documentation and kernel sources erraticly name function 2 |
as CD-audio volume. |
====================================================================== |
=================== Function 28 - set SB16 volume. =================== |
====================================================================== |
Parameters: |
* eax = 28 - function number |
* ebx = what to install: |
* 1 - install common volume |
* 2 - install CD-audio volume |
* cl = volume level (0=off, 0xFF=max) |
Returned value: |
* eax = 0 - success |
* eax = 1 - SB base is not defined |
* eax = 2 - incorrect subfunction |
Remarks: |
* Previously SB base port must be defined by |
subfunction 4 of function 21. |
* This function gives more variants for volume, that function 25. |
====================================================================== |
=================== Function 29 - get system date. =================== |
====================================================================== |
Parameters: |
* eax = 29 - function number |
Returned value: |
* eax = 0x00DDMMYY, where |
(binary-decimal coding, BCD, is used) |
* YY = two low digits of year (00..99) |
* MM = month (01..12) |
* DD = day (01..31) |
Remarks: |
* To set system date use function 22. |
====================================================================== |
=============== Function 32 - delete file from ramdisk. ============== |
====================================================================== |
Parameters: |
* eax = 32 - function number |
* ebx = pointer to the filename |
Returned value: |
* eax = 0 - success; otherwise file system error code |
Remarks: |
* This function is obsolete; function 58 allows to fulfill |
the same operations with the extended possibilities. |
* The current implementation returns only values 0(success) and |
5(file not found). |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
================ Function 33 - write file to ramdisk. ================ |
====================================================================== |
Parameters: |
* eax = 33 - function number |
* ebx = pointer to the filename |
* ecx = pointer to data for writing |
* edx = number of bytes for writing |
* should be set esi=0 |
Returned value: |
* eax = 0 - success, otherwise file system error code |
Remarks: |
* This function is obsolete; function 70 allows to fulfil |
the same operations with extended possibilities. |
* If esi contains non-zero value and selected file already exists, |
one more file with the same name will be created. |
* Otherwise file will be overwritten. |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
======= Function 35 - read the color of a pixel on the screen. ======= |
====================================================================== |
Parameters: |
* eax = 35 |
* ebx = y*xsize+x, where |
* (x,y) = coordinates of a pixel (beginning from 0) |
* xsize = horizontal screen size |
Returned value: |
* eax = color 0x00RRGGBB |
Remarks: |
* To get screen sizes use function 14. Pay attention, |
that it subtracts 1 from both sizes. |
* There is also direct access (without any system calls) |
to videomemory through the selector gs. To get parameters of |
the current videomode, use function 61. |
====================================================================== |
========= Function 37 - get coordinates/status of the mouse. ========= |
====================================================================== |
---------- Subfunction 0 - screen coordinates of the mouse ----------- |
Parameters: |
* eax = 37 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer |
(beginning from 0) |
-- Subfunction 1 - coordinates of the mouse relative to the window --- |
Parameters: |
* eax = 37 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer |
relative to the application window (beginning from 0) |
Remarks: |
* The value is calculated by formula (x-xwnd)*65536 + (y-ywnd). |
If y>=ywnd, the low word is non-negative and contains |
relative y-coordinate, and the high word - relative x-coordinate |
(with correct sign). Otherwise the low word is negative and still |
contains relative y-coordinate, and to the high word |
1 should be added. |
------------ Subfunction 2 - pressed buttons of the mouse ------------ |
Parameters: |
* eax = 37 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax contains information on the pressed mouse buttons: |
* bit 0 is set = left button is pressed |
* bit 1 is set = right button is pressed |
* other bits are cleared |
====================================================================== |
====================== Function 38 - draw line. ====================== |
====================================================================== |
Parameters: |
* eax = 38 - function number |
* ebx = [start coordinate on axis x]*65536 + |
[end coordinate on axis x] |
* ecx = [start coordinate on axis y]*65536 + |
[end coordinate on axis y] |
* edx = 0x00RRGGBB - color |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates are relative to the window. |
* End point is also drawn. |
====================================================================== |
== Function 39, subfunction 1 - get a size of the background image. == |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = [width]*65536 + [height] |
Remarks: |
* There is a pair function to set sizes of background image - |
subfunction 1 of function 15. After which it is necessary, |
of course, anew to define image. |
====================================================================== |
== Function 39, subfunction 2 - get pixel from the background image. = |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 2 - subfunction number |
* ecx = offset |
Returned value: |
* eax = 0x00RRGGBB - pixel color, if offset is valid |
(less than 0x160000-16) |
* eax = 2 otherwise |
Remarks: |
* Do not rely on returned value for invalid offsets, it may be |
changed in future kernel versions. |
* Offset for pixel with coordinates (x,y) |
is calculated as (x+y*xsize)*3. |
* There is a pair function to set pixel on the background image - |
subfunction 2 of function 15. |
====================================================================== |
== Function 39, subfunction 4 - get drawing mode for the background. = |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = 1 - tile |
* eax = 2 - stretch |
Remarks: |
* There is a pair function to set drawing mode - |
subfunction 4 of function 15. |
====================================================================== |
=========== Function 40 - set the mask for expected events. ========== |
====================================================================== |
The mask for expected events affects function working with events |
10, 11, 23 - they notify only about events allowed by this mask. |
Parameters: |
* eax = 40 - function number |
* ebx = mask: bit i corresponds to event i+1 (see list of events) |
(set bit permits notice on event) |
Returned value: |
* function does not return value |
Remarks: |
* Default mask (7=111b) enables nofices about redraw, |
keys and buttons. This is enough for many applications. |
* Events prohibited in the mask are saved anyway, when come; |
they are simply not informed with event functions. |
* Event functions take into account the mask on moment of |
function call, not on moment of event arrival. |
====================================================================== |
==================== Function 41 - get IRQ owner. ==================== |
====================================================================== |
Parameters: |
* eax = 41 - function number |
* ebx = IRQ number, 0..15 |
Returned value: |
* eax = owner PID |
* eax = 0, if there is no owner |
* eax = -1 for incorrect ebx |
====================================================================== |
==================== Function 42 - read IRQ data. ==================== |
====================================================================== |
When an IRQ occurs, the system reads data from ports indicated |
earlier by function 44 and writes this data to |
internal buffer. This function reads out data from that buffer |
bytewise. |
Parameters: |
* eax = 42 - function number |
* ebx = IRQ number, 0..15 |
Returned value: (use value of ecx to distinguish) |
* if the thread is not IRQ owner (or IRQ number is incorrect): |
* ecx = 2 |
* if there is no data: |
* eax = 0 |
* ecx = 1 |
* ebx destroyed |
* if all is ok: |
* eax = byte size of data, not yet read from buffer |
* ecx = 0 |
* ebx = current byte |
Remarks: |
* Previously the thread must reserve indicated IRQ for itself |
by function 45. |
* The size of data buffer is 4000 bytes, on overflow |
"fresh" data cease to be written in the buffer. |
====================================================================== |
================ Function 43 - input/output to a port. =============== |
====================================================================== |
------------------------ Output data to port ------------------------- |
Parameters: |
* eax = 43 - function number |
* bl = byte for output |
* ecx = port number 0xnnnn (from 0 to 0xFFFF) |
Returned value: |
* eax = 0 - success |
* eax = 1 - the thread has not reserved the selected port |
------------------------ Input data from port ------------------------ |
Parameters: |
* eax = 43 - function number |
* ebx is ignored |
* ecx = 0x8000nnnn, where nnnn = port number (from 0 to 0xFFFF) |
Returned value: |
* eax = 0 - success, thus ebx = entered byte |
* eax = 1 - the thread has not reserved the selected port |
Remarks: |
* Previously the thread must reserve the selected port |
for itself by function 46. |
* Instead of call to this function it is better to use |
processor instructions in/out - this is much |
faster and a bit shorter and easier. |
====================================================================== |
=========== Function 44 - define operations at IRQ arrival. ========== |
====================================================================== |
At IRQ arrival the system can read the data from ports defined |
by this function and write these data to internal buffer, whence |
they can be read by ôóíêöèåé 42. |
Parameters: |
* eax = 44 - function number |
* ebx = pointer to the array of structures each describing one port: |
* +0: word: 0 means end of array, otherwise port number |
* +2: byte: reserved (ignored) |
* +3: byte: 1=read byte from this port, 2=read word |
* ecx = IRQ number, 0..15 |
Returned value: |
* eax = 0 - success |
* eax = 1 - the thread is not owner of selected IRQ |
Remarks: |
* Previously the thread must reserve for itself selected IRQ |
by function 45. |
* First 16 ports are considered only. |
* The current implementation considers incorrect value of field +3 |
as a signal to terminate IRQ processing. |
====================================================================== |
=================== Function 45 - reserve/free IRQ. ================== |
====================================================================== |
Parameters: |
* eax = 45 - function number |
* ebx = 0 - reserve, 1 = free |
* ecx = IRQ number, 0..15 |
Returned value: |
* eax = 0 - success |
* eax = 1 - error (invalid IRQ number |
or attempt to reserve not free IRQ |
or to free IRQ, not reserved by this thread) |
Remarks: |
* IRQ reservation is required for functions 42 and 44. |
* Only one thread can reserve the specific IRQ. |
* IRQs, handled by the system itself, are reserved by the system |
(thread 1) at booting. |
* When a thread terminates, all reserved by it IRQs |
are freed automatically. |
====================================================================== |
====== Function 46 - reserve/free a group of input/output ports. ===== |
====================================================================== |
To work with reserved ports an application can access directly by |
commands in/out (recommended way) and can use function 43 |
(not recommended way). |
Parameters: |
* eax = 46 - function number |
* ebx = 0 - reserve, 1 - free |
* ecx = start port number |
* edx = end port number (inclusive) |
Returned value: |
* eax = 0 - success |
* eax = 1 - error |
Remarks: |
* For ports reservation: an error occurs if and only if |
one from the following condition satisfies: |
* start port is more than end port; |
* the selected range contains incorrect port number |
(correct are from 0 to 0xFFFF); |
* limit for the total number of reserved areas is exceeded |
(maximum 255 are allowed); |
* the selected range intersects with any of earlier reserved |
* For ports free: an error is an attempt to free range, |
that was not earlier reserved by this function |
(with same ecx,edx). |
* If an error occurs (for both cases) function performs no action. |
* At booting the system reserves for itself ports 0..0xff, and if |
COM-mouse is detected - additionally range of COM-ports |
0x3f0..0x3ff and/or 0x2f0..0x2ff. |
* When a thread terminates, all reserved by it ports |
are freed automatically. |
====================================================================== |
============= Function 47 - draw a number in the window. ============= |
====================================================================== |
Parameters: |
* eax = 47 - function number |
* ebx = parameters of conversion number to text: |
* bl = 0 - ecx contains number |
* bl = 1 - ecx contains pointer to dword-number |
* bh = 0 - display in decimal number system |
* bh = 1 - display in hexadecimal system |
* bh = 2 - display in binary system |
* áèòû 16-21 = how many digits to display |
* áèòû 22-31 reserved and must be set to 0 |
* ecx = number (if bl=0) or pointer (if bl=1) |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
* esi = 0xN0RRGGBB, RRGGBB=color, N=font (0/1) |
Returned value: |
* function does not return value |
Remarks: |
* The given length must not exceed 60. |
* The exactly given amount of digits is output. If number is small |
and can be written by smaller amount of digits, it is supplemented |
by leading zeroes; if the number is big and can not be written by |
given amount of digits, extra digits are not drawn. |
* Parameters of fonts are shown in the description of function 4 |
(text output). |
====================================================================== |
========= Function 48, subfunction 0 - apply screen settings. ======== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 0 - subfunction number |
* ecx = 0 - reserved |
Returned value: |
* function does not return value |
Remarks: |
* Function redraws the screen after parameters change by |
subfunctions 1 and 2. |
* Function call without prior call to one of indicated subfunctions |
is ignored. |
* Function call with nonzero ecx is ignored. |
====================================================================== |
=========== Function 48, subfunction 1 - set button style. =========== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 1 - subfunction number |
* ecx = button style: |
* 0 = flat |
* 1 = 3d |
Returned value: |
* function does not return value |
Remarks: |
* After call to this function one should redraw the screen by |
subfunction 0. |
* Button style influences only to their draw of function 8. |
====================================================================== |
====== Function 48, subfunction 2 - set standard window colors. ====== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 2 - subfunction number |
* ecx = pointer to the color table |
* edx = size of the color table |
(must be 40 bytes for future compatibility) |
Format of the color table is shown in description of subfunction 3. |
Returned value: |
* function does not return value |
Remarks: |
* After call to this function one should redraw the screen by |
subfunction 0. |
* Table of standard colors influences only to applications, |
which receive this table obviously (by subfunction 3) |
and use it (specifying colors from it to drawing functions). |
* Table of standard colors is included in skin and is installed |
anew with skin installation (by subfunction 8). |
* Color table can be viewed/changed interactively with |
the application 'desktop'. |
====================================================================== |
====== Function 48, subfunction 3 - get standard window colors. ====== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 3 - subfunction number |
* ecx = pointer to the buffer with size edx bytes, |
where table will be written |
* edx = size of color table |
(must be 40 bytes for future compatibility) |
Returned value: |
* function does not return value |
Format of the color table: |
each item is dword-value for color 0x00RRGGBB |
* +0: dword: frames - color of frame |
* +4: dword: grab - color of header |
* +8: dword: grab_button - color of button on header bar |
* +12 = +0xC: dword: grab_button_text - color of text on button |
on header bar |
* +16 = +0x10: dword: grab_text - color of text on header |
* +20 = +0x14: dword: work - color of working area |
* +24 = +0x18: dword: work_button - color of button in working area |
* +28 = +0x1C: dword: work_button_text - color of text on button |
in working area |
* +32 = +0x20: dword: work_text - color of text in working area |
* +36 = +0x24: dword: work_graph - color of graphics in working area |
Remarks: |
* Structure of the color table is described in the standard |
include file 'macros.inc' as 'system_colors'; for example, |
it is possible to write: |
sc system_colors ; variable declaration |
... ; somewhere one must call |
; this function with ecx=sc |
mov ecx, [sc.work_button_text] ; read text color on |
; buttin in working area |
* A program itself desides to use or not to use color table. |
For usage program must simply at calls to drawing functions select |
color taken from the table. |
* At change of the table of standard colors (by subfunction 2 with |
the subsequent application of changes by subfunction 0 or |
at skin set by subfunction 8) the system sends to all windows |
redraw message (the event with code 1). |
* Color table can be viewed/changed interactively with |
the application 'desktop'. |
====================================================================== |
============ Function 48, subfunction 4 - get skin height. =========== |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = skin height |
Remarks: |
* Skin height is defined as the height of a header |
of skinned windows. |
* See also general structure of window in the description |
of function 0. |
====================================================================== |
======== Function 48, subfunction 5 - get screen working area. ======= |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 5 - subfunction number |
Returned value: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
Remarks: |
* The screen working area defines position and coordinates of |
a maximized window. |
* The screen working area in view of normal work is all screen |
without system panel (the application '@panel'). |
* (left,top) are coordinates of the left upper corner, |
(right,bottom) are coordinates of the right lower one. |
Thus the size of working area on x axis can be calculated by |
formula right-left+1, on y axis - by formula bottom-right+1. |
* See also function 14, |
to get sizes of all screen. |
* There is a pair function to set working area - subfunction 6. |
====================================================================== |
======== Function 48, subfunction 6 - set screen working area. ======= |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 6 - subfunction number |
* ecx = [left]*65536 + [right] |
* edx = [top]*65536 + [bottom] |
Returned value: |
* function does not return value |
Remarks: |
* The screen working area defines position and coordinates of |
a maximized window. |
* This function is used only by the application '@panel', |
which set working area to all screen without system panel. |
* (left,top) are coordinates of the left upper corner, |
(right,bottom) are coordinates of the right lower one. |
Thus the size of working area on x axis can be calculated by |
formula right-left+1, on y axis - by formula bottom-right+1. |
* If 'left'>='right', x-coordinate of working area is not changed. |
If 'left'<0, 'left' will not be set. If 'right' is greater than or |
equal to screen width, 'right' will not be set. |
Similarly on y axis. |
* See also function 14, |
to get sizes of all screen. |
* There is a pair function to get working area - subfunction 5. |
* This function redraws the screen automatically, |
updating coordinates and sizes of maximized windows. |
The system sends to all windows redraw message (the event 1). |
====================================================================== |
=========== Function 48, subfunction 7 - get skin margins. =========== |
====================================================================== |
Returns the area of a header of a skinned window, intended for |
a text of a header. |
Parameters: |
* eax = 48 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
Remarks: |
* An application decides itself to use or not to use this function. |
* It is recommended to take into account returned value |
of this function for choice of a place for drawing header text |
(by function 4) or a substitute of header text |
(at the discretion of an application). |
====================================================================== |
============= Function 48, subfunction 8 - set used skin. ============ |
====================================================================== |
Parameters: |
* eax = 48 - function number |
* ebx = 8 - subfunction number |
* ecx = pointer to a block for function 58, in |
which the fields of intermediate buffer and file name are filled |
Returned value: |
* eax = 0 - success |
* otherwise eax = file system error code; if file does not |
contain valid skin, function returns error 3 |
(unknown file system). |
Remarks: |
* After successful skin loading the system sends to all windows |
redraw message (the event 1). |
* At booting the system reads skin from file 'default.skn' |
on ramdisk. |
* User can change the skin statically by creating hisself |
'default.skn' or dynamically with the application 'desktop'. |
====================================================================== |
=========== Function 49 - Advanced Power Management (APM). =========== |
====================================================================== |
Parameters: |
* eax = 49 - function number |
* dx = number of the APM function |
(analogue of ax in APM specification) |
* bx, cx = parameters of the APM function |
Returned value: |
* 16-bit registers ax, bx, cx, dx, si, di and carry flag CF |
are set according to the APM specification |
* high halves of 32-bit registers eax, ebx, ecx, |
edx, esi, edi are destroyed |
Remarks: |
* APM 1.2 specification is described in the document |
"Advanced Power Management (APM) BIOS Specification" |
(Revision 1.2), available at |
http://www.microsoft.com/whdc/archive/amp_12.mspx; |
besides it is included in famous Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). |
====================================================================== |
=================== Function 50 - set window shape. ================== |
====================================================================== |
Normal windows have rectangular shape. This function can give to |
a window any shape. The shape is given by a set of points inside |
the base rectangle belonging to a window. Position and coordinates |
of the base rectangle are set by function 0 |
and changed by function 67. |
--------------------------- Set shape data --------------------------- |
Parameters: |
* eax = 50 - function number |
* ebx = 0 - subfunction number |
* ecx = pointer to shape data (array of bytes 0/1) |
Returned value: |
* function does not return value |
-------------------------- Set shape scale --------------------------- |
Parameters: |
* eax = 50 - function number |
* ebx = 1 - subfunction number |
* ecx sets a scale: each byte of data defines |
(2^scale)*(2^scale) pixels |
Returned value: |
* function does not return value |
Remarks: |
* Default scale is 0 (scale factor is 1). If in the shape data |
one byte corresponds to one pixel, there is no necessity |
to set scale. |
* Let's designate xsize = window width (in pixels), ysize = height; |
pay attention, that they are one pixel more than defined by |
functions 0, 67. |
* On definition of scale xsize and ysize must be divisible |
on 2^scale. |
* Byte of data on offset 'a' must be 0/1 and defines belonging |
to a window of square with the side 2^scale (if scale=0, |
this is one pixel) and coordinates of the left upper corner |
(a mod (xsize shr scale), a div (xsize shr scale)) |
* Data size: (xsize shr scale)*(ysize shr scale). |
* Data must be presented in the memory and not change |
after set of shape. |
* The system views the shape data at every window redraw by |
function 0. |
* The call of subfunction 0 with NULL pointer results in return |
to the rectangular shape. |
====================================================================== |
==================== Function 51 - create thread. ==================== |
====================================================================== |
Parameters: |
* eax = 51 - function number |
* ebx = 1 - unique subfunction |
* ecx = address of thread entry point (starting eip) |
* edx = pointer to thread stack (starting esp) |
Returned value: |
* eax = -1 - error (there is too many threads) |
* otherwise eax = TID - thread identifier |
</UL> |
====================================================================== |
=== Function 52, subfunction 0 - get network driver configuration. === |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = configuration dword |
Remarks: |
* Configuration dword can be set by subfunction 2. |
* The kernel does not use this variable. The value of this |
variable and working with it subfunctions 0 and 2 is represented |
doubtful. |
====================================================================== |
========= Function 52, subfunction 1 - get local IP-address. ========= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = IP-address (4 bytes) |
Remarks: |
* Local IP-address is set by subfunction 3. |
====================================================================== |
=== Function 52, subfunction 2 - set network driver configuration. === |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 2 - subfunction number |
* ecx = configuration dword; if low 7 bits derivate the number 3, |
function [re-]initializes Ethernet-card, otherwise |
Ethernet turns off |
Returned value: |
* if Ethernet-interface is not requested, function returns eax=2, |
but this can be changed in future kernel versions |
* if Ethernet-interface is requested, eax=0 means error |
(absence of Ethernet-card), and nonzero value - success |
Remarks: |
* Configuration dword can be read by subfunction 0. |
* The kernel does not use this variable. The value of this |
variable, subfunction 0 and part of subfunction 2, which set it, |
is represented doubtful. |
====================================================================== |
========= Function 52, subfunction 3 - set local IP-address. ========= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 3 - subfunction number |
* ecx = IP-address (4 bytes) |
Returned value: |
* the current implementation returns eax=3, but this can be changed |
in future versions |
Remarks: |
* Local IP-address can be get by subfunction 1. |
====================================================================== |
= Function 52, subfunction 6 - add data to the stack of input queue. = |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 6 - subfunction number |
* edx = data size |
* esi = data pointer |
Returned value: |
* eax = -1 - error |
* eax = 0 - success |
Remarks: |
* This function is intended only for slow network drivers |
(PPP, SLIP). |
* Data size must not exceed 1500 bytes, though function |
performs no checks on correctness. |
====================================================================== |
Function 52, subfunction 8 - read data from the network output queue. |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 8 - subfunction number |
* esi = pointer to 1500-byte buffer |
Returned value: |
* eax = number of read bytes (in the current implementation |
either 0 = no data or 1500) |
* data was copied in buffer |
Remarks: |
* This function is intended only for slow network drivers |
(PPP, SLIP). |
====================================================================== |
============ Function 52, subfunction 9 - get gateway IP. ============ |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 9 - subfunction number |
Returned value: |
* eax = gateway IP (4 bytes) |
====================================================================== |
=========== Function 52, subfunction 10 - get subnet mask. =========== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 10 - subfunction number |
Returned value: |
* eax = subnet mask |
====================================================================== |
============ Function 52, subfunction 11 - set gateway IP. =========== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 11 - subfunction number |
* ecx = gateway IP (4 bytes) |
Returned value: |
* the current implementation returns eax=11, but this can be changed |
in future versions |
====================================================================== |
=========== Function 52, subfunction 12 - set subnet mask. =========== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 12 - subfunction number |
* ecx = subnet mask |
Returned value: |
* the current implementation returns eax=12, but this can be changed |
in future versions |
====================================================================== |
============== Function 52, subfunction 13 - get DNS IP. ============= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 13 - subfunction number |
Returned value: |
* eax = DNS IP (4 bytes) |
====================================================================== |
============== Function 52, subfunction 14 - set DNS IP. ============= |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 14 - subfunction number |
* ecx = DNS IP (4 bytes) |
Returned value: |
* the current implementation returns eax=14, but this can be changed |
in future versions |
====================================================================== |
============ Function 53, subfunction 0 - open UDP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 0 - subfunction number |
* ecx = local port (only low word is taken into account) |
* edx = remote port (only low word is taken into account) |
* esi = remote IP |
Returned value: |
* eax = -1 = 0xFFFFFFFF - error; ebx destroyed |
* eax = socket handle (some number which unambiguously identifies |
socket and have sense only for the system) - success; |
ebx destroyed |
====================================================================== |
=========== Function 53, subfunction 1 - close UDP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 1 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = -1 - incorrect handle |
* eax = 0 - success |
* ebx destroyed |
Remarks: |
* The current implementation does not close automatically all |
sockets of a thread at termination. In particular, one should not |
kill a thread with many opened sockets - there will be an outflow |
of resources. |
* The current implementation does no checks on correctness |
(function returns error only if thread tries to close not opened |
socket with correct handle). |
====================================================================== |
============== Function 53, subfunction 2 - poll socket. ============= |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 2 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = number of read bytes |
* ebx destroyed |
Remarks: |
* There is no checks for correctness. |
====================================================================== |
========= Function 53, subfunction 3 - read byte from socket. ======== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 3 - subfunction number |
* ecx = socket handle |
Returned value: |
* if there is no read data: eax=0, bl=0, |
other bytes of ebx are destroyed |
* if there are read data: eax=number of rest bytes |
(possibly 0), bl=read byte, other bytes of ebx are destroyed |
Remarks: |
* There is no checks for correctness. |
====================================================================== |
========== Function 53, subfunction 4 - write to UDP-socket. ========= |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 4 - subfunction number |
* ecx = socket handle |
* edx = number of bytes to write |
* esi = pointer to data to write |
Returned value: |
* eax = 0xffffffff - invalid handle |
* eax = 0xffff - not enough memory |
* eax = 0 - success |
* ebx destroyed |
Remarks: |
* Check on validity of handle is minimal - only not very incorrect |
not opened handles are eliminated. |
* Number of bytes to write must not exceed 1500-28, though |
the appropriate check is not made. |
====================================================================== |
============ Function 53, subfunction 5 - open TCP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 5 - subfunction number |
* ecx = local port (only low word is taken into account) |
* edx = remote port (only low word is taken into account) |
* esi = remote IP |
* edi = open mode: SOCKET_PASSIVE=0 or SOCKET_ACTIVE=1 |
Returned value: |
* eax = -1 = 0xFFFFFFFF - error; ebx destroys |
* eax = socket handle (some number which unambiguously identifies |
socket and have sense only for the system) - success; |
ebx destroyed |
====================================================================== |
========= Function 53, subfunction 6 - get TCP-socket status. ======== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 6 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = socket status: one of |
* TCB_LISTEN = 1 |
* TCB_SYN_SENT = 2 |
* TCB_SYN_RECEIVED = 3 |
* TCB_ESTABLISHED = 4 |
* TCB_FIN_WAIT_1 = 5 |
* TCB_FIN_WAIT_2 = 6 |
* TCB_CLOSE_WAIT = 7 |
* TCB_CLOSING = 8 |
* TCB_LAST_ASK = 9 |
* TCB_TIME_WAIT = 10 |
* TCB_CLOSED = 11 |
* ebx destroys |
Remarks: |
* There is no checks for correctness. |
====================================================================== |
========== Function 53, subfunction 7 - write to TCP-socket. ========= |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 7 - subfunction number |
* ecx = socket handle |
* edx = number of bytes to write |
* esi = pointer to data to write |
Returned value: |
* eax = 0xffffffff - error |
* eax = 0xffff - not enough memory |
* eax = 0 - success |
* ebx destroyed |
Remarks: |
* Check on validity of handle is minimal - only not very incorrect |
not opened handles are eliminated. |
* Number of bytes to write must not exceed 1500-40, though |
the appropriate check is not made. |
====================================================================== |
=========== Function 53, subfunction 8 - close TCP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 8 - subfunction number |
* ecx = socket handle |
Returned value: |
* eax = -1 - invalid handle |
* eax = 0xffff - not enough memory for socket close packet |
* eax = 0 - success |
* in many cases eax is destroyed (the result of function 'queue' |
is returned) - probably this is bug, which will be corrected |
* ebx destroyed |
Remarks: |
* The current implementation does not close automatically all |
sockets of a thread at termination. In particular, one should not |
kill a thread with many opened sockets - there will be an outflow |
of resources. |
* The current implementation does no checks on correctness |
(function returns error only if thread tries to close not opened |
socket with correct handle). |
====================================================================== |
=== Function 53, subfunction 9 - check whether local port is free. === |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 9 - subfunction number |
* ecx = local port number (low 16 bits are used only) |
Returned value: |
* eax = 0 - port is used |
* eax = 1 - port is free |
* ebx destroyed |
====================================================================== |
= Function 53, subfunction 255 - debug information of network driver. |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 255 - subfunction number |
* ecx = type of requested information (see below) |
Returned value: |
* eax = requested information |
* ebx destroyed |
Possible values for ecx: |
* 100: length of queue 0 (empty queue) |
* 101: length of queue 1 (ip-out queue) |
* 102: length of queue 2 (ip-in queue) |
* 103: length of queue 3 (net1out queue) |
* 200: number of items in the ARP table |
* 201: size of the ARP table (in items) (20 for current version) |
* 202: read item at edx of the ARP table to the temporary buffer, |
whence 5 following types take information; |
in this case eax is not defined |
* 203: IP-address saved by type 202 |
* 204: high dword of MAC-address saved by type 202 |
* 205: low word of MAC-address saved by type 202 |
* 206: status word saved by type 202 |
* 207: ttl word saved by type 202 |
* 2: total number of received IP-packets |
* 3: total number of transferred IP-packets |
* 4: total number of dumped received packets |
* 5: total number of received ARP-packets |
* 6: status of packet driver, 0=inactive, nonzero=active |
====================================================================== |
========== Function 55, subfunction 0 - load data for SB16. ========== |
====================================================================== |
Parameters: |
* eax = 55 - function number |
* ebx = 0 - subfunction number |
* ecx = pointer to data (is copied 64 kilobytes, is used as much as |
set by subfunction 2) |
Returned value: |
* function does not return value |
Remarks: |
* Format and size of data are set by subfunction 2. |
====================================================================== |
======== Function 55, subfunction 1 - begin play data on SB16. ======= |
====================================================================== |
Parameters: |
* eax = 55 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* function does not return value |
Remarks: |
* Previously data must be loaded by subfunction 0 and |
their format must be defined by subfunction 2. |
* Function returns control, when playing of data began; after that |
play goes independently from application (and does not use |
processor time at all). |
* Previously must be defined SB16 base port |
(by subfunction 4 of function 21) and DMA channel |
(by subfunction 10 of function 21). |
====================================================================== |
======== Function 55, subfunction 2 - set format of SB16 data. ======= |
====================================================================== |
Parameters: |
* eax = 55 - function number |
* ebx = 2 - subfunction number |
* ecx = 0 - set digit capacity |
* edx = 1 - 8bit mono |
* edx = 2 - 8bit stereo |
* ecx = 1 - set data size |
* edx = size in bytes |
* ecx = 2 - set play frequency |
* edx = frequency |
Returned value: |
* function does not return value |
Remarks: |
* When the system boots, it sets following default parameters: |
digit capacity - 8bit mono, size - 64 Kb, frequency - 44100 Hz. |
Nevertheless it is recommended to set necessary values obviously |
as they could be reset by some application. |
====================================================================== |
Function 55, subfunction 55 - begin to play data on built-in speaker. |
====================================================================== |
Parameters: |
* eax = 55 - function number |
* ebx = 55 - subfunction number |
* esi = pointer to data |
Returned value: |
* eax = 0 - success |
* eax = 55 - error (speaker is off or busy) |
Data is an array of items with variable length. |
Format of each item is defined by first byte: |
* 0 = end of data |
* 1..0x80 = sets sound duration on 1/100 of second; sound note |
is defined by immediate value of frequency |
* following word (2 bytes) contains frequency divider; |
frequency is defined as 1193180/divider |
* 0x81 = invalid |
* 0x82..0xFF = note is defined by octave and number: |
* duration in 1/100 of second = (first byte)-0x81 |
* there is one more byte; |
* (second byte)=0xFF - delay |
* otherwise it looks like a*0x10+b, where b=number of the note in |
an octave from 1 to 12, a=number of octave (beginning from 0) |
Remarks: |
* Speaker play can be disabled/enabled by |
subfunction 8 of function 18. |
* Function returns control, having informed the system |
an information on request. Play itself goes independently from |
the program. |
* The data must be kept in the memory at least up to the end |
of play. |
====================================================================== |
=============== Function 56 - write file to hard disk. =============== |
====================================================================== |
Parameters: |
* eax = 56 - function number |
* ebx = pointer to the file name |
* ecx = size of data to write (in bytes) |
* edx = pointer to data to write |
* esi = pointer to path (ASCIIZ-string) |
Returned value: |
* eax = 0 - success, otherwise file system error code |
Remarks: |
* This function is obsolete; function 70 allows to fulfil the same |
operations with the extended possibilities. |
* This function assumes that during its call by one application |
no other application works with hard disk. |
* The path to file is ASCIIZ-string, which may be empty |
(if the file is created in the root folder) or have the format |
/d1/d2/.../dn, where all folder names must have the 8+3 format, |
i.e. 8 characters of name and 3 characters of the extension |
without separator, supplemented by blanks if necessary; |
all letters must be capital. |
* The file name must also have the format 8+3. |
====================================================================== |
================ Function 58 - work with file system. ================ |
====================================================================== |
Parameters: |
* eax = 58 |
* ebx = pointer to the information structure |
Returned value: |
* eax = 0 - success; otherwise file system error code |
* some subfunctions return value in other registers too |
General format of the information structure: |
* +0: dword: subfunction number |
* +4: dword: number of block |
* +8: dword: size |
* +12 = +0xC: dword: pointer to data |
* +16 = +0x10: dword: pointer to a memory for system operations |
(4096 bytes) |
* +20 = +0x14: n db: ASCIIZ-string with the file name |
Specifications - in documentation on the appropriate subfunction. |
Filename is case-insensitive for latin letters, russian letters |
must be capital. |
Format of filename: |
/base/number/dir1/dir2/.../dirn/file, |
where /base/number identifies device, on which file is located: |
one of |
* /RD/1 = /RAMDISK/1 to access ramdisk |
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive, |
/FD/2 = /FLOPPYDISK/2 to access second one |
* /HD/x = /HARDDISK/x - obsolete variant of access to hard disk |
(in this case base is defined by subfunction 7 of function 21), |
x - partition number (beginning from 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices |
IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - partition number on the selected hard drive, varies from 1 |
to 255 (on each hard drive the indexing starts from 1) |
Remarks: |
* In the first two cases it is also possible to use FIRST |
instead of 1, SECOND instead of 2, but it is not recommended |
for convenience of transition to the future extensions. |
* Limitation n<=39 is imposed. |
* Names of folders and file dir1,...,dirn,file must have the |
format 8.3: name no more than 8 characters, dot, extension no |
more than 3 characters. Trailing spaces are ignored, no other |
spaces is allowed. If name occupies equally 8 characters, |
dot may be omitted (though it is not recommended to use this |
feature for convenience of transition to the future extensions). |
* This function does not support folders on ramdisk. |
Examples: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/1/menuet/pics/tanzania.bmp',0 |
Existing subfunctions: |
* subfunction 0 - read file/folder |
* subfunction 1 - rewrite file |
* subfunction 2 - delete file/folder |
* subfunction 3 - write to existing file |
* subfunction 4 - make folder |
* subfunction 5 - rename/move file/folder |
* subfunction 8 - LBA-read from device |
* subfunction 15 - get file system information |
* subfunction 16 - start application |
====================================================================== |
=========== Function 58, subfunction 0 - read file/folder. =========== |
====================================================================== |
Parameters: |
* eax = 58 |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 0 = subfunction number |
* +4: dword: first block to read (beginning from 0) |
* +8: dword: amount of blocks to read |
* +12 = +0xC: dword: pointer to buffer for data |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = file size (in bytes) or -1=0xffffffff, if file was not found |
Remarks: |
* Block size is 512 bytes. |
* This function is obsolete, for reading files use subfunction 0 |
of function 70, for reading folders - subfunction 1 of |
function 70. |
* Function can read contents of a folder. Only FAT file system is |
supported. The format of FAT-folder is described |
in any FAT documentation. |
* Size of a folder is determined by size of FAT clusters chain. |
* If file was ended before last requested block was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* Function can read root folders /rd/1,/fd/x,/hd[n]/x, but |
in the first two cases the current implementation does not follow |
to the declared rules: |
for /rd/1: |
* if one want to read 0 blocks, function considers, |
that he requested 1; |
* if one requests more than 14 blocks or starting block is |
not less than 14, function returns eax=5 (not found) è ebx=-1; |
* size of ramdisk root folder is 14 blocks, |
0x1C00=7168 áàéò; but function returns ebx=0 |
(except of the case of previous item); |
* strangely enough, it is possible to read 14th block (which |
generally contains a garbage - I remind, the indexing begins |
from 0); |
* if some block with the number not less than 14 was requested, |
function returns eax=6(EOF); otherwise eax=0. |
For /fd/x: |
* if the start block is not less than 14, function returns |
eax=5 (not found) and ebx=0; |
* note that format of FAT12 allows floppies with the root size |
more or less than 14 blocks; |
* check for length is not performed; |
* if data was successful read, function returns |
eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1. |
* The function handles reading of special folders /,/rd,/fd,/hd[n]; |
but the result does not correspond to expected (on operations with |
normal files/folders), does not follow the declared rules, |
may be changed in future versions of the kernel and consequently |
is not described. To obtain the information about the equipment |
use subfunction 11 of function 18 or |
read corresponding folder with subfunction 1 of function 70. |
====================================================================== |
============= Function 58, subfunction 1 - rewrite file. ============= |
====================================================================== |
If the file does not exist, it is created. |
If the file exists, it is rewritten. |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 1 = subfunction number |
* +4: dword: ignored (set to 0) |
* +8: dword: number of bytes to write |
* +12 = +0xC: dword: pointer to data to write |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* This function is obsolete, use subfunction 2 of function 70. |
====================================================================== |
========== Function 58, subfunction 2 - delete file/folder. ========== |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 2 = subfunction number |
* +4: dword: ignored |
* +8: dword: ignored |
* +12 = +0xC: dword: ignored |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* By operations with a floppy one should not delete not empty |
folder. The code working with hard disk deletes not empty folders |
correctly (i.e. recursively with all files and nested folders). |
Function 58 does not support folders on ramdisk. |
====================================================================== |
==== Function 58, subfunction 3 - write data to the existing file. === |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 3 = subfunction number |
* +4: dword: starting position in the file; -1 = append to the end |
* +8: dword: number of bytes to write |
* +12 = +0xC: dword: pointer to data to write |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* Ramdisk and floppies do not support this function, it is only |
for hard disks. |
* File must already exist (otherwise function returns 5, not found). |
To create files use subfunction 1. |
* If the starting position is greater than file size, the function |
returns eax=6(EOF). If the end position is greater than file size, |
file is extended. |
* The code of write processing for hard disk interpretes zero |
value of the field +8 as the instruction to truncate the file to |
the size, given in the field +4. However the code of processing |
58th function blocks this possibility for applications by |
immediate return (with eax=0) in the case of zero size. |
====================================================================== |
============== Function 58, subfunction 4 - make folder. ============= |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 4 = subfunction number |
* +4: dword: ignored |
* +8: dword: ignored |
* +12 = +0xC: dword: ignored |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* Ramdisk and floppies do not support this function, it is only |
for hard disks. |
====================================================================== |
======== Function 58, subfunction 5 - rename/move file/folder. ======= |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 5 = subfunction number |
* +4: dword: ignored |
* +8: dword: ignored |
* +12 = +0xC: dword: ignored |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
* +20+n: (at once after terminating null character) new |
ASCIIZ-name, must start from /hd/1, that is interpreted as |
the hard disk, indicated in the first name |
(moving from one disk to another is not supported) |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* Ramdisk and floppies do not support this function, it is only |
for hard disks. |
* If the new ASCIIZ-name is strongly incorrect, i.e. does not start |
from /hd/1, /hd/first, /harddisk/1, /harddisk/first or after this |
space or null character follows, function returns, strangely |
enough, error code 4. It is the only function which returns |
this code. |
====================================================================== |
========= Function 58, subfunction 8 - LBA-read from device. ========= |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 8 = subfunction number |
* +4: dword: number of block to read (beginning from 0) |
* +8: dword: ignored (set to 1) |
* +12 = +0xC: dword: pointer to buffer for data (512 bytes) |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of |
/rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3. |
Instead of digits it is allowed, though not recommended for |
convenience of transition to future extensions, to use |
'first','second','third','fourth'. |
Returned value: |
* for device name /hd/xxx, where xxx is not in the list above: |
* eax = ebx = 1 |
* for invalid device name (except for the previous case): |
* eax = 5 |
* ebx does not change |
* if LBA-access is disabled by subfunction 11 of function 21: |
* eax = 2 |
* ebx destroyed |
* for ramdisk: attempt to read block outside ramdisk |
(18*2*80 blocks) results in |
* eax = 3 |
* ebx = 0 |
* for successful read: |
* eax = ebx = 0 |
Remarks: |
* Block size is 512 bytes; function reads one block. |
* Do not depend on returned value, it can be changed |
in future versions. |
* Function requires that LBA-access to devices is enabled by |
subfunction 11 of function 21. To check this one can use |
subfunction 11 of function 26. |
* LBA-read of floppy is not supported. |
* Function reads data on physical hard drive; if for any reason |
data of the concrete partition are required, application must |
define starting sector of this partition (either directly |
through MBR, or from the full structure returned by |
ïîäôóíêöèåé 11 ôóíêöèè 18). |
* Function does not check error code of hard disk, so request of |
nonexisting sector reads something (most probably it will be |
zeroes, but this is defined by device) and this is considered |
as success (eax=0). |
====================================================================== |
==== Function 58, subfunction 15 - get information on file system. === |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 15 = subfunction number |
* +4: dword: ignored |
* +8: dword: ignored |
* +12 = +0xC: dword: ignored |
* +16 = +0x10: dword: ignored |
* +20 = +0x14: (only second character is checked) |
/rd=/RAMDISK or /hd=/HARDDISK |
Returned value: |
* if the second character does not belong to set {'r','R','h','H'}: |
* eax = 3 |
* ebx = ecx = dword [fileinfo] = 0 |
* for ramdisk: |
* eax = 0 (success) |
* ebx = total number of clusters = 2847 |
* ecx = number of free clusters |
* dword [fileinfo] = cluster size = 512 |
* for hard disk: base and partition are defined by subfunctions |
7 and 8 of function 21: |
* eax = 0 (success) |
* ebx = total number of clusters |
* ecx = number of free clusters |
* dword [fileinfo] = cluster size (in bytes) |
Remarks: |
* Be not surprised to strange layout of 4th returned parameter |
- when this code was writing, at system calls application got |
only registers eax,ebx,ecx (from pushad-structure transmitted |
as argument to the system function). Now it is corrected, so, |
probably, it is meaningful to return cluster size in edx, while |
this function is not used yet. |
* There exists also subfunction 11 of function 18, |
which returns information on file system. From the full table |
of disk subsystem it is possible to deduce cluster size (there |
it is stored in sectors) and total number of clusters |
for hard disks. |
====================================================================== |
========== Function 58, subfunction 16 - start application. ========== |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 16 = subfunction number |
* +4: dword: flags: |
* bit 0: start the process as debugged |
* other bits are reserved and must be cleared |
* +8: dword: 0 or pointer to ASCIIZ-string with parameters |
* +12 = +0xC: dword: ignored |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax > 0 - the program is loaded, eax contains PID |
* eax < 0 - an error has occured, -eax contains |
file system error code |
Remarks: |
* This function is obsolete, use subfunction 7 of function 70. |
* Command line must be terminated by character with code 0 |
(ASCIIZ-string); function takes into account either all characters |
up to terminating null inclusively or the first 256 charachters |
depending on what is less. |
* If the process is started as debugged, it is created in |
the suspended state; to run use subfunction 5 of function 69. |
====================================================================== |
=============== Function 59 - trace last system calls. =============== |
====================================================================== |
Gets data on all system calls of all processes. |
Parameters: |
* eax = 59 - function number |
* ebx = 0 - unique subfunction |
* ecx = pointer to the buffer |
* edx = size of the buffer |
Returned value: |
* eax = total number of system calls made from system boot |
(modulo 2^32) |
* ebx = 0 |
Format of information on one call: (size = 0x40 = 64 bytes) |
* +0: dword: PID of process/thread |
* +4: 7*dword: garbage |
* +32 = +0x20: dword: value of edi at the call |
* +36 = +0x24: dword: esi |
* +40 = +0x28: dword: ebp |
* +44 = +0x2C: dword: stack pointer of the kernel handler |
* +48 = +0x30: dword: ebx |
* +52 = +0x34: dword: edx |
* +56 = +0x38: dword: ecx |
* +60 = +0x3C: dword: eax (=number of system function) |
Remarks: |
* The function is used only in the application 'systrace'. |
It is rather difficult to imagine a situation, in which |
this application or this function are really useful; |
and all system calls for support of this function are a little |
decelerated (though not strongly)... |
* So there is a proposition to delete from the kernel |
support of this function, together with application 'systrace'. |
* The information on system calls saves in the system |
ring buffer with 0x10 entries. |
This function simply copies the given size of data |
from this buffer to the given address. |
* One can determine, which entry in the buffer corresponds to |
last system call, by value of eax, namely, it is the entry |
(eax and 0xF) (at offset (eax and 0xF)*0x40). |
* In the current implementation there can be the seldom |
meeting problems of unsynchronization, when the information |
on some calls becomes outdated. |
* Under the system buffer one page, 4Kb, is allocated. |
Size of an entry = 64 bytes. Why only 16 entries are used, |
is not clearly. |
* The value of esp at the moment of system call cannot |
be determined by this function. |
* The current implementation does not check edx for correctness. |
====================================================================== |
========== Function 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC is used for message dispatching from one process/thread to |
another. Previously it is necessary to agree how to interpret |
the concrete message. |
----------- Subfunction 1 - set the area for IPC receiving ----------- |
Is called by process-receiver. |
Parameters: |
* eax = 60 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to the buffer |
* edx = size of the buffer |
Returned value: |
* eax = 0 - always success |
Format of IPC-buffer: |
* +0: dword: if nonzero, buffer is considered locked; |
lock/unlock the buffer, when you work with it and need that |
buffer data are not changed from outside (no new messages) |
* +4: dword: occupied place in the buffer (in bytes) |
* +8: first message |
* +8+n: second message |
* ... |
Format of a message: |
* +0: dword: PID of sender |
* +4: dword: message length (not including this header) |
* +8: n*byte: message data |
------------------ Subfunction 2 - send IPC message ------------------ |
Is called by process-sender. |
Parameters: |
* eax = 60 - function number |
* ebx = 2 - subfunction number |
* ecx = PID of receiver |
* edx = pointer to the message data |
* esi = message length (in bytes) |
Returned value: |
* eax = 0 - success |
* eax = 1 - the receiver has not defined buffer for IPC messages |
(can be, still have no time, |
and can be, this is not right process) |
* eax = 2 - the receiver has blocked IPC-buffer; try to wait a bit |
* eax = 3 - overflow of IPC-buffer of the receiver |
* eax = 4 - process/thread with such PID does not exist |
Remarks: |
* Immediately after writing of IPC-message to the buffer the system |
sends to the receiver the event with code 7 (see event codes). |
====================================================================== |
==== Function 61 - get parameters for the direct graphics access. ==== |
====================================================================== |
The data of the graphics screen (the memory area which displays |
screen contents) are accessible to a program directly, without |
any system calls, through the selector gs: |
mov eax, [gs:0] |
places in eax the first dword of the buffer, which contains |
information on color of the left upper point (and, possibly, colors |
of several following). |
mov [gs:0], eax |
by work in VESA modes with LFB sets color of the left upper point |
(and, possibly, colors of several following). |
To interpret the data of graphics screen program needs to know |
some parameters, returning by this function. |
Remarks: |
* Graphics parameters changes very seldom at work, |
namely, only in cases, when user works with the application VRR. |
* At videomode change the system redraws all windows (event |
with code 1) and redraws the background (event 5). |
Same events occur in other cases too, which meet much more often, |
than videomode change. |
* By operation in videomodes with LFB the selector gs points to |
LFB itself, so reading/writing on gs result directly in |
change of screen contents. By operation in videomodes without |
LFB gs points to some data area in the kernel, and all functions |
of screen output fulfil honesty double operation on writing |
directly to the screen and writing to this buffer. In result |
at reading contents of this buffer the results correspond to |
screen contents (with, generally speaking, large color |
resolution), and writing is ignored. |
One exception is the mode 320*200, for which main loop of the |
system thread updates the screen according to mouse movements. |
------------------------- Screen resolution -------------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = [resolution on x axis]*65536 + [resolution on y axis] |
Remarks: |
* One can use function 14 paying attention that |
it returns sizes on 1 pixel less. It is fully equivalent way. |
---------------------- Number of bits per pixel ---------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = number of bits per pixel (24 or 32) |
-------------------- Number of bytes per scanline -------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = number of bytes occupied by one scanline |
(horizontal line on the screen) |
====================================================================== |
===== Function 62, subfunction 0 - get version of PCI-interface. ===== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 0 - subfunction number |
Returned value: |
* eax = -1 - PCI access is disabled; otherwise |
* ah.al = version of PCI-interface (ah=version, al=subversion) |
* high word of eax is zeroed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* If PCI BIOS is not supported, the value of ax is undefined. |
====================================================================== |
==== Function 62, subfunction 1 - get number of the last PCI-bus. ==== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 1 - subfunction number |
Returned value: |
* eax = -1 - access to PCI is disabled; otherwise |
* al = number of the last PCI-bus; other bytes of eax are destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* If PCI BIOS is not supported, the value of ax is undefined. |
====================================================================== |
===================== Function 62, subfunction 2 ===================== |
===== Get mechanism of addressing to the PCI configuration space. ==== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 2 - subfunction number |
Returned value: |
* eax = -1 - access to PCI is disabled; otherwise |
* al = mechanism (1 or 2); other bytes of eax are destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Addressing mechanism is selected depending on |
equipment characteristics. |
* Subfunctions of read and write work automatically |
with the selected mechanism. |
====================================================================== |
======== Function 62, subfunctions 4,5,6 - read PCI-register. ======== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 4 - read byte |
* bl = 5 - read word |
* bl = 6 - read dword |
* bh = number of PCI-bus |
* ch = dddddfff, where ddddd = number of the device on the bus, |
fff = function number of device |
* cl = number of register (must be even for bl=5, |
divisible by 4 for bl=6) |
Returned value: |
* eax = -1 - error (access to PCI is disabled or parameters |
are not supported); otherwise |
* al/ax/eax (depending on requested size) contains the data; |
the other part of register eax is destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Access mechanism 2 supports only 16 devices on a bus and ignores |
function number. To get access mechanism use subfunction 2. |
* Some registers are standard and exist for all devices, some are |
defined by the concrete device. The list of registers of the |
first type can be found e.g. in famous |
Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); |
registers of the second type must be listed |
in the device documentation. |
====================================================================== |
====== Function 62, subfunctions 8,9,10 - write to PCI-register. ===== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 8 - write byte |
* bl = 9 - write word |
* bl = 10 - write dword |
* bh = number of PCI-bus |
* ch = dddddfff, where ddddd = number of the device on the bus, |
fff = function number of device |
* cl = number of register (must be even for bl=9, |
divisible by 4 for bl=10) |
* dl/dx/edx (depending on requested size) contatins |
the data to write |
Returned value: |
* eax = -1 - error (access to PCI is disabled or parameters |
are not supported) |
* eax = 0 - success |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Access mechanism 2 supports only 16 devices on a bus and ignores |
function number. To get access mechanism use subfunction 2. |
* Some registers are standard and exist for all devices, some are |
defined by the concrete device. The list of registers of the |
first type can be found e.g. in famous Interrupt List by |
Ralf Brown; registers of the second type must be listed |
in the device documentation. |
====================================================================== |
============== Function 63 - work with the debug board. ============== |
====================================================================== |
The debug board is the global system buffer (with the size |
512 bytes), to which any program can write (generally speaking, |
arbitrary) data and from which other program can read these data. |
By the agreement written data are text strings interpreted as |
debug messages on a course of program execution. The kernel in |
some situations also writes to the debug board information on |
execution of some functions; by the agreement kernel messages |
begins from the prefix "K : ". |
For view of the debug board the application 'board' was created, |
which reads data from the buffer and displays them in its window. |
'board' interpretes the sequence of codes 13,10 as newline. |
A character with null code in an end of line is not necessary, |
but also does not prevent. |
Because debugger has been written, the value of the debug board |
has decreased, as debugger allows to inspect completely a course of |
program execution without any efforts from the direction of program |
itself. Nevertheless in some cases the debug board is still useful. |
----------------------------- Write byte ----------------------------- |
Parameters: |
* eax = 63 - function number |
* ebx = 1 - subfunction number |
* cl = data byte |
Returned value: |
* function does not return value |
Remarks: |
* Byte is written to the buffer. Buffer size is 512 bytes. |
At buffer overflow all obtained data are lost. |
* For output to the debug board of more complicated objects |
(strings, numbers) it is enough to call this function in cycle. |
It is possible not to write the appropriate code manually and use |
file 'debug.inc', which is included into the distributive. |
----------------------------- Read byte ------------------------------ |
Takes away byte from the buffer. |
Parameters: |
* eax = 63 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = ebx = 0 - the buffer is empty |
* eax = byte, ebx = 1 - byte was successfully read |
====================================================================== |
============== Function 64 - resize application memory. ============== |
====================================================================== |
Parameters: |
* eax = 64 - function number |
* ebx = 1 - unique subfunction |
* ecx = new memory size |
Returned value: |
* eax = 0 - success |
* eax = 1 - not enough memory |
Remarks: |
* At the moment this function is a sole resource for dynamic |
allocation/free of application memory. |
====================================================================== |
================== Function 66 - work with keyboard. ================= |
====================================================================== |
The input mode influences results of reading keys by function 2. |
When a program loads, ASCII input mode is set for it. |
-------------- Subfunction 1 - set keyboard input mode. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 1 - subfunction number |
* ecx = mode: |
* 0 = normal (ASCII-characters) |
* 1 = scancodes |
Returned value: |
* function does not return value |
-------------- Subfunction 2 - get keyboard input mode. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = current mode |
------------ Subfunction 3 - get status of control keys. ------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = bit mask: |
* bit 0 (mask 1): left Shift is pressed |
* bit 1 (mask 2): right Shift is pressed |
* bit 2 (mask 4): left Ctrl is pressed |
* bit 3 (mask 8): right Ctrl is pressed |
* bit 4 (mask 0x10): left Alt is pressed |
* bit 5 (mask 0x20): right Alt is pressed |
* bit 6 (mask 0x40): CapsLock is on |
* bit 7 (mask 0x80): NumLock is on |
* bit 8 (mask 0x100): ScrollLock is on |
* other bits are cleared |
-------------- Subfunction 4 - set system-wide hotkey. --------------- |
When hotkey is pressed, the system notifies only those applications, |
which have installed it; the active application (which receives |
all normal input) does not receive such keys. |
The notification consists in sending event with the code 2. |
Reading hotkey is the same as reading normal key - by function 2. |
Parameters: |
* eax = 66 - function number |
* ebx = 4 - subfunction number |
* cl determines key scancode; |
use cl=0 to give combinations such as Ctrl+Shift |
* edx = 0xXYZ determines possible states of control keys: |
* Z (low 4 bits) determines state of LShift and RShift: |
* 0 = no key must be pressed; |
* 1 = exactly one key must be pressed; |
* 2 = both keys must be pressed; |
* 3 = must be pressed LShift, but not RShift; |
* 4 = must be pressed RShift, but not LShift |
* Y - similar for LCtrl and RCtrl; |
* X - similar for LAlt and RAlt |
Returned value: |
* eax=0 - success |
* eax=1 - too mant hotkeys (maximum 256 are allowed) |
Remarks: |
* Hotkey can work either at pressing or at release. Release |
scancode of a key is more on 128 than pressing scancode |
(i.e. high bit is set). |
* Several applications can set the same combination; |
all such applications will be informed on pressing |
such combination. |
-------------- Subfunction 5 - delete installed hotkey. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 5 - subfunction number |
* cl = scancode of key and edx = 0xXYZ the same as in subfunction 4 |
Returned value: |
* eax = 0 - success |
* eax = 1 - there is no such hotkey |
Remarks: |
* When a process/thread terminates, all hotkey installed by it are |
deleted. |
* The call to this subfunction does not affect other applications. |
If other application has defined the same combination, it will |
still receive notices. |
====================================================================== |
========= Function 67 - change position/sizes of the window. ========= |
====================================================================== |
Parameters: |
* eax = 67 - function number |
* ebx = new x-coordinate of the window |
* ecx = new y-coordinate of the window |
* edx = new x-size of the window |
* esi = new y-size of the window |
Returned value: |
* function does not return value |
Remarks: |
* The value -1 for a parameter means "do not change"; e.g. to move |
the window without resizing it is possible to specify edx=esi=-1. |
* Previously the window must be defined by function 0. |
It sets initial coordinates and sizes of the window. |
* Sizes of the window are understood in sense of function 0, |
that is one pixel less than real sizes. |
* The function call for maximized windows is simply ignored. |
* For windows of appropriate styles position and/or sizes can be |
changed by user; current position and sizes can be obtained by |
call to function 9. |
* The function sends to the window redraw event (with the code 1). |
====================================================================== |
====== Function 68, subfunction 0 - get the task switch counter. ===== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = number of task switches from the system booting |
(modulo 2^32) |
====================================================================== |
======= Function 68, subfunction 1 - switch to the next thread. ====== |
====================================================================== |
The function completes the current time slice allocated to the |
thread and switches to the next. (Which thread in which process |
will be next, is unpredictable). Later, when execution queue |
will reach the current thread, execution will be continued. |
Parameters: |
* eax = 68 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* function does not return value |
====================================================================== |
============= Function 68, subfunction 2 - cache + rdpmc. ============ |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 2 - subfunction number |
* ecx = required action: |
* ecx = 0 - enable instruction 'rdpmc' |
(ReaD Performance-Monitoring Counters) for applications |
* ecx = 1 - find out whether cache is disabled/enabled |
* ecx = 2 - enable cache |
* ecx = 3 - disable cache |
Returned value: |
* for ecx=0: |
* eax = the value of cr4 |
* for ecx=1: |
* eax = (cr0 and 0x60000000): |
* eax = 0 - cache is on |
* eax <> 0 - cache is off |
* for ecx=2 and ecx=3: |
* function does not return value |
====================================================================== |
=========== Function 68, subfunction 3 - read MSR-register. ========== |
====================================================================== |
MSR = Model Specific Register; the complete list of MSR-registers |
of a processor is included to the documentation on it (for example, |
IA-32 Intel Architecture Software Developer's Manual, |
Volume 3, Appendix B); each processor family has its own subset |
of the MSR-registers. |
Parameters: |
* eax = 68 - function number |
* ebx = 3 - subfunction number |
* ecx is ignored |
* edx = MSR address |
Returned value: |
* ebx:eax = high:low dword of the result |
Remarks: |
* If ecx contains nonexistent or not implemented for this processor |
MSR, processor will generate an exception in the kernel, which |
will kill the thread. |
* Previously it is necessary to check, whether MSRs are supported |
as a whole, with the instruction 'cpuid'. Otherwise processor |
will generate other exception in the kernel, which will anyway |
kill the thread. |
====================================================================== |
========= Function 68, subfunction 4 - write to MSR-register. ======== |
====================================================================== |
MSR = Model Specific Register; the complete list of MSR-registers |
of a processor is included to the documentation on it (for example, |
IA-32 Intel Architecture Software Developer's Manual, |
Volume 3, Appendix B); each processor family has its own subset |
of the MSR-registers. |
Parameters: |
* eax = 68 - function number |
* ebx = 4 - subfunction number |
* ecx is ignored |
* edx = MSR address |
* esi:edi = high:low dword |
Returned value: |
* ebx:eax = copy of esi:edi |
Çàìå÷àíèÿ: |
* If ecx contains nonexistent or not implemented for this processor |
MSR, processor will generate an exception in the kernel, which |
will kill the thread. |
* Previously it is necessary to check, whether MSRs are supported |
as a whole, with the instruction 'cpuid'. Otherwise processor |
will generate other exception in the kernel, which will anyway |
kill the thread. |
====================================================================== |
======= Function 68, subfunction 5 - allocate physical memory. ======= |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 5 - subfunction number |
* ecx = size (in bytes) |
Returned value: |
* eax = physical address of allocated memory |
Remarks: |
* Normal applications must not use this function, it is intended |
for the case, when for some device it is required to place |
data to the known physical address. (In effect, this function |
was developed for AC97WAV.) |
* The number of blocks of physical memory is limited (by constant |
24, and this constant includes some blocks for kernel). |
* To free a memory allocated by such way use |
subfunction 6, to copy data there and back |
use subfunctions 7 and 8. |
====================================================================== |
========= Function 68, subfunction 6 - free physical memory. ========= |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 6 - subfunction number |
* ecx = physical address of memory |
Returned value: |
* function does not return value |
Remarks: |
* Normal applications must not use this function, it is intended |
for the case, when for some device it is required to place |
data to the known physical address. (In effect, this function |
was developed for AC97WAV.) |
* The memory must be previously allocated by subfunction 5. |
====================================================================== |
===== Function 68, subfunction 7 - write data to physical memory. ==== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 7 - subfunction number |
* ecx = physical address |
* edx = pointer to the data (in the application) |
* esi = size of the data (in bytes) |
Returned value: |
* function does not return value |
Remarks: |
* Normal applications must not use this function, it is intended |
for the case, when for some device it is required to place |
data to the known physical address. (In effect, this function |
was developed for AC97WAV.) |
* The range of physical addresses should lie inside of previously |
allocated by subfunction 5 block of physical memory. |
* There is no check for correctness. |
====================================================================== |
==== Function 68, subfunction 8 - read data from physical memory. ==== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 8 - subfunction number |
* ecx = physical address |
* edx = pointer to buffer for data (in application) |
* esi = size of data (in bytes) |
Returned value: |
* function does not return value |
Remarks: |
* Normal applications must not use this function, it is intended |
for the case, when for some device it is required to place |
data to the known physical address. (In effect, this function |
was developed for AC97WAV.) |
* The range of physical addresses should lie inside of previously |
allocated by subfunction 5 block of physical memory. |
* There is no check for correctness. |
====================================================================== |
====================== Fucntion 69 - debugging. ====================== |
====================================================================== |
A process can load other process as debugged by set of corresponding |
bit by call to subfunction 16 of function 58 |
or subfunction 7 of function 70. |
A process can have only one debugger; one process can debug some |
others. The system notifies debugger on events occuring with |
debugged process. Messages are written to the buffer defined by |
subfunction 0. |
Format of a message: |
* +0: dword: message code |
* +4: dword: PID of debugged process |
* +8: there can be additional data depending on message code |
Message codes: |
* 1 = exception |
* in addition dword-number of the exception is given |
* process is suspended |
* 2 = process has terminated |
* comes at any termination: both through the system function -1, |
and at "murder" by any other process (including debugger itself) |
* 3 = debug exception int 1 = #DB |
* in addition dword-image of the register DR6 is given: |
* bits 0-3: condition of the corresponding breakpoint (set by |
subfunction 9) is satisfied |
* áèò 14: exception has occured because of the trace mode |
(flag TF is set TF) |
* process is suspended |
When debugger terminates, all debugged processes are killed. |
If debugger does not want this, it must previously detach by |
subfunction 3. |
All subfunctions are applicable only to processes/threads started |
from the current by function 58 or 70 with set debugging flag. |
Debugging of multithreaded programs is not supported yet. |
The full list of subfunctions: |
* subfunction 0 - define data area for debug messages |
* subfunction 1 - get contents of registers of debugged thread |
* subfunction 2 - set contents of registers of debugged thread |
* subfunction 3 - detach from debugged process |
* subfunction 4 - suspend debugged thread |
* subfunction 5 - resume debugged thread |
* subfunction 6 - read from the memory of debugged process |
* subfunction 7 - write to the memory of debugged process |
* subfunction 8 - terminate debugged thread |
* subfunction 9 - set/clear hardware breakpoint |
====================================================================== |
= Function 69, subfunction 0 - define data area fror debug messages. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 0 - subfunction number |
* ecx = pointer |
Format of data area: |
* +0: dword: N = buffer size (not including this header) |
* +4: dword: occupied place |
* +8: N*byte: buffer |
Returned value: |
* function does not return value |
Remarks: |
* If the size field is negative, the buffer is considered locked |
and at arrival of new message the system will wait. |
For synchronization frame all work with the buffer by operations |
lock/unlock |
neg [bufsize] |
* Data in the buffer are considered as array of items with variable |
length - messages. Format of a message is explained in |
general description. |
====================================================================== |
===================== Function 69, subfunction 1 ===================== |
============ Get contents of registers of debugged thread. =========== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 1 - subfunction number |
* ecx = thread identifier |
* edx = size of context structure, must be 0x28=40 bytes |
* esi = pointer to context structure |
Returned value: |
* function does not return value |
Format of context structure: (FPU is not supported yet) |
* +0: dword: eip |
* +4: dword: eflags |
* +8: dword: eax |
* +12 = +0xC: dword: ecx |
* +16 = +0x10: dword: edx |
* +20 = +0x14: dword: ebx |
* +24 = +0x18: dword: esp |
* +28 = +0x1C: dword: ebp |
* +32 = +0x20: dword: esi |
* +36 = +0x24: dword: edi |
Remarks: |
* If the thread executes code of ring-0, the function returns |
contents of registers of ring-3. |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
===================== Function 69, subfunction 2 ===================== |
============ Set contents of registers of debugged thread. =========== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 2 - subfunction number |
* ecx = thread identifier |
* edx = size of context structure, must be 0x28=40 bytes |
Returned value: |
* function does not return value |
Format of context structure is shown in the description of |
subfunction 1. |
Remarks: |
* If the thread executes code of ring-0, the function returns |
contents of registers of ring-3. |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
===== Function 69, subfunction 3 - detach from debugged process. ===== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 3 - subfunction number |
* ecx = identifier |
Returned value: |
* function does not return value |
Remarks: |
* If the process was suspended, it resumes execution. |
====================================================================== |
======== Function 69, subfunction 4 - suspend debugged thread. ======= |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 4 - subfunction number |
* ecx = thread identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
======== Function 69, subfunction 5 - resume debugged thread. ======== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 5 - subfunction number |
* ecx = thread identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
= Fucntion 69, subfunction 6 - read from memory of debugged process. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 6 - subfunction number |
* ecx = identifier |
* edx = number of bytes to read |
* esi = address in the memory of debugged process |
* edi = pointer to buffer for data |
Returned value: |
* eax = -1 at an error (invalid PID or buffer) |
* otherwise eax = number of read bytes (possibly, 0, |
if esi is too large) |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
== Function 69, subfunction 7 - write to memory of debugged process. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 7 - subfunction number |
* ecx = identifier |
* edx = number of bytes to write |
* esi = address of memory in debugged process |
* edi = pointer to data |
Returned value: |
* eax = -1 at an error (invalid PID or buffer) |
* otherwise eax = number of written bytes (possibly, 0, |
if esi is too large) |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
======= Function 69, subfunction 8 - terminate debugged thread. ====== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 8 - subfunction number |
* ecx = identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
* The function is similar to subfunction 2 of function 18 |
with two differences: it requires first remark and |
accepts PID rather than slot number. |
====================================================================== |
===== Function 69, subfunction 9 - set/clear hardware breakpoint. ==== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 9 - subfunction number |
* ecx = thread identifier |
* dl = index of breakpoint, from 0 to 3 inclusively |
* dh = flags: |
* if high bit is cleared - set breakpoint: |
* bits 0-1 - condition: |
* 00 = breakpoint on execution |
* 01 = breakpoint on read |
* 11 = breakpoint on read/write |
* bits 2-3 - length; for breakpoints on exception it must be |
00, otherwise one of |
* 00 = byte |
* 01 = word |
* 11 = dword |
* esi = breakpoint address; must be aligned according to |
the length (i.e. must be even for word breakpoints, |
divisible by 4 for dword) |
* if high bit is set - clear breakpoint |
Returned value: |
* eax = 0 - success |
* eax = 1 - error in the input data |
* eax = 2 - (reserved, is never returned in the current |
implementation) a global breakpoint with that index is already set |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
* Hardware breakpoints are implemented through DRx-registers of |
the processor, all limitations results from this. |
* The function can reinstall the breakpoint, previously set |
by it (and it does not inform on this). |
Carry on the list of set breakpoints in the debugger. |
* Breakpoints generate debug exception #DB, on which the system |
notifies debugger. |
* Breakpoints on write and read/write act after |
execution of the caused it instruction. |
====================================================================== |
==== Function 70 - work with file system with long names support. ==== |
====================================================================== |
Parameters: |
* eax = 70 |
* ebx = pointer to the information structure |
Returned value: |
* eax = 0 - success; otherwise file system error code |
* some subfunctions return value in other registers too |
General format of the information structure: |
* +0: dword: subfunction number |
* +4: dword: file offset |
* +8: dword: high dword of offset (must be 0) or flags field |
* +12 = +0xC: dword: size |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: n db: ASCIIZ-string with the filename |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with the filename |
Specifications - in documentation on the appropriate subfunction. |
Filename is case-insensitive. Russian letters must be written in |
the encoding cp866 (DOS). |
Format of filename: |
/base/number/dir1/dir2/.../dirn/file, |
where /base/number identifies device, on which file is located: |
one of |
* /RD/1 = /RAMDISK/1 to access ramdisk |
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive, |
/FD/2 = /FLOPPYDISK/2 to access second one |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices |
IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - partition number on the selected hard drive, varies from 1 |
to 255 (on each hard drive the indexing starts from 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 to access accordingly to |
CD on IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave) |
Examples: |
* '/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/2/menuet/pics/tanzania.bmp',0 |
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 |
Available subfunctions: |
* subfunction 0 - read file |
* subfunction 1 - read folder |
* subfunction 2 - create/rewrite file |
* subfunction 5 - get attributes of file/folder |
* subfunction 6 - set attributes of file/folder |
* subfunction 7 - start application |
For CD-drives due to hardware limitations only subfunctions |
0,1,5 and 7 are available, other subfunctions return error |
with code 2. |
====================================================================== |
=== Function 70, subfunction 0 - read file with long names support. == |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 0 = subfunction number |
* +4: dword: file offset (in bytes) |
* +8: dword: 0 (reserved for high dword of offset) |
* +12 = +0xC: dword: number of bytes to read |
* +16 = +0x10: dword: pointer to buffer for data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of read bytes or -1=0xffffffff if file was not found |
Remarks: |
* If file was ended before last requested block was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* The function does not allow to read folder (returns eax=10, |
access denied). |
====================================================================== |
== Function 70, subfunction 1 - read folder with long names support. = |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 1 = subfunction number |
* +4: dword: index of starting block (beginning from 0) |
* +8: dword: flags field: |
* bit 0 (mask 1): in what format to return names, |
0=ANSI, 1=UNICODE |
* other bits are reserved and must be set to 0 for the future |
compatibility |
* +12 = +0xC: dword: number of blocks to read |
* +16 = +0x10: dword: pointer to buffer for data, buffer size |
must be not less than 32 + [+12]*560 bytes |
* +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of files, information on which was written to |
the buffer, or -1=0xffffffff, if folder was not found |
Structure of the buffer: |
* +0: 32*byte: header |
* +32 = +0x20: n1*byte: block with information on file 1 |
* +32+n1: n2*byte: block with information on file 2 |
* ... |
Structure of header: |
* +0: dword: version of structure (current is 1) |
* +4: dword: number of placed blocks; is not greater than requested |
in the field +12 of information structure; can be less, if |
there are no more files in folder (the same as in ebx) |
* +8: dword: total number of files in folder |
* +12 = +0xC: 20*byte: reserved (zeroed) |
Structure of block of data for folder entry (BDFE): |
* +0: dword: attributes of file: |
* bit 0 (mask 1): file is read-only |
* bit 1 (mask 2): file is hidden |
* bit 2 (mask 4): file is system |
* bit 3 (mask 8): this is not a file but volume label |
(for one partition meets no more than once and |
only in root folder) |
* bit 4 (mask 0x10): this is a folder |
* bit 5 (mask 0x20): file was not archived - many archivation |
programs have an option to archive only files with this bit set, |
and after archiving this bit is cleared - it can be useful |
for automatically creating of backup-archives as at writing |
this bit is usually set |
* +4: byte: type of name data: |
(coincides with bit 0 of flags in the information structure) |
* 0 = ASCII = 1-byte representation of each character |
* 1 = UNICODE = 2-byte representation of each character |
* +5: 3*byte: reserved (zero) |
* +8: 4*byte: time of file creation |
* +12 = +0xC: 4*byte: date of file creation |
* +16 = +0x10: 4*byte: time of last access (read or write) |
* +20 = +0x14: 4*byte: date of last access |
* +24 = +0x18: 4*byte: time of last modification |
* +28 = +0x1C: 4*byte: date of last modification |
* +32 = +0x20: qword: file size in bytes (up to 16777216 Tb) |
* +40 = +0x28: name |
* for ASCII format: maximum length is 263 characters |
(263 bytes), byte after the name has value 0 |
* äëÿ ôîðìàòà UNICODE: maximum length is 259 characters |
(518 bytes), 2 bytes after the name have value 0 |
Time format: |
* +0: byte: seconds |
* +1: byte: minutes |
* +2: byte: hours |
* +3: byte: reserved (0) |
* for example, 23.59.59 is written as (in hex) 3B 3B 17 00 |
Date format: |
* +0: byte: day |
* +1: byte: month |
* +2: word: year |
* for example, 25.11.1979 is written as (in hex) 19 0B BB 07 |
Remarks: |
* If BDFE contains ASCII name, the length of BDFE is 304 bytes, |
if UNICODE name - 560 bytes. Value of length is aligned |
on 16-byte bound (to accelerate processing in CPU cache). |
* First character after a name is zero (ASCIIZ-string). The further |
data contain garbage. |
* If files in folder were ended before requested number was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* Any folder on the disk, except for root, contains two special |
entries "." and "..", identifying accordingly the folder itself |
and the parent folder. |
* The function allows also to read virtual folders "/", "/rd", |
"/fd", "/hd[n]", thus attributes of subfolders are set to 0x10, |
and times and dates are zeroed. An alternative way to get the |
equipment information - subfunction 11 of function 18. |
====================================================================== |
===================== Function 70, subfunction 2 ===================== |
============ Create/rewrite file with long names support. ============ |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 2 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: number of bytes to read |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of written bytes (possibly 0) |
Remarks: |
* If a file with given name did not exist, it is created; |
if it existed, it is rewritten. |
* If there is not enough free space on disk, the function will |
write as many as can and then return error code 8. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
==== Function 70, subfunction 5 - get information on file/folder. ==== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 5 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: pointer to buffer for data (40 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Information on file is returned in the BDFE format (block of data |
for folder entry), explained in the description of |
subfunction 1, but without filename |
(i.e. only first 40 = 0x28 bytes). |
Remarks: |
* The function does not support virtual folders such as /, /rd and |
root folders like /rd/1. |
====================================================================== |
===== Function 70, subfunction 6 - set attributes of file/folder. ==== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 6 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: pointer to buffer with attributes (32 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
File attributes are first 32 bytes in BDFE (block of data |
for folder entry), explained in the description of subfunction 1 |
(that is, without name and size of file). Attribute |
file/folder/volume label (bits 3,4 in dword +0) is not changed. |
Byte +4 (name format) is ignored. |
Remarks: |
* The function does not support virtual folders such as /, /rd and |
root folders like /rd/1. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
=========== Function 70, subfunction 7 - start application. ========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 7 = subfunction number |
* +4: dword: flags field: |
* áèò 0: start process as debugged |
* other bits are reserved and must be set to 0 |
* +8: dword: 0 or pointer to ASCIIZ-string with parameters |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax > 0 - program is loaded, eax contains PID |
* eax < 0 - an error has occured, -eax contains |
file system error code |
* ebx destroyed |
Remarks: |
* Command line must be terminated by the character with the code 0 |
(ASCIIZ-string); function takes into account either all characters |
up to terminating zero inclusively or first 256 character |
regarding what is less. |
* If the process is started as debugged, it is created in |
the suspended state; to run use subfunction 5 of function 69. |
====================================================================== |
========== Function 71, subfunction 1 - set window caption. ========== |
====================================================================== |
Parameters: |
* eax = 71 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to caption string |
Returned value: |
* function does not return value |
Remarks: |
* String must be in the ASCIIZ-format. Disregarding real string |
length, no more than 255 characters are drawn. |
* Pass NULL in ecx to remove caption. |
====================================================================== |
=============== Function -1 - terminate thread/process =============== |
====================================================================== |
Parameters: |
* eax = -1 - function number |
Returned value: |
* function does not return neither value nor control |
Remarks: |
* If the process did not create threads obviously, it has only |
one thread, which termination results in process termination. |
* If the current thread is last in the process, its termination |
also results in process terminates. |
* This function terminates the current thread. Other thread can be |
killed by call to subfunction 2 of function 18. |
====================================================================== |
=========================== List of events =========================== |
====================================================================== |
Next event can be retrieved by the call of one from functions 10 |
(to wait for event), 11 (to check without waiting), 23 |
(to wait during the given time). |
These functions return only those events, which enter into a mask set |
by function 40. By default it is first three, |
there is enough for most applications. |
Codes of events: |
* 1 = redraw event (is reset by call to function 0) |
* 2 = key on keyboard is pressed (acts, only when the window is |
active) or hotkey is pressed; is reset, when all keys from |
the buffer are read out by function 2 |
* 3 = button is pressed, defined earlier by function 8 |
(or close button, created implicitly by function 0; |
minimize button is handled by the system and sends no message; |
acts, only when the window is active; |
is reset when all buttons from the buffer |
are read out by function 17) |
* 4 = reserved (in current implementation never comes even after |
unmasking by function 40) |
* 5 = the desktop background is redrawed (is reset automatically |
after redraw, so if in redraw time program does not wait and |
does not check events, it will not remark this event) |
* 6 = mouse event (something happened - button pressing or moving; |
is reset at reading) |
* 7 = IPC event (see function 60 - |
Inter Process Communication; is reset at reading) |
* 8 = network event (is reset at reading) |
* 9 = debug event (is reset at reading; see |
debug subsystem) |
* 16..31 = event with appropriate IRQ |
(16=IRQ0, 31=IRQ15) (is reset after reading all IRQ data) |
====================================================================== |
=================== Error codes of the file system =================== |
====================================================================== |
* 0 = success |
* 1 = base and/or partition of a hard disk is not defined |
(by subfunctions 7, 8 of function 21) |
* 2 = function is not supported for the given file system |
* 3 = unknown file system |
* 4 = is returned only from function 'rename' by transmission of |
the strongly incorrect parameter and in any way does not |
correspond to the description in the kernel sources |
"partition not defined at hd" |
* 5 = file not found |
* 6 = end of file, EOF |
* 7 = pointer lies outside of application memory |
* 8 = disk is full |
* 9 = FAT table is destroyed |
* 10 = access denied |
* 11 = device error |
Application start functions can return also following errors: |
* 30 = 0x1E = not enough memory |
* 31 = 0x1F = file is not executable |
* 32 = 0x20 = too many processes |
/kernel/branches/gfx_kernel/fs/fat12.inc |
---|
0,0 → 1,2074 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; FAT12.INC ;; |
;; (C) 2005 Mario79, License: GPL ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
n_sector dd 0 ; temporary save for sector value |
flp_status dd 0 |
clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write |
path_pointer_flp dd 0 |
pointer_file_name_flp dd 0 |
save_root_flag db 0 |
save_flag db 0 |
root_read db 0 ; 0-necessary to load root, 1-not to load root |
flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat |
flp_number db 0 ; 1- Floppy A, 2-Floppy B |
old_track db 0 ; old value track |
flp_label rb 15 ; Label and ID of inserted floppy disk |
reserve_flp: |
cli |
cmp [flp_status],0 |
je reserve_flp_ok |
sti |
call change_task |
jmp reserve_flp |
reserve_flp_ok: |
push eax |
mov eax,[0x3000] |
shl eax,5 |
mov eax,[eax+0x3000+TASKDATA.pid] |
mov [flp_status],eax |
pop eax |
sti |
ret |
floppy_free_space: |
;--------------------------------------------- |
; |
; returns free space in edi |
; |
;--------------------------------------------- |
push eax ebx ecx |
call read_flp_fat |
cmp [FDC_Status],0 |
jne fdc_status_error_2 |
mov eax,0x282000 |
xor edi,edi |
mov ecx,2847 ;1448000/512 |
rdfs1_1: |
mov ebx,[eax] |
and ebx,4095 |
jne rdfs2_1 |
add edi,512 |
rdfs2_1: |
add eax,2 |
loop rdfs1_1 |
fdc_status_error_2: |
pop ecx ebx eax |
ret |
floppy_fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars - for root directory |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X |
; edi pointer to path /fd/1/...... - for all files in nested directories |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; 10 = access denied |
;-------------------------------------------------------------- |
mov [save_flag],0 |
mov [path_pointer_flp],edi |
cmp esi,0 ; return ramdisk root |
jne fr_noroot_1 |
cmp ebx,224/16 |
jbe fr_do_1 |
mov eax,5 |
mov ebx,0 |
mov [flp_status],0 |
ret |
fr_do_1: |
push ebx ecx edx |
call read_flp_root |
pop edx ecx ebx |
cmp [FDC_Status],0 |
jne fdc_status_error_1 |
mov edi,edx |
dec ebx |
shl ebx,9 |
mov esi,0x8000 |
add esi,ebx |
shl ecx,9 |
cld |
rep movsb |
mov eax,0 ; ok read |
mov ebx,0 |
mov [flp_status],0 |
ret |
fdc_status_error_1: |
mov [flp_status],0 |
mov eax,10 |
mov ebx,-1 |
ret |
fr_noroot_1: |
sub esp,32 |
call expand_filename |
frfloppy_1: |
cmp ebx,0 |
jne frfl5_1 |
mov ebx,1 |
frfl5_1: |
cmp ecx,0 |
jne frfl6_1 |
mov ecx,1 |
frfl6_1: |
dec ebx |
push eax |
push eax ebx ecx edx esi edi |
call read_flp_fat |
cmp [FDC_Status],0 |
jne fdc_status_error_3_1 |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
call SeekTrack |
mov dh,14 |
l.20_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error_3_1 |
mov dl,16 |
mov edi,0xD000 |
inc [FDD_Sector] |
l.21_1: |
mov esi,eax ;Name of file we want |
mov ecx,11 |
cld |
rep cmpsb ;Found the file? |
je fifound_1 ;Yes |
add ecx,21 |
add edi, ecx ;Advance to next entry |
dec dl |
cmp dl,0 |
jne l.21_1 |
dec dh |
cmp dh,0 |
jne l.20_1 |
fdc_status_error_3: |
mov eax,5 ; file not found ? |
mov ebx,-1 |
add esp,32+28 |
mov [flp_status],0 |
ret |
fdc_status_error_3_2: |
cmp [FDC_Status],0 |
je fdc_status_error_3 |
fdc_status_error_3_1: |
add esp,32+28 |
jmp fdc_status_error_1 |
fifound_1: |
mov eax,[path_pointer_flp] |
cmp [eax+36],byte 0 |
je fifound_2 |
add edi,0xf |
mov eax,[edi] |
and eax,65535 |
mov ebx,[path_pointer_flp] |
add ebx,36 |
call get_cluster_of_a_path_flp |
jc fdc_status_error_3_2 |
mov ebx,[ebx-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
jmp fifound_3 |
fifound_2: |
mov ebx,[edi-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
add edi,0xf |
mov eax,[edi] |
fifound_3: |
and eax,65535 |
mov [n_sector],eax ;eax=cluster |
frnew_1: |
add eax,31 ;bootsector+2*fat+filenames |
cmp [esp+16],dword 0 ; wanted cluster ? |
jne frfl7_1 |
call read_chs_sector |
cmp [FDC_Status],0 |
jne fdc_status_error_5 |
mov edi,[esp+8] |
call give_back_application_data_1 |
add [esp+8],dword 512 |
dec dword [esp+12] ; last wanted cluster ? |
cmp [esp+12],dword 0 |
je frnoread_1 |
jmp frfl8_1 |
frfl7_1: |
dec dword [esp+16] |
frfl8_1: |
mov edi,[n_sector] |
shl edi,1 ;find next cluster from FAT |
add edi,0x282000 |
mov eax,[edi] |
and eax,4095 |
mov edi,eax |
mov [n_sector],edi |
cmp edi,4095 ;eof - cluster |
jz frnoread2_1 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread_1 |
sub [esp+24],dword 512 |
jmp frnew_1 |
read_chs_sector: |
call calculate_chs |
call ReadSectWithRetr |
ret |
frnoread2_1: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread_1 |
mov [fdc_irq_func],fdc_null |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
mov [flp_status],0 |
ret |
frnoread_1: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,0 |
mov [flp_status],0 |
ret |
fdc_status_error_5: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
jmp fdc_status_error_1 |
read_flp_root: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_root_read |
cmp [root_read],1 |
je unnecessary_root_read |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov edi,0x8000 |
call SeekTrack |
read_flp_root_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_root_read |
push edi |
call give_back_application_data_1 |
pop edi |
add edi,512 |
inc [FDD_Sector] |
cmp [FDD_Sector],16 |
jne read_flp_root_1 |
mov [root_read],1 |
unnecessary_root_read: |
popa |
ret |
read_flp_fat: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
cmp [flp_fat],1 |
je unnecessary_flp_fat |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov edi,0x8000 |
call SeekTrack |
read_flp_fat_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
push edi |
call give_back_application_data_1 |
pop edi |
add edi,512 |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne read_flp_fat_1 |
mov [FDD_Sector],1 |
mov [FDD_Head],1 |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
call give_back_application_data_1 |
call calculatefatchain_flp |
mov [root_read],0 |
mov [flp_fat],1 |
unnecessary_flp_fat: |
popa |
ret |
calculatefatchain_flp: |
pushad |
mov esi,0x8000 |
mov edi,0x282000 |
fcnew_1: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
mov ecx,dword [esi+8] |
mov edx,ecx |
shr edx,4 ;8 ok |
shr dx,4 ;7 ok |
xor ch,ch |
shld ecx,ebx,20 ;6 ok |
shr cx,4 ;5 ok |
shld ebx,eax,12 |
and ebx,0x0fffffff ;4 ok |
shr bx,4 ;3 ok |
shl eax,4 |
and eax,0x0fffffff ;2 ok |
shr ax,4 ;1 ok |
mov dword [edi],eax |
add edi,4 |
mov dword [edi],ebx |
add edi,4 |
mov dword [edi],ecx |
add edi,4 |
mov dword [edi],edx |
add edi,4 |
add esi,12 |
cmp edi,0x282000+2856*2 ;2849 clusters |
jnz fcnew_1 |
popad |
ret |
check_label: |
pushad |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
call SetUserInterrupts |
call FDDMotorON |
call RecalibrateFDD |
cmp [FDC_Status],0 |
jne fdc_status_error |
call SeekTrack |
cmp [FDC_Status],0 |
jne fdc_status_error |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error |
mov esi,flp_label |
mov edi,0xD000+39 |
mov ecx,15 |
cld |
rep cmpsb |
je same_label |
mov [root_read],0 |
mov [flp_fat],0 |
same_label: |
mov esi,0xD000+39 |
mov edi,flp_label |
mov ecx,15 |
cld |
rep movsb |
popad |
ret |
fdc_status_error: |
popad |
ret |
save_flp_root: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_root_save |
cmp [root_read],0 |
je unnecessary_root_save |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov esi,0x8000 |
call SeekTrack |
save_flp_root_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_root_save |
inc [FDD_Sector] |
cmp [FDD_Sector],16 |
jne save_flp_root_1 |
unnecessary_root_save: |
mov [fdc_irq_func],fdc_null |
popa |
ret |
save_flp_fat: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
cmp [flp_fat],0 |
je unnecessary_flp_fat_save |
call restorefatchain_flp |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov esi,0x8000 |
call SeekTrack |
save_flp_fat_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_flp_fat_1 |
mov [FDD_Sector],1 |
mov [FDD_Head],1 |
call take_data_from_application_1 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
mov [root_read],0 |
unnecessary_flp_fat_save: |
mov [fdc_irq_func],fdc_null |
popa |
ret |
restorefatchain_flp: ; restore fat chain |
pushad |
mov esi,0x282000 |
mov edi,0x8000 |
fcnew2_1: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
shl ax,4 |
shl eax,4 |
shl bx,4 |
shr ebx,4 |
shrd eax,ebx,8 |
shr ebx,8 |
mov dword [edi],eax |
add edi,4 |
mov word [edi],bx |
add edi,2 |
add esi,8 |
cmp edi,0x8000+0x1200 ;4274 bytes - all used FAT |
jb fcnew2_1 |
mov esi,0x8000 ; duplicate fat chain |
mov edi,0x8000+0x1200 |
mov ecx,0x1200/4 |
cld |
rep movsd |
popad |
ret |
floppy_filedelete: |
;-------------------------------------------- |
; |
; filedelete - sys floppy |
; in: |
; eax - filename 11 chars - for root directory |
; edi pointer to path /fd/1/...... - for all files in nested directories |
; |
; out: |
; eax - 0 = successful, 1 = file not found, 10 = access denied |
; |
;-------------------------------------------- |
mov [path_pointer_flp],edi |
mov [save_flag],0 |
mov ebp,1 ; file not found as default |
filedelete_newtry_1: |
sub esp,32 |
call expand_filename |
push eax ebx ecx edx esi edi |
call read_flp_fat |
cmp [FDC_Status],0 |
jne frnoreadd_1 |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
call SeekTrack |
mov dh,14 |
l.20_2: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error_4 |
mov dl,16 |
mov edi,0xD000 |
inc [FDD_Sector] |
l.21_2: |
mov esi,eax ;Name of file we want |
mov ecx,11 |
cld |
rep cmpsb ;Found the file? |
je fifoundd_1 ;Yes |
add ecx,21 |
add edi, ecx ;Advance to next entry |
dec dl |
jne l.21_2 |
dec dh |
jne l.20_2 |
jmp frnoreadd_1 |
fdc_status_error_4: |
pop edi esi edx ecx ebx eax |
add esp,32 |
jmp fdc_status_error_1 |
fifoundd_1: |
mov eax,[path_pointer_flp] |
cmp [eax+36],byte 0 |
je fifoundd_2 |
movzx eax, word [edi+0xf] |
mov ebx,[path_pointer_flp] |
add ebx,36 |
call get_cluster_of_a_path_flp |
jc frnoreadd_1_1 |
mov edi,ebx |
add edi,11 |
jmp fifoundd_2_1 |
fifoundd_2: |
dec [FDD_Sector] |
fifoundd_2_1: |
mov [edi-11],byte 0xE5 ;mark filename deleted |
movzx edi, word [edi+0xf] ;edi = cluster |
frnewd_1: |
shl edi,1 ;find next cluster from FAT |
add edi,0x282000 |
mov eax,[edi] |
mov [edi],word 0x0 ;clear fat chain cluster |
and eax,4095 |
mov edi,eax |
cmp edi,dword 4095 ;last cluster ? |
jz frnoreadd2_1 |
jmp frnewd_1 |
frnoreadd2_1: |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error_4 |
call save_flp_fat |
cmp [FDC_Status],0 |
jne fdc_status_error_4 |
; pop edi esi edx ecx ebx eax |
; add esp,32 |
mov ebp,0 ; file found |
; jmp filedelete_newtry_1 |
jmp frnoreadd_1 |
frnoreadd_1_1: |
cmp [FDC_Status],0 |
jne fdc_status_error_4 |
frnoreadd_1: |
pop edi esi edx ecx ebx eax |
add esp,32 |
mov eax,ebp |
ret |
floppy_filesave: |
;---------------------------------------------------------- |
; |
; filesave - sys floppy |
; |
; eax ; pointer to file name 11 chars - for root directory |
; ebx ; buffer |
; ecx ; count to write in bytes |
; edx ; 0 create new , 1 append |
; edi pointer to path /fd/1/...... - for all files in nested directories |
; |
; output : eax = 0 - ok |
; 5 - file not found / directory not found |
; 8 - disk full |
; 10 - access denied |
;----------------------------------------------------------- |
mov [path_pointer_flp],edi |
sub esp,32 |
call expand_filename |
cmp edx,0 |
jnz fsdel_1 |
pusha |
call floppy_filedelete |
cmp [FDC_Status],0 |
jne fdc_status_error_6 |
popa |
mov [save_flag],1 |
fsdel_1: |
call floppy_free_space |
cmp [FDC_Status],0 |
jne fdc_status_error_6 |
cmp ecx,edi |
jb rd_do_save_1 |
add esp,32 |
mov eax,8 ; not enough free space |
mov [flp_status],0 |
ret |
fdc_status_error_6: |
popa |
add esp,32 |
jmp fdc_status_error_1 |
rd_do_save_1: |
push eax ebx ecx edx esi edi |
call read_flp_fat |
cmp [FDC_Status],0 |
jne fdc_status_error_7 |
push eax |
mov eax,[path_pointer_flp] |
cmp [eax+36],byte 0 |
jne fifoundds_2 |
pop eax |
mov [save_root_flag],1 |
call read_flp_root |
cmp [FDC_Status],0 |
jne fdc_status_error_7 |
mov edi,0x8000 ;Point at directory |
mov edx,224 +1 |
; find an empty spot for filename in the root dir |
l20ds_1: |
sub edx,1 |
jz frnoreadds_1 |
l21ds_1: |
cmp [edi],byte 0xE5 |
jz fifoundds_1 |
cmp [edi],byte 0x0 |
jz fifoundds_1 |
add edi,32 ; Advance to next entry |
jmp l20ds_1 |
fifoundds_2: |
pop eax |
mov [save_root_flag],0 |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
call SeekTrack |
mov dh,14 |
l.20_3: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error_7 |
mov dl,16 |
mov edi,0xD000 |
inc [FDD_Sector] |
l.21_3: |
mov esi,eax ;Name of file we want |
mov ecx,11 |
cld |
rep cmpsb ;Found the file? |
je fifoundds_3 ;Yes |
add ecx,21 |
add edi, ecx ;Advance to next entry |
dec dl |
jne l.21_3 |
dec dh |
jne l.20_3 |
fdc_status_error_8: |
pop edi esi edx ecx ebx eax |
mov eax,5 ; file not found ? |
mov ebx,-1 |
add esp,32 |
mov [flp_status],0 |
ret |
fifoundds_3: |
add edi,0xf |
mov eax,[edi] |
and eax,65535 |
mov ebx,[path_pointer_flp] |
add ebx,36 |
call get_cluster_of_a_path_flp |
jc fdc_status_error_7_1 |
found_directory_for_writing_flp: |
call analyze_directory_to_write_flp |
jc fdc_status_error_7_1 |
mov edi,ebx |
fifoundds_1: |
push edi ; move the filename to root dir |
mov esi,[esp+4+20] |
cmp [save_root_flag],0 |
jne fifoundds_4 |
mov esi,[pointer_file_name_flp] |
fifoundds_4: |
mov ecx,11 |
cld |
rep movsb |
pop edi |
mov edx,edi |
add edx,11+0xf ; edx <- cluster save position |
mov ebx,[esp+12] ; save file size |
mov [edi+28],ebx |
mov [edi+11],byte 0x20 ; attribute |
call get_date_for_file ; from FAT32.INC |
mov [edi+24],ax ; date |
mov [edi+18],ax ; date |
call get_time_for_file ; from FAT32.INC |
mov [edi+22],ax ; time |
xor ax,ax |
mov [edi+20],ax |
mov ebx,1 ; first cluster |
cmp [save_root_flag],0 |
jne frnewds_1 |
call frnewds_2 |
pusha |
call WriteSectWithRetr |
popa |
cmp [FDC_Status],0 |
jne fdc_status_error_7 |
jmp frnewds_3 |
frnewds_1: |
call frnewds_2 |
frnewds_3: |
pusha ; move save to floppy cluster |
add ebx,31 |
mov eax,ebx |
mov esi,[esp+32+16] |
call take_data_from_application_1 |
call save_chs_sector |
cmp [FDC_Status],0 |
jne fdc_status_error_7 |
popa |
mov eax,[esp+12] |
cmp eax,512 |
jb flnsa_1 |
sub eax,512 |
mov [esp+12],eax |
mov eax,[esp+16] |
add eax,512 |
mov [esp+16],eax |
jmp frnewds_1 |
frnewds_2: |
add ebx,1 |
mov edi,ebx ; find free cluster in FAT |
shl edi,1 |
add edi,0x282000 |
mov eax,[edi] |
and eax,4095 |
jnz frnewds_2 |
mov [edx],bx ; save next cluster pos. to prev cl. |
mov edx,edi ; next save pos abs mem add |
ret |
flnsa_1: |
mov [edi],word 4095 ; mark end of file - last cluster |
cmp [save_root_flag],1 |
jne flnsa_2 |
call save_flp_root |
cmp [FDC_Status],0 |
jne fdc_status_error_7 |
flnsa_2: |
call save_flp_fat |
cmp [FDC_Status],0 |
jne fdc_status_error_7 |
frnoreadds_1: |
pop edi esi edx ecx ebx eax |
add esp,32 |
mov eax,0 |
mov [flp_status],0 |
ret |
fdc_status_error_7_1: |
cmp [FDC_Status],0 |
je fdc_status_error_8 |
fdc_status_error_7: |
pop edi esi edx ecx ebx eax |
add esp,32 |
jmp fdc_status_error_1 |
save_chs_sector: |
call calculate_chs |
call WriteSectWithRetr |
ret |
calculate_chs: |
mov bl,[FDD_Track] |
mov [old_track],bl |
mov ebx,18 |
xor edx,edx |
div ebx |
inc edx |
mov [FDD_Sector],dl |
xor edx,edx |
mov ebx,2 |
div ebx |
mov [FDD_Track],al |
mov [FDD_Head],0 |
cmp edx,0 |
je no_head_2 |
inc [FDD_Head] |
no_head_2: |
mov dl,[old_track] |
cmp dl,[FDD_Track] |
je no_seek_track_1 |
call SeekTrack |
no_seek_track_1: |
ret |
get_cluster_of_a_path_flp: |
;--------------------------------------------------------- |
; input : EBX = pointer to a path string |
; (example: the path "/files/data/document" become |
; "files......data.......document...0" |
; '.' = space char |
; '0' = char(0) (ASCII=0) !!! ) |
; output : if (CARRY=1) -> ERROR in the PATH |
; if (CARRY=0) -> EAX=cluster |
;--------------------------------------------------------- |
push edx |
mov edx,ebx |
search_end_of_path_flp: |
cmp [save_flag],0 |
jne search_end_of_path_flp_1 |
cmp byte [edx],0 |
je found_end_of_path_flp |
jmp search_end_of_path_flp_2 |
search_end_of_path_flp_1: |
cmp byte [edx+12],0 |
je found_end_of_path_flp |
search_end_of_path_flp_2: |
inc edx ; '/' |
call analyze_directory_flp |
jc directory_not_found_flp |
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field |
mov ax,[ebx+26] ; read the LOW 16bit cluster field |
and eax,0xfff ;[fatMASK] |
add edx,11 ; 8+3 (name+extension) |
jmp search_end_of_path_flp |
found_end_of_path_flp: |
inc edx |
mov [pointer_file_name_flp],edx |
pop edx |
clc ; no errors |
ret |
directory_not_found_flp: |
pop edx |
stc ; errors occour |
ret |
analyze_directory_flp: |
;-------------------------------- |
; input : EAX = first cluster of the directory |
; EBX = pointer to filename |
; output : IF CARRY=0 EAX = sector where th file is found |
; EBX = pointer in buffer |
; [buffer .. buffer+511] |
; ECX,EDX,EDI,EDI not changed |
; IF CARRY=1 |
;-------------------------------- |
push ebx ;[esp+16] |
push ecx |
push edx |
push esi |
push edi |
adr56_flp: |
mov [clust_tmp_flp],eax |
add eax,31 |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status],0 |
jne not_found_file_analyze_flp |
mov ecx,512/32 |
mov ebx,0xD000 |
adr1_analyze_flp: |
mov esi,edx ;[esp+16] |
mov edi,ebx |
cld |
push ecx |
mov ecx,11 |
rep cmpsb |
pop ecx |
je found_file_analyze_flp |
add ebx,32 |
loop adr1_analyze_flp |
mov eax,[clust_tmp_flp] |
shl eax,1 ;find next cluster from FAT |
add eax,0x282000 |
mov eax,[eax] |
and eax,4095 |
cmp eax,0x0ff8 |
jb adr56_flp |
not_found_file_analyze_flp: |
pop edi |
pop esi |
pop edx |
pop ecx |
add esp,4 |
stc ;file not found |
ret |
found_file_analyze_flp: |
pop edi |
pop esi |
pop edx |
pop ecx |
add esp,4 |
clc ;file found |
ret |
analyze_directory_to_write_flp: |
;-------------------------------- |
; input : EAX = first cluster of the directory |
; output : IF CARRY=0 EAX = sector where the file is found |
; EBX = pointer in buffer |
; [buffer .. buffer+511] |
; ECX,EDX,EDI,EDI not changed |
; IF CARRY=1 |
;-------------------------------- |
push ecx |
push edx |
push esi |
adr561: |
mov [clust_tmp_flp],eax |
add eax,31 |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status],0 |
jne error_found_file_analyze1 |
mov ecx,512/32 |
mov ebx,0xD000 |
adr1_analyze1: |
cmp byte [ebx],0x00 |
je found_file_analyze1 |
cmp byte [ebx],0xe5 |
je found_file_analyze1 |
avanti: |
add ebx,32 |
loop adr1_analyze1 |
mov eax,[clust_tmp_flp] |
shl eax,1 ;find next cluster from FAT |
add eax,0x282000 |
mov eax,[eax] |
and eax,4095 |
cmp eax,0x0ff8 |
jb adr561 |
call get_free_FAT ;this block of code add a new cluster |
;for the directory because the directory |
;is full |
mov [edi],word 0x0fff |
mov eax,[clust_tmp_flp] |
shl eax,1 ;find next cluster from FAT |
add eax,0x282000 |
sub edi,0x282000 |
mov [eax],di |
pusha |
mov ecx,512/4 |
xor eax,eax |
mov edi,0xD000 |
cld |
rep stosd |
popa |
mov eax,edi |
add eax,31 |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status],0 |
jne error_found_file_analyze1 |
mov ebx,0xD000 |
found_file_analyze1: |
pop esi |
pop edx |
pop ecx |
clc ;file found |
ret |
error_found_file_analyze1: |
pop esi |
pop edx |
pop ecx |
stc |
ret |
get_free_FAT_flp: |
;------------------------------------------ |
; input : EAX = # cluster for start the searching |
; output : EAX = # first cluster found free |
;------------------------------------------- |
push ebx |
mov ebx,1 |
check_new_flp: |
add ebx,1 |
mov edi,ebx ; find free cluster in FAT |
shl edi,1 |
add edi,0x282000 |
mov eax,[edi] |
and eax,4095 |
cmp eax,0x0 |
jnz check_new_flp |
pop ebx |
ret |
; \begin{diamond} |
fat_find_lfn: |
; in: esi->name |
; [esp+4] = next |
; [esp+8] = first |
; [esp+C]... - possibly parameters for first and next |
; out: CF=1 - file not found |
; else CF=0, esi->next name component, edi->direntry |
pusha |
lea eax, [esp+0Ch+20h] |
call dword [eax-4] |
jc .reterr |
sub esp, 262*2 ; reserve place for LFN |
mov ebp, esp |
push 0 ; for fat_get_name: read ASCII name |
.l1: |
call fat_get_name |
jc .l2 |
call fat_compare_name |
jz .found |
.l2: |
lea eax, [esp+0Ch+20h+262*2+4] |
call dword [eax-8] |
jnc .l1 |
add esp, 262*2+4 |
.reterr: |
stc |
popa |
ret |
.found: |
add esp, 262*2+4 |
; if this is LFN entry, advance to true entry |
cmp byte [edi+11], 0xF |
jnz @f |
lea eax, [esp+0Ch+20h] |
call dword [eax-8] |
jc .reterr |
@@: |
add esp, 8 ; CF=0 |
push esi |
push edi |
popa |
ret |
flp_root_next: |
cmp edi, 0xD200-0x20 |
jae @f |
add edi, 0x20 |
ret ; CF=0 |
@@: |
; read next sector |
inc dword [eax] |
cmp dword [eax], 14 |
jae flp_root_first.readerr |
flp_root_first: |
mov eax, [eax] |
pusha |
add eax, 19 |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .readerr |
mov edi, 0xD000 |
ret ; CF=0 |
.readerr: |
stc |
ret |
flp_rootmem_first: |
mov edi, 0x8000 |
clc |
ret |
flp_rootmem_next: |
add edi, 0x20 |
cmp edi, 0x8000+14*0x200 |
cmc |
flp_rootmem_next_write: |
flp_rootmem_begin_write: |
flp_rootmem_end_write: |
ret |
flp_rootmem_extend_dir: |
stc |
ret |
flp_notroot_next: |
cmp edi, 0xD200-0x20 |
jae flp_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
flp_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
mov ecx, [ecx*2+0x282000] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae flp_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
flp_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
pusha |
add eax, 31 |
call read_chs_sector |
popa |
mov edi, 0xD000 |
cmp [FDC_Status], 0 |
jnz .err |
ret ; CF=0 |
.err2: |
pop ecx |
.err: |
stc |
ret |
flp_notroot_begin_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call read_chs_sector |
popa |
ret |
flp_notroot_end_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call save_chs_sector |
popa |
ret |
flp_notroot_next_write: |
cmp edi, 0xD200 |
jae @f |
ret |
@@: |
call flp_notroot_end_write |
jmp flp_notroot_next_sector |
flp_notroot_extend_dir: |
; find free cluster in FAT |
pusha |
xor eax, eax |
mov edi, 0x282000 |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF ; mark as last cluster |
sub edi, 0x282000 |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [0x282000+ecx*2], di |
mov [eax], edi |
xor eax, eax |
mov edi, 0xD000 |
mov ecx, 128 |
rep stosd |
popa |
call flp_notroot_end_write |
mov edi, 0xD000 |
clc |
ret |
.notfound: |
popa |
stc |
ret |
fd_find_lfn: |
; in: esi->name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry, eax=directory cluster (0 for root) |
push esi edi |
push 0 |
push flp_root_first |
push flp_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] ; cluster |
mov [esp+8], eax |
mov dword [esp+4], flp_notroot_first |
mov dword [esp], flp_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
mov eax, [esp+8] |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRead - LFN variant for reading floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyRead: |
call read_flp_fat |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call fd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
sub ebx, 512 |
jae .skip |
lea eax, [edi+31] |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .err |
lea eax, [0xD000+ebx+512] |
neg ebx |
push ecx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
.skip: |
movzx edi, word [edi*2+0x282000] |
jmp .new |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
jmp .reteof |
.err: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
mov al, 11 |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyReadFolder - LFN variant for reading floppy folders |
; |
; esi points to filename |
; ebx pointer to structure: 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyReadFolder: |
call read_flp_fat |
push edi |
cmp byte [esi], 0 |
jz .root |
call fd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read files |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov esi, edi ; esi points to BDFE |
.main_loop: |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
mov edi, 0xD000 |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
cmp edi, 0xD200 |
jb .do_bdfe |
pop eax |
inc eax |
dec byte [esp+262*2+12] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+0x282000] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+12], 0 |
@@: |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
mov edi, 0xD000 |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec ebx |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
cmp edi, 0xD200 |
jb .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+12] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+0x282000] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+12], 0 |
@@: |
jmp .main_loop |
.error: |
add esp, 262*2+4 |
pop ebp ecx edi edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx edi edi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRewrite - LFN variant for writing sys floppy |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fsfrfe2: |
popad |
fsfrfe: |
mov eax, 11 |
xor ebx, ebx |
ret |
fs_FloppyRewrite: |
cmp byte [esi], 0 |
jz @b |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz fsfrfe |
pushad |
xor ebp, ebp |
push esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea ebp, [esi-1] |
jmp @b |
@@: |
pop esi |
test ebp, ebp |
jnz .noroot |
call read_flp_root |
cmp [FDC_Status], 0 |
jnz fsfrfe2 |
push flp_rootmem_extend_dir |
push flp_rootmem_end_write |
push flp_rootmem_next_write |
push flp_rootmem_begin_write |
xor ebp, ebp |
push ebp |
push flp_rootmem_first |
push flp_rootmem_next |
jmp .common1 |
.noroot: |
; check existence |
mov byte [ebp], 0 |
call fd_find_lfn |
mov byte [ebp], '/' |
lea esi, [ebp+1] |
jnc @f |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push flp_notroot_extend_dir |
push flp_notroot_end_write |
push flp_notroot_next_write |
push flp_notroot_begin_write |
push ebp |
push flp_notroot_first |
push flp_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found; must not be directory |
test byte [edi+11], 10h |
jz @f |
add esp, 28 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [0x282000 + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 28 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+28 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <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 |
jnc .scan_dir |
.fsfrfe3: |
add esp, 8+8+12+28 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [FDC_Status], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+16] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+28 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+12] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
.doit: |
lea eax, [esp+8] |
call dword [eax+12] ; flush directory |
push ecx |
push edi |
add edi, 26 ; edi points to low word of cluster |
push edi |
mov esi, edx |
jecxz .done |
mov ecx, 2849 |
mov edi, 0x282000 |
push 0 ; first cluster |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
mov al, ERROR_DISK_FULL |
jnz .ret |
dec edi |
dec edi |
lea eax, [edi-0x282000] |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
cmp dword [esp], 0 |
jz .first |
xchg edi, [esp+4] |
stosw |
mov edi, [esp+4] |
jmp @f |
.first: |
mov [esp], eax |
@@: |
inc ecx |
; write data |
push ecx edi |
mov ecx, 512 |
cmp dword [esp+20], ecx |
jae @f |
mov ecx, [esp+20] |
@@: |
push ecx |
mov edi, 0xD000 |
rep movsb |
pop ecx |
push ecx |
sub ecx, 512 |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
add eax, 31 |
pusha |
call save_chs_sector |
popa |
pop ecx |
cmp [FDC_Status], 0 |
jnz .diskerr |
sub [esp+20], ecx |
pop edi ecx |
jnz .write_loop |
.done: |
xor eax, eax |
.ret: |
pop ebx edi edi ecx |
mov [esp+28+28], eax |
lea eax, [esp+8] |
call dword [eax+4] |
mov [edi+26], bx |
mov ebx, esi |
sub ebx, edx |
mov [edi+28], ebx |
call dword [eax+12] |
mov [esp+28+16], ebx |
test ebp, ebp |
jnz @f |
call save_flp_root |
@@: |
add esp, 28 |
cmp [FDC_Status], 0 |
jnz .err3 |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .err3 |
popa |
ret |
.err3: |
popa |
mov al, 11 |
xor ebx, ebx |
ret |
.diskerr: |
sub esi, ecx |
mov eax, 11 |
pop edi ecx |
jmp .ret |
fs_FloppyGetFileInfo: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call fd_find_lfn |
jmp fs_GetFileInfo_finish |
ret11: |
mov eax, 11 |
ret |
fs_FloppySetFileInfo: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call fd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push eax |
call bdfe_to_fat_entry |
pop eax |
test eax, eax |
jz .root |
add eax, 31 |
pusha |
call save_chs_sector |
popa |
jmp .cmn |
.root: |
call save_flp_root |
.cmn: |
pop edi |
xor eax, eax |
cmp [FDC_Status], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyExecute - LFN variant for executing from floppy |
; |
; esi points to floppy filename (e.g. 'dir1/name') |
; ebp points to full filename (e.g. '/fd/1/dir1/name') |
; dword [ebx] = flags |
; dword [ebx+4] = cmdline |
; |
; ret ebx,edx destroyed |
; eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
fs_FloppyExecute: |
mov edx, [ebx] |
mov ebx, [ebx+4] |
test ebx, ebx |
jz @f |
add ebx, std_application_base_address |
@@: |
;---------------------------------------------------------------- |
; |
; fs_FloppyExecute.flags - second entry |
; |
; esi points to floppy filename (kernel address) |
; ebp points to full filename |
; edx flags |
; ebx cmdline (kernel address) |
; |
; ret eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
.flags: |
call read_flp_fat |
cmp byte [esi], 0 |
jnz @f |
; cannot execute root! |
mov eax, -ERROR_ACCESS_DENIED |
ret |
@@: |
push edi |
call fd_find_lfn |
jnc .found |
pop edi |
mov eax, -ERROR_FILE_NOT_FOUND |
ret |
.found: |
movzx eax, word [edi+26] ; cluster |
push eax |
push dword [edi+28] ; size |
push .DoRead |
call fs_execute |
add esp, 12 |
pop edi |
ret |
.DoRead: |
; read next block |
; in: eax->parameters, edi->buffer |
; out: eax = error code |
pushad |
cmp dword [eax], 0 ; file size |
jz .eof |
mov eax, [eax+4] ; cluster |
add eax, 31 |
call read_chs_sector |
cmp [FDC_Status], 0 |
jnz .err |
pop edi |
mov esi, 0xD000 |
push edi |
mov ecx, 512/4 |
rep movsd |
mov eax, [esp+28] |
mov ecx, [eax] |
sub ecx, 512 |
jae @f |
add edi, ecx |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
@@: |
mov [eax], ecx |
mov edx, [eax+4] |
mov dx, [edx*2+0x282000] |
mov [eax+4], dx ; high word is already zero |
popad |
xor eax, eax |
ret |
.eof: |
popad |
mov eax, 6 |
ret |
.err: |
popad |
mov eax, 11 |
ret |
; \end{diamond} |
/kernel/branches/gfx_kernel/fs/fat32.inc |
---|
0,0 → 1,3967 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; FAT32.INC ;; |
;; ;; |
;; FAT16/32 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; |
;; ;; |
;; See file COPYING for details ;; |
;; 23.06.2006 LFN start application - diamond ;; |
;; 15.06.2006 LFN get/set file/folder info - diamond ;; |
;; 27.05.2006 LFN create/rewrite file - diamond ;; |
;; 04.05.2006 LFN read folder - diamond ;; |
;; 29.04.2006 Elimination of hangup after the ;; |
;; expiration hd_wait_timeout - Mario79 ;; |
;; 23.04.2006 LFN read file - diamond ;; |
;; 28.01.2006 find all Fat16/32 partition in all input point ;; |
;; to MBR, see file part_set.inc - Mario79 ;; |
;; 15.01.2005 get file size/attr/date, file_append - ATV ;; |
;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;; |
;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;; |
;; 23.11.2004 don't allow overwrite dir with file - ATV ;; |
;; 18.11.2004 get_disk_info and more error codes - ATV ;; |
;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;; |
;; 10.11.2004 removedir clear whole directory structure - ATV ;; |
;; 08.11.2004 rename - ATV ;; |
;; 30.10.2004 file_read return also dirsize in bytes - ATV ;; |
;; 20.10.2004 Makedir/Removedir - ATV ;; |
;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;; |
;; 06.9.2004 Fix free space by Mario79 added - MH ;; |
;; 24.5.2004 Write back buffer for File_write -VT ;; |
;; 20.5.2004 File_read function to work with syscall 58 - VT ;; |
;; 30.3.2004 Error parameters at function return - VT ;; |
;; 01.5.2002 Bugfix in device write - VT ;; |
;; 20.5.2002 Hd status check - VT ;; |
;; 29.6.2002 Improved fat32 verification - VT ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00 |
ERROR_SUCCESS = 0 |
ERROR_DISK_BASE = 1 |
ERROR_UNSUPPORTED_FS = 2 |
ERROR_UNKNOWN_FS = 3 |
ERROR_PARTITION = 4 |
ERROR_FILE_NOT_FOUND = 5 |
ERROR_END_OF_FILE = 6 |
ERROR_MEMORY_POINTER = 7 |
ERROR_DISK_FULL = 8 |
ERROR_FAT_TABLE = 9 |
ERROR_ACCESS_DENIED = 10 |
PUSHAD_EAX equ [esp+28] |
PUSHAD_ECX equ [esp+24] |
PUSHAD_EDX equ [esp+20] |
PUSHAD_EBX equ [esp+16] |
PUSHAD_EBP equ [esp+8] |
PUSHAD_ESI equ [esp+4] |
PUSHAD_EDI equ [esp+0] |
cluster dd 0 ; used by file_write,makedir,append |
partition_count dd 0 ; partitions found by set_FAT32_variables |
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous |
longname_sec2 dd 0 ; directory sectors for delete long filename |
hd_error dd 0 ; set by wait_for_sector_buffer |
hd_setup dd 0 |
hd_wait_timeout dd 0 |
cluster_tmp dd 0 ; used by analyze_directory |
; and analyze_directory_to_write |
file_size dd 0 ; used by file_read |
sector_tmp dd 0 ; used by rename,append,file_write |
entry_pos dd 0 ; used by rename,append,file_write |
old_filesize dd 0 ; used by append |
new_filepos dd 0 ; used by append |
bytes2write dd 0 ; used by append |
cache_search_start dd 0 ; used by find_empty_slot |
fat_in_cache dd -1 |
fat_cache: times 512 db 0 |
uglobal |
Sector512: ; label for dev_hdcd.inc |
buffer: times 512 db 0 |
deltree_buffer: times 512 db 0 |
endg |
iglobal |
NewDirEntry1 db ". ",0x10 |
times 20 db 0 |
NewDirEntry2 db ".. ",0x10 |
times 20 db 0 |
endg |
uglobal |
dir_entry: times 32 db 0 |
startpath: times 255 db 0 |
fat16_root db 0 ; flag for fat16 rootdir |
f_del db 0 ; 1=overwrite fat entry |
fat_change db 0 ; 1=fat has changed |
endg |
reserve_hd1: |
cli |
cmp [hd1_status],0 |
je reserve_ok1 |
sti |
call change_task |
jmp reserve_hd1 |
reserve_ok1: |
push eax |
mov eax,[0x3000] |
shl eax,5 |
mov eax,[eax+0x3000+TASKDATA.pid] |
mov [hd1_status],eax |
pop eax |
sti |
ret |
;******************************************** |
reserve_hd_channel: |
cmp [hdbase], 0x1F0 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
cli |
cmp [IDE_Channel_1],0 |
je .reserve_ok_1 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.IDE_Channel_2: |
cli |
cmp [IDE_Channel_2],0 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.reserve_ok_1: |
mov [IDE_Channel_1],1 |
ret |
.reserve_ok_2: |
mov [IDE_Channel_2],1 |
ret |
free_hd_channel: |
cmp [hdbase], 0x1F0 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1],0 |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2],0 |
ret |
;******************************************** |
clear_hd_cache: |
push eax ecx edi |
mov edi,0x600000 |
mov ecx,16384 |
xor eax,eax |
cld |
rep stosd ; clear hd cache with 0 |
mov [cache_search_start],eax |
mov [fat_in_cache],-1 |
mov [fat_change],0 |
pop edi ecx eax |
ret |
problem_partition db 0 ; used for partitions search |
include 'part_set.inc' |
set_FAT: |
;-------------------------------- |
; input : EAX = cluster |
; EDX = value to save |
; output : EDX = old value |
;-------------------------------- |
push eax ebx esi |
cmp eax,2 |
jb sfc_error |
cmp eax,[LAST_CLUSTER] |
ja sfc_error |
cmp [fat_type],16 |
je sfc_1 |
add eax,eax |
sfc_1: |
add eax,eax |
mov esi,511 |
and esi,eax ; esi = position in fat sector |
shr eax,9 ; eax = fat sector |
add eax,[FAT_START] |
mov ebx,fat_cache |
cmp eax,[fat_in_cache] ; is fat sector already in memory? |
je sfc_in_cache ; yes |
cmp [fat_change],0 ; is fat changed? |
je sfc_no_change ; no |
call write_fat_sector ; yes. write it into disk |
cmp [hd_error],0 |
jne sfc_error |
sfc_no_change: |
mov [fat_in_cache],eax ; save fat sector |
call hd_read |
cmp [hd_error],0 |
jne sfc_error |
sfc_in_cache: |
cmp [fat_type],16 |
jne sfc_test32 |
cmp [f_del],1 ; overwrite previous value? |
je sfc_set16 ; yes |
cmp word [ebx+esi],0 ; is cluster free? |
je sfc_set16 ; yes |
mov dword [8*0x100000],0xffffff |
mov edx,[ebx+esi] ; get old value |
jmp sfc_nonzero |
sfc_set16: |
xchg [ebx+esi],dx ; save new value and get old value |
jmp sfc_write |
sfc_test32: |
mov eax,[fatMASK] |
cmp [f_del],1 ; overwrite previous value? |
je sfc_set32 ; yes |
test eax,[ebx+esi] ; is cluster free? |
je sfc_set32 ; yes |
mov dword [8*0x100000],0xffffff |
mov edx,[ebx+esi] ; get old value |
jmp sfc_nonzero |
sfc_set32: |
and edx,eax |
xor eax,-1 ; mask for high bits |
and eax,[ebx+esi] ; get high 4 bits |
or eax,edx |
mov edx,[ebx+esi] ; get old value |
mov [ebx+esi],eax ; save new value |
sfc_write: |
mov [fat_change],1 ; fat has changed |
sfc_nonzero: |
and edx,[fatMASK] |
sfc_error: |
pop esi ebx eax |
ret |
get_FAT: |
;-------------------------------- |
; input : EAX = cluster |
; output : EAX = next cluster |
;-------------------------------- |
push ebx esi |
cmp [fat_type],16 |
je gfc_1 |
add eax,eax |
gfc_1: |
add eax,eax |
mov esi,511 |
and esi,eax ; esi = position in fat sector |
shr eax,9 ; eax = fat sector |
add eax,[FAT_START] |
mov ebx,fat_cache |
cmp eax,[fat_in_cache] ; is fat sector already in memory? |
je gfc_in_cache |
cmp [fat_change],0 ; is fat changed? |
je gfc_no_change ; no |
call write_fat_sector ; yes. write it into disk |
cmp [hd_error],0 |
jne hd_error_01 |
gfc_no_change: |
mov [fat_in_cache],eax |
call hd_read |
cmp [hd_error],0 |
jne hd_error_01 |
gfc_in_cache: |
mov eax,[ebx+esi] |
and eax,[fatMASK] |
hd_error_01: |
pop esi ebx |
ret |
get_free_FAT: |
;----------------------------------------------------------- |
; input : EAX = # cluster for start the searching |
; output : if CARRY=0 EAX = # first cluster found free |
; if CARRY=1 disk full |
; Note : for more speed need to use fat_cache directly |
;----------------------------------------------------------- |
push ecx |
mov ecx,[LAST_CLUSTER] ; counter for full disk |
sub ecx,2 |
gff_test: |
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2 |
jbe gff_in_range |
mov eax,2 |
gff_in_range: |
push eax |
call get_FAT ; get cluster state |
cmp [hd_error],0 |
jne gff_not_found_1 |
test eax,eax ; is it free? |
pop eax |
je gff_found ; yes |
inc eax ; next cluster |
dec ecx ; is all checked? |
jns gff_test ; no |
gff_not_found_1: |
add esp,4 |
gff_not_found: |
pop ecx ; yes. disk is full |
stc |
ret |
gff_found: |
pop ecx |
clc |
ret |
write_fat_sector: |
;----------------------------------------------------------- |
; write changed fat to disk |
;----------------------------------------------------------- |
push eax ebx ecx |
mov [fat_change],0 |
mov eax,[fat_in_cache] |
cmp eax,-1 |
jz write_fat_not_used |
mov ebx,fat_cache |
mov ecx,[NUMBER_OF_FATS] |
write_next_fat: |
call hd_write |
cmp [hd_error],0 |
jne write_fat_not_used |
add eax,[SECTORS_PER_FAT] |
dec ecx |
jnz write_next_fat |
write_fat_not_used: |
pop ecx ebx eax |
ret |
analyze_directory: |
;----------------------------------------------------------- |
; input : EAX = first cluster of the directory |
; EBX = pointer to filename |
; output : IF CARRY=0 EAX = sector where th file is found |
; EBX = pointer in buffer |
; [buffer .. buffer+511] |
; ECX,EDX,ESI,EDI not changed |
; IF CARRY=1 filename not found |
; Note : if cluster=0 it's changed to read rootdir |
; save 2 previous directory sectors in longname_sec |
;----------------------------------------------------------- |
push ecx edx esi edi ebx ; ebx = [esp+0] |
mov [longname_sec1],0 |
mov [longname_sec2],0 |
adr_new_cluster: |
mov [cluster_tmp],eax |
mov [fat16_root],0 |
cmp eax,[LAST_CLUSTER] |
ja adr_not_found ; too big cluster number, something is wrong |
cmp eax,2 |
jnb adr_data_cluster |
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir |
cmp [fat_type],16 |
jne adr_data_cluster |
mov eax,[ROOT_START] |
mov edx,[ROOT_SECTORS] |
mov [fat16_root],1 ; flag for fat16 rootdir |
jmp adr_new_sector |
adr_data_cluster: |
sub eax,2 |
mov edx,[SECTORS_PER_CLUSTER] |
imul eax,edx |
add eax,[DATA_START] |
adr_new_sector: |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne adr_not_found |
mov ecx,512/32 ; count of dir entrys per sector = 16 |
adr_analyze: |
mov edi,[ebx+11] ; file attribute |
and edi,0xf |
cmp edi,0xf |
je adr_long_filename |
test edi,0x8 ; skip over volume label |
jne adr_long_filename ; Note: label can be same name as file/dir |
mov esi,[esp+0] ; filename need to be uppercase |
mov edi,ebx |
push ecx |
mov ecx,11 |
cld |
rep cmpsb ; compare 8+3 filename |
pop ecx |
je adr_found |
adr_long_filename: |
add ebx,32 ; position of next dir entry |
dec ecx |
jnz adr_analyze |
mov ecx,[longname_sec1] ; save 2 previous directory sectors |
mov [longname_sec1],eax ; for delete long filename |
mov [longname_sec2],ecx |
inc eax ; next sector |
dec edx |
jne adr_new_sector |
cmp [fat16_root],1 ; end of fat16 rootdir |
je adr_not_found |
adr_next_cluster: |
mov eax,[cluster_tmp] |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne adr_not_found |
cmp eax,2 ; incorrect fat chain? |
jb adr_not_found ; yes |
cmp eax,[fatRESERVED] ; is it end of directory? |
jb adr_new_cluster ; no. analyse it |
adr_not_found: |
pop edi edi esi edx ecx ; first edi will remove ebx |
stc ; file not found |
ret |
adr_found: |
pop edi edi esi edx ecx ; first edi will remove ebx |
clc ; file found |
ret |
analyze_directory_to_write: |
;----------------------------------------------------------- |
; input : EAX = first cluster of the directory |
; output : IF CARRY=0 EAX = sector where the empty pos is found |
; EBX = pointer in buffer |
; [buffer .. buffer+511] |
; ECX,EDX,ESI,EDI not changed |
; IF CARRY=1 disk full or fat corrupted |
; Note : if cluster=0 it's changed to read rootdir |
;----------------------------------------------------------- |
push ecx edx edi |
adw_new_cluster: |
mov [cluster_tmp],eax |
mov [fat16_root],0 |
cmp eax,[LAST_CLUSTER] |
ja adw_not_found ; too big cluster number, something is wrong |
cmp eax,2 |
jnb adw_data_cluster |
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir |
cmp [fat_type],16 |
jne adw_data_cluster |
mov eax,[ROOT_START] |
mov edx,[ROOT_SECTORS] |
mov [fat16_root],1 ; flag for fat16 rootdir |
jmp adw_new_sector |
adw_data_cluster: |
sub eax,2 |
mov edx,[SECTORS_PER_CLUSTER] |
imul eax,edx |
add eax,[DATA_START] |
adw_new_sector: |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne adw_not_found |
mov ecx,512/32 ; count of dir entrys per sector = 16 |
adw_analyze: |
cmp byte [ebx],0x00 ; is free entry? |
je adw_found ; yes |
cmp byte [ebx],0xe5 ; is deleted entry? |
je adw_found ; yes |
add ebx,32 ; position of next dir entry |
dec ecx |
jnz adw_analyze |
inc eax ; next sector |
dec edx |
jne adw_new_sector |
cmp [fat16_root],1 ; end of fat16 rootdir |
je adw_not_found |
mov eax,[cluster_tmp] |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne adw_not_found |
cmp eax,2 ; incorrect fat chain? |
jb adw_not_found ; yes |
cmp eax,[fatRESERVED] ; is it end of directory? |
jb adw_new_cluster ; no. analyse it |
mov eax,2 ; this block of code add a new cluster |
call get_free_FAT ; for the directory because the directory |
jc adw_not_found ; is full |
mov edx,[fatEND] ; new end for directory |
call set_FAT |
cmp [hd_error],0 |
jne adw_not_found |
push eax ; save new cluster |
mov edx,eax |
mov eax,[cluster_tmp] ; change last cluster to point new cluster |
mov [f_del],1 |
call set_FAT |
cmp [hd_error],0 |
jne adw_not_found_1 |
mov [f_del],0 |
mov ecx,-1 ; remove 1 cluster from free disk space |
call add_disk_free_space |
cmp [hd_error],0 |
jne adw_not_found_1 |
mov ecx,512/4 |
xor eax,eax |
mov edi,buffer |
cld |
rep stosd ; clear new directory cluster |
pop eax |
sub eax,2 |
mov ecx,[SECTORS_PER_CLUSTER] |
imul eax,ecx |
add eax,[DATA_START] |
mov ebx,buffer |
push eax ; save sector number |
adw_set_empty_directory: |
call hd_write |
cmp [hd_error],0 |
jne adw_not_found_1 |
inc eax ; next sector |
dec ecx |
jnz adw_set_empty_directory |
pop eax |
adw_found: |
pop edi edx ecx |
clc ; free space found |
ret |
adw_not_found_1: |
add esp,4 |
adw_not_found: |
pop edi edx ecx |
stc ; free space not found |
ret |
get_data_cluster: |
;----------------------------------------------------------- |
; input : EAX = cluster |
; EBX = pointer to buffer |
; EDX = # blocks to read in buffer |
; ESI = # blocks to skip over |
; output : if CARRY=0 ok EBX/EDX/ESI updated |
; if CARRY=1 cluster out of range |
; Note : if cluster=0 it's changed to read rootdir |
;----------------------------------------------------------- |
push eax ecx |
mov [fat16_root],0 |
cmp eax,[LAST_CLUSTER] |
ja gdc_error ; too big cluster number, something is wrong |
cmp eax,2 |
jnb gdc_cluster |
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir |
cmp [fat_type],16 |
jne gdc_cluster |
mov eax,[ROOT_START] |
mov ecx,[ROOT_SECTORS] ; Note: not cluster size |
mov [fat16_root],1 ; flag for fat16 rootdir |
jmp gdc_read |
gdc_cluster: |
sub eax,2 |
mov ecx,[SECTORS_PER_CLUSTER] |
imul eax,ecx |
add eax,[DATA_START] |
gdc_read: |
test esi,esi ; first wanted block |
je gdcl1 ; yes, skip count is 0 |
dec esi |
jmp gdcl2 |
gdcl1: |
call hd_read |
cmp [hd_error],0 |
jne gdc_error |
add ebx,512 ; update pointer |
dec edx |
gdcl2: |
test edx,edx ; is all read? |
je out_of_read |
inc eax ; next sector |
dec ecx |
jnz gdc_read |
out_of_read: |
pop ecx eax |
clc |
ret |
gdc_error: |
pop ecx eax |
stc |
ret |
set_data_cluster: |
;----------------------------------------------------------- |
; input : EAX = cluster |
; EBX = pointer to buffer |
; output : if CARRY=0 ok |
; if CARRY=1 cluster out of range |
;----------------------------------------------------------- |
push eax ebx edx |
cmp eax,[LAST_CLUSTER] |
ja sdc_error ; too big cluster number, something is wrong |
sub eax,2 |
jb sdc_error ; don't allow rootdir write |
mov edx,[SECTORS_PER_CLUSTER] |
imul eax,edx |
add eax,[DATA_START] |
sdc_write: |
call hd_write |
cmp [hd_error],0 |
jne sdc_error |
add ebx,512 ; update pointer |
inc eax |
dec edx |
jnz sdc_write |
pop edx ebx eax |
clc |
ret |
sdc_error: |
pop edx ebx eax |
stc |
ret |
get_cluster_of_a_path: |
;--------------------------------------------------------- |
; input : EBX = pointer to a path string |
; (example: the path "/files/data/document" become |
; "files......data.......document...0" |
; '.' = space char |
; '0' = char(0) (ASCII=0) !!! ) |
; output : if (CARRY=1) -> ERROR in the PATH |
; if (CARRY=0) -> EAX=cluster |
;--------------------------------------------------------- |
push ebx edx |
mov eax,[ROOT_CLUSTER] |
mov edx,ebx |
search_end_of_path: |
cmp byte [edx],0 |
je found_end_of_path |
inc edx ; '/' |
mov ebx,edx |
call analyze_directory |
jc directory_not_found |
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field |
mov ax,[ebx+26] ; read the LOW 16bit cluster field |
and eax,[fatMASK] |
add edx,11 ; 8+3 (name+extension) |
jmp search_end_of_path |
found_end_of_path: |
pop edx ebx |
clc ; no errors |
ret |
directory_not_found: |
pop edx ebx |
stc ; errors occour |
ret |
bcd2bin: |
;---------------------------------- |
; input : AL=BCD number (eg. 0x11) |
; output : AH=0 |
; AL=decimal number (eg. 11) |
;---------------------------------- |
xor ah,ah |
shl ax,4 |
shr al,4 |
aad |
ret |
get_date_for_file: |
;----------------------------------------------------- |
; Get date from CMOS and pack day,month,year in AX |
; DATE bits 0..4 : day of month 0..31 |
; 5..8 : month of year 1..12 |
; 9..15 : count of years from 1980 |
;----------------------------------------------------- |
mov al,0x7 ;day |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,5 |
mov al,0x8 ;month |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,4 |
mov al,0x9 ;year |
out 0x70,al |
in al,0x71 |
call bcd2bin |
add ax,20 ;because CMOS return only the two last |
;digit (eg. 2000 -> 00 , 2001 -> 01) and we |
rol eax,9 ;need the difference with 1980 (eg. 2001-1980) |
ret |
get_time_for_file: |
;----------------------------------------------------- |
; Get time from CMOS and pack hour,minute,second in AX |
; TIME bits 0..4 : second (the low bit is lost) |
; 5..10 : minute 0..59 |
; 11..15 : hour 0..23 |
;----------------------------------------------------- |
mov al,0x0 ;second |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,6 |
mov al,0x2 ;minute |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,6 |
mov al,0x4 ;hour |
out 0x70,al |
in al,0x71 |
call bcd2bin |
rol eax,11 |
ret |
set_current_time_for_entry: |
;----------------------------------------------------- |
; Set current time/date for file entry |
; input : ebx = file entry pointer |
;----------------------------------------------------- |
push eax |
call get_time_for_file ; update files date/time |
mov [ebx+22],ax |
call get_date_for_file |
mov [ebx+24],ax |
pop eax |
ret |
makedir: |
;----------------------------------------------------- |
; input : eax = directory name |
; edx = path |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 8 - disk full |
; 10 - access denied |
; Note : can only make one directory at time |
;----------------------------------------------------- |
cmp [fat_type],0 |
jnz make_dir_fat_ok |
mov eax,ERROR_UNKNOWN_FS |
ret |
make_dir_fat_ok: |
; call reserve_hd1 |
pushad |
mov ebx,edx |
call get_cluster_of_a_path |
jnc make_dir_found_path |
cmp [hd_error],0 |
jne make_dir_error_1 |
make_dir_path_not_found: |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne make_dir_error_2 |
mov [hd1_status],0 |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
make_dir_disk_full: |
cmp [hd_error],0 |
jne make_dir_error_1 |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne make_dir_error_2 |
mov [hd1_status],0 |
mov eax,ERROR_DISK_FULL |
ret |
make_dir_already_exist: |
cmp [hd_error],0 |
jne make_dir_error_1 |
mov eax,[cluster] ; directory cluster |
xor edx,edx ; free |
mov [f_del],1 |
call set_FAT |
cmp [hd_error],0 |
jne make_dir_error_1 |
mov [f_del],0 |
popad |
call update_disk ; write all of cache and fat to hd |
make_dir_error_2: |
mov [hd1_status],0 |
mov eax,ERROR_ACCESS_DENIED |
ret |
make_dir_error_1: |
popad |
jmp make_dir_error_2 |
make_dir_error_3: |
add esp,4 |
jmp make_dir_error_1 |
make_dir_found_path: |
cmp eax,[ROOT_CLUSTER] |
jnz make_dir_not_root |
xor eax,eax |
make_dir_not_root: |
mov ecx,eax ; directorys start cluster |
mov word [NewDirEntry2+26],cx ; 16 bits low of cluster |
shr ecx,16 |
mov word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16) |
push eax ; save parent directory cluster |
mov eax,2 |
call get_free_FAT |
mov [cluster],eax ; first free cluster |
pop eax |
jc make_dir_disk_full |
push eax |
mov eax,[cluster] ; directory cluster |
mov edx,[fatEND] ; end for directory |
call set_FAT |
cmp [hd_error],0 |
jne make_dir_error_3 |
pop eax |
mov ebx,PUSHAD_EAX ; dir name |
push eax |
call analyze_directory ; check if directory already exist |
cmp [hd_error],0 |
jne make_dir_error_1 |
pop eax |
jnc make_dir_already_exist ; need to free allocated cluster! |
call analyze_directory_to_write |
jc make_dir_already_exist ; need to free allocated cluster! |
mov esi,PUSHAD_EAX ; dir name |
mov edi,ebx ; pointer in buffer |
mov ecx,11 |
cld |
rep movsb |
mov dword [ebx+28],0 ; dir size is always 0 |
mov ecx,[cluster] |
mov [ebx+26],cx ; 16 bits low of cluster |
mov word [NewDirEntry1+26],cx |
shr ecx,16 |
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) |
mov word [NewDirEntry1+20],cx |
mov byte [ebx+11],0x10 ; attribute = directory |
call set_current_time_for_entry |
mov ecx,[ebx+22] |
mov dword [NewDirEntry1+22],ecx |
mov dword [NewDirEntry2+22],ecx |
mov ebx,buffer ; save the directory name,length,cluster |
call hd_write |
cmp [hd_error],0 |
jne make_dir_error_1 |
mov ecx,512/4 |
xor eax,eax |
mov edi,buffer |
cld |
rep stosd ; clear new directory cluster |
mov eax,[cluster] ; new directory cluster |
sub eax,2 |
mov edx,[SECTORS_PER_CLUSTER] |
imul eax,edx |
add eax,[DATA_START] |
mov ebx,buffer |
add eax,edx ; start from last sector |
dir_set_empty_directory: |
dec eax ; next sector |
cmp edx,1 ; is first directory sector? |
jnz not_first_sector ; no. write empty sector |
mov esi,NewDirEntry1 |
mov edi,buffer |
mov ecx,64/4 |
cld |
rep movsd ; copy 2 first directory entrys "." and ".." |
not_first_sector: |
call hd_write |
cmp [hd_error],0 |
jne make_dir_error_1 |
dec edx |
jnz dir_set_empty_directory |
mov ecx,-1 ; remove 1 cluster from free disk space |
call add_disk_free_space |
cmp [hd_error],0 |
jne make_dir_error_1 |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne make_dir_error_2 |
mov [hd1_status],0 |
xor eax,eax |
ret |
removedir: |
;----------------------------------------------------- |
; input : eax = file/directory name |
; edx = path |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 10 - access denied |
;----------------------------------------------------- |
cmp [fat_type],0 |
jnz remove_dir_fat_ok |
mov eax,ERROR_UNKNOWN_FS |
ret |
remove_dir_fat_ok: |
; call reserve_hd1 |
push edi |
mov edi,1 ; allow directory remove |
call file_delete |
cmp [hd_error],0 |
jne @f |
pop edi |
call update_disk ; write all of cache and fat to hd |
@@: |
mov [hd1_status],0 |
ret |
add_disk_free_space: |
;----------------------------------------------------- |
; input : ecx = cluster count |
; Note : negative = remove clusters from free space |
; positive = add clusters to free space |
;----------------------------------------------------- |
test ecx,ecx ; no change |
je add_dfs_no |
cmp [fat_type],32 ; free disk space only used by fat32 |
jne add_dfs_no |
push eax ebx |
mov eax,[ADR_FSINFO] |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne add_not_fs |
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id |
jne add_not_fs |
add [ebx+0x1e8],ecx |
call hd_write |
cmp [hd_error],0 |
jne add_not_fs |
add_not_fs: |
pop ebx eax |
add_dfs_no: |
ret |
file_append: |
;----------------------------------------------------- |
; input : eax = file name |
; edx = path |
; ecx = pointer to buffer |
; ebx = bytes to write (0 = truncate file) |
; esi = start position (-1 = end of file) |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 6 - end of file |
; 8 - disk full |
; 9 - fat table corrupted |
; 10 - access denied |
; ebx = bytes written |
;----------------------------------------------------- |
cmp [fat_type],0 |
jnz append_fat_ok |
mov eax,ERROR_UNKNOWN_FS |
ret |
append_fat_ok: |
; call reserve_hd1 |
pushad |
mov ebx,edx |
call get_cluster_of_a_path |
jc append_not_found |
mov ebx,PUSHAD_EAX ; file name |
call analyze_directory |
jc append_not_found |
mov [sector_tmp],eax |
mov [entry_pos],ebx |
test byte [ebx+11],0x10 ; is it directory? |
jnz append_access ; yes |
mov ecx,[ebx+28] ; file size |
mov edi,PUSHAD_ESI ; write position |
cmp edi,-1 ; -1 = eof |
jnz append_inside_file |
mov edi,ecx ; file size |
append_inside_file: |
cmp edi,ecx ; start above old file size? |
ja append_eof ; yes |
mov [old_filesize],ecx |
mov [new_filepos],edi |
mov ecx,PUSHAD_EBX ; bytes to write |
test ecx,ecx ; truncate? |
jz append_truncate ; yes |
mov [bytes2write],ecx ; bytes to write |
mov esi,PUSHAD_ECX ; pointer to buffer |
mov eax,[ebx+20-2] ; FAT entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
jnz append_find_pos ; first cluster <> 0 |
mov eax,2 |
call get_free_FAT |
jc append_disk_full |
mov ecx,eax ; set files first cluster |
mov [ebx+26],cx ; 16 bits low of cluster |
shr ecx,16 |
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) |
mov edx,[fatEND] ; new end for cluster chain |
call set_FAT |
cmp [hd_error],0 |
jne append_access |
push eax ; save first cluster |
mov eax,[sector_tmp] |
mov ebx,buffer |
call hd_write ; write new file entry back to disk |
cmp [hd_error],0 |
jne append_access_1 |
pop eax |
append_remove_free: |
mov ecx,-1 ; remove 1 cluster from free disk space |
call add_disk_free_space ; Note: uses buffer |
cmp [hd_error],0 |
jne append_access |
append_found_cluster: |
mov [cluster],eax |
sub eax,2 |
mov ecx,[SECTORS_PER_CLUSTER] |
imul eax,ecx |
add eax,[DATA_START] |
xor edi,edi |
append_new_sector: |
cmp [hd_error],0 |
jne append_access |
push ecx |
mov ecx,[bytes2write] ; bytes left in buffer |
mov ebx,512 |
sub ebx,edi ; bytes left in sector |
cmp ecx,ebx |
jb append_bytes_ok |
mov ecx,ebx |
append_bytes_ok: |
cmp ecx,512 ; overwrite full sector? |
jz append_full_sector ; yes |
mov ebx,buffer ; overwrite part of sector |
call hd_read ; read old sector |
cmp [hd_error],0 |
jne append_access_1 |
append_full_sector: |
sub [bytes2write],ecx |
add [new_filepos],ecx |
add edi,buffer |
cld |
rep movsb |
pop ecx |
mov ebx,buffer |
call hd_write |
cmp [hd_error],0 |
jne append_access |
cmp [bytes2write],0 ; is all done? |
jz append_done |
xor edi,edi |
inc eax |
dec ecx |
jnz append_new_sector |
mov eax,[cluster] |
call get_FAT |
cmp [hd_error],0 |
jne append_access |
cmp eax,2 |
jb append_fat |
cmp eax,[LAST_CLUSTER] |
jbe append_found_cluster |
append_alloc_cluster: |
mov eax,2 ; ToDo: use temp array to keep track |
call get_free_FAT ; of last free cluster |
jc append_disk_full |
push eax ; save new cluster |
mov edx,[fatEND] ; new end for cluster chain |
call set_FAT |
cmp [hd_error],0 |
jne append_access_1 |
mov edx,eax |
mov eax,[cluster] |
mov [f_del],1 |
call set_FAT ; update previous cluster |
cmp [hd_error],0 |
jne append_access_1 |
mov [f_del],0 |
pop eax |
jmp append_remove_free |
append_find_pos: |
call find_filepos |
mov [cluster],ebx |
jnc append_new_sector |
test edi,edi |
jz append_alloc_cluster |
append_fat: |
mov eax,ERROR_FAT_TABLE |
jmp append_ret_code |
append_disk_full: |
cmp [hd_error],0 |
jne append_access |
mov eax,ERROR_DISK_FULL |
jmp append_ret_code |
append_done: |
xor eax,eax |
append_ret_code: |
mov PUSHAD_EAX,eax ; return code |
mov eax,[sector_tmp] ; update directory entry |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne append_access |
mov ebx,[entry_pos] |
mov ecx,[new_filepos] |
cmp ecx,[old_filesize] ; is file pos above old size? |
jbe append_size_ok ; no |
mov [ebx+28],ecx ; new file size |
append_size_ok: |
call set_current_time_for_entry |
mov ebx,buffer |
call hd_write ; write new file entry back to disk |
cmp [hd_error],0 |
jne append_access |
sub ecx,PUSHAD_ESI ; start position |
mov PUSHAD_EBX,ecx ; bytes written |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne append_access_2 |
mov [hd1_status],0 |
ret |
append_eof: |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_END_OF_FILE |
ret |
append_not_found: |
cmp [hd_error],0 |
jne append_access |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
append_access_1: |
add esp,4 |
append_access: |
popad |
append_access_2: |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_ACCESS_DENIED |
ret |
append_truncate: |
mov edx,[ebx+20-2] ; FAT entry |
mov dx,[ebx+26] |
and edx,[fatMASK] |
mov [ebx+28],edi ; set new file size |
test edi,edi ; 0 length file? |
jnz truncate_save_size ; no |
mov [ebx+20],di ; FAT entry = 0 |
mov [ebx+26],di |
truncate_save_size: |
call set_current_time_for_entry |
mov ebx,buffer |
call hd_write |
cmp [hd_error],0 |
jne append_access |
mov eax,edx ; first cluster |
test edi,edi ; 0 length file? |
jz truncate_clear_chain |
imul esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes |
truncate_new_cluster: |
cmp eax,2 ; incorrect fat chain? |
jb truncate_eof ; yes |
cmp eax,[fatRESERVED] ; is it end of file? |
jnb truncate_eof ; yes |
sub edi,esi |
jbe truncate_pos_found |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne append_access |
jmp truncate_new_cluster |
truncate_pos_found: |
mov edx,[fatEND] ; new end for cluster chain |
mov [f_del],1 |
call set_FAT |
cmp [hd_error],0 |
jne append_access |
mov [f_del],0 |
mov eax,edx ; clear rest of chain |
truncate_clear_chain: |
call clear_cluster_chain |
cmp [hd_error],0 |
jne append_access |
truncate_eof: |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne append_access_2 |
mov [hd1_status],0 |
xor ebx,ebx |
xor eax,eax |
ret |
find_filepos: |
;----------------------------------------------------- |
; input : eax = first cluster |
; edi = bytes to skip over (start position) |
; output : if CARRY=0 file position found |
; if CARRY=1 end of file found |
; eax = current file sector |
; ebx = last cluster |
; ecx = sector count in last cluster |
; edi = bytes to skip over (sector position) |
;----------------------------------------------------- |
push esi |
mov ecx,[SECTORS_PER_CLUSTER] |
imul esi,ecx,512 ; esi = cluster size in bytes |
mov ebx,eax |
filepos_new_cluster: |
cmp eax,2 ; incorrect fat chain? |
jb filepos_eof ; yes |
cmp eax,[fatRESERVED] ; is it end of file? |
jnb filepos_eof ; yes |
mov ebx,eax |
cmp edi,esi ; skip over full cluster? |
jb filepos_cluster_ok ; no |
sub edi,esi |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne filepos_eof |
jmp filepos_new_cluster |
filepos_cluster_ok: |
sub eax,2 |
imul eax,ecx |
add eax,[DATA_START] |
filepos_new_sector: |
cmp edi,512 ; skip over full sector? |
jb filepos_sector_ok ; no |
sub edi,512 |
inc eax |
dec ecx |
jnz filepos_new_sector |
filepos_eof: |
pop esi |
stc |
ret |
filepos_sector_ok: |
pop esi |
clc |
ret |
file_write: |
;-------------------------------------------------------------------------- |
; INPUT : user-reg register-in-this meaning symbol-in-this-routine |
; |
; EAX EDI system call to write / |
; EBX EAX (PAR0) pointer to file-name PAR0 |
; EDX ECX (PAR1) pointer to buffer PAR1 |
; ECX EBX (PAR2) file size PAR2 |
; ESI EDX (PAR3) pointer to path PAR3 |
; |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 8 - disk full |
; 10 - access denied |
;-------------------------------------------------------------------------- |
cmp [fat_type],0 |
jnz fat_ok_for_writing |
mov eax,ERROR_UNKNOWN_FS |
ret |
fat_ok_for_writing: |
; call reserve_hd1 |
pushad |
xor edi,edi ; don't allow directory remove |
call file_delete ; try to delete the file first |
cmp [hd_error],0 |
jne exit_write_access_1 |
test eax,eax |
jz old_deleted ; deleted ok |
cmp eax,ERROR_FILE_NOT_FOUND |
jnz exit_write_access ; it exist but can't delete |
old_deleted: |
mov ebx,PUSHAD_EDX |
call get_cluster_of_a_path |
jnc found_directory_for_writing |
cmp [hd_error],0 |
jne exit_write_access |
exit_writing_with_error: |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne exit_write_access_2 |
mov [hd1_status],0 |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
exit_writing_disk_full_clear: |
cmp [hd_error],0 |
jne exit_write_access_1 |
mov eax,[sector_tmp] |
mov ebx,buffer |
call hd_read ; read directory sector |
cmp [hd_error],0 |
jne exit_write_access_1 |
mov edx,[entry_pos] |
mov byte [edx],0xe5 ; mark as deleted |
call hd_write |
cmp [hd_error],0 |
jne exit_write_access_1 |
mov eax,[edx+20-2] ; FAT entry |
mov ax,[edx+26] |
and eax,[fatMASK] |
call clear_cluster_chain |
exit_writing_disk_full: |
cmp [hd_error],0 |
jne exit_write_access_1 |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne exit_write_access_2 |
mov [hd1_status],0 |
mov eax,ERROR_DISK_FULL |
ret |
exit_write_access: |
popad |
call update_disk ; write all of cache and fat to hd |
mov [hd1_status],0 |
mov eax,ERROR_ACCESS_DENIED |
ret |
exit_write_access_1: |
popad |
exit_write_access_2: |
mov [hd1_status],0 |
mov eax,ERROR_ACCESS_DENIED |
ret |
found_directory_for_writing: |
call analyze_directory_to_write |
jc exit_writing_disk_full |
mov [sector_tmp],eax |
mov [entry_pos],ebx |
push eax ; save directory sector |
mov eax,2 |
call get_free_FAT |
mov [cluster],eax ; first free cluster |
pop eax |
jc exit_writing_disk_full |
mov esi,PUSHAD_EAX ; file name |
mov edi,ebx ; pointer in buffer |
mov ecx,11 |
cld |
rep movsb |
mov esi,PUSHAD_EBX ; file size (bytes left) |
mov [ebx+28],esi ; file size |
mov ecx,[cluster] |
mov [ebx+26],cx ; 16 bits low of cluster |
shr ecx,16 |
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) |
mov byte [ebx+11],0x20 ; attribute = archive |
call set_current_time_for_entry |
mov ebx,buffer ; save the directory name,length,cluster |
call hd_write |
cmp [hd_error],0 |
jne exit_write_access_1 |
imul edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes |
xor ecx,ecx ; cluster count |
mov ebx,PUSHAD_ECX ; ebx = buffer |
hd_new_block_write: |
mov eax,[cluster] ; eax = block |
call set_data_cluster |
cmp [hd_error],0 |
jne exit_write_access_1 |
sub esi,edi ; sub wrote bytes |
jbe file_saved_OK ; end if all done |
add ebx,edi ; update buffer position |
inc eax |
call get_free_FAT ; next free in FAT |
jc exit_writing_disk_full_clear |
mov edx,eax |
xchg eax,[cluster] ; get old cluster and save new cluster |
call set_FAT ; add it in cluster chain |
cmp [hd_error],0 |
jne exit_write_access_1 |
dec ecx ; update cluster count |
jmp hd_new_block_write |
file_saved_OK: |
mov edx,[fatEND] ; new end for cluster chain |
call set_FAT |
cmp [hd_error],0 |
jne exit_write_access_1 |
dec ecx ; update cluster count |
call add_disk_free_space ; remove clusters from free disk space |
cmp [hd_error],0 |
jne exit_write_access_1 |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne exit_write_access_2 |
mov [hd1_status],0 |
xor eax,eax |
ret |
file_read: |
;-------------------------------------------------------------------------- |
; INPUT : user-register register-in-this meaning symbol-in-this |
; |
; EAX EDI system call to write / |
; EBX EAX (PAR0) pointer to file-name PAR0 |
; EDX ECX (PAR1) pointer to buffer PAR1 |
; ECX EBX (PAR2) vt file blocks to read PAR2 |
; ESI EDX (PAR3) pointer to path PAR3 |
; EDI ESI vt first 512 block to read |
; EDI if 0 - read root |
; |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 6 - end of file |
; 9 - fat table corrupted |
; 10 - access denied |
; ebx = size of file/directory |
;-------------------------------------------------------------------------- |
cmp [fat_type],0 |
jnz fat_ok_for_reading |
xor ebx,ebx |
mov eax,ERROR_UNKNOWN_FS |
mov [hd1_status], ebx |
ret |
fat_ok_for_reading: |
; call reserve_hd1 |
pushad |
mov ebx,edx |
call get_cluster_of_a_path |
jc file_to_read_not_found |
test edi,edi ; read rootdir |
jne no_read_root |
xor eax,eax |
call get_dir_size ; return rootdir size |
cmp [hd_error],0 |
jne file_access_denied |
mov [file_size],eax |
mov eax,[ROOT_CLUSTER] |
jmp file_read_start |
no_read_root: |
mov ebx,PUSHAD_EAX ; file name |
call analyze_directory |
jc file_to_read_not_found |
mov eax,[ebx+28] ; file size |
test byte [ebx+11],0x10 ; is it directory? |
jz read_set_size ; no |
mov eax,[ebx+20-2] ; FAT entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
call get_dir_size |
cmp [hd_error],0 |
jne file_access_denied |
read_set_size: |
mov [file_size],eax |
mov eax,[ebx+20-2] ; FAT entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
file_read_start: |
mov ebx,PUSHAD_ECX ; pointer to buffer |
mov edx,PUSHAD_EBX ; file blocks to read |
mov esi,PUSHAD_ESI ; first 512 block to read |
file_read_new_cluster: |
call get_data_cluster |
jc file_read_eof ; end of file or cluster out of range |
test edx,edx ; is all read? |
je file_read_OK ; yes |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne file_access_denied |
cmp eax,[fatRESERVED] ; end of file |
jnb file_read_eof |
cmp eax,2 ; incorrect fat chain |
jnb file_read_new_cluster |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
mov eax,ERROR_FAT_TABLE |
ret |
file_read_eof: |
cmp [hd_error],0 |
jne file_access_denied |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
mov eax,ERROR_END_OF_FILE |
ret |
file_read_OK: |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
xor eax,eax |
ret |
file_to_read_not_found: |
cmp [hd_error],0 |
jne file_access_denied |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
file_access_denied: |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_ACCESS_DENIED |
ret |
get_dir_size: |
;----------------------------------------------------- |
; input : eax = first cluster (0=rootdir) |
; output : eax = directory size in bytes |
;----------------------------------------------------- |
push edx |
xor edx,edx ; count of directory clusters |
test eax,eax |
jnz dir_size_next |
mov eax,[ROOT_SECTORS] |
shl eax,9 ; fat16 rootdir size in bytes |
cmp [fat_type],16 |
je dir_size_ret |
mov eax,[ROOT_CLUSTER] |
dir_size_next: |
cmp eax,2 ; incorrect fat chain |
jb dir_size_end |
cmp eax,[fatRESERVED] ; end of directory |
ja dir_size_end |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne dir_size_ret |
inc edx |
jmp dir_size_next |
dir_size_end: |
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes |
imul eax,edx |
dir_size_ret: |
pop edx |
ret |
file_delete: |
;----------------------------------------------------- |
; input : eax = file/directory name |
; edx = path |
; edi = 1 - allow directory remove else don't remove directory |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 10 - access denied |
;----------------------------------------------------- |
cmp [fat_type],0 |
jnz file_del_fat_ok |
mov eax,ERROR_UNKNOWN_FS |
ret |
file_del_fat_ok: |
pushad |
mov ebx,edx |
call get_cluster_of_a_path |
jc file_to_delete_not_found |
mov ebx,PUSHAD_EAX ; file/directory name |
call analyze_directory |
jc file_to_delete_not_found |
test byte [ebx+11],0x10 ; is it directory? |
jz delete_notdir ; no. it's file |
cmp edi,1 ; allow directory remove |
jnz delete_no_access ; no |
push eax ; save directory sector |
mov eax,[ebx+20-2] ; first cluster of file |
mov ax,[ebx+26] ; 0 length files start cluster = 0 |
and eax,[fatMASK] |
xor ebp,ebp ; counter for directory deepnes |
call clear_directory |
pop eax |
jc delete_no_access |
push ebx ; save directory pointer in buffer |
mov ebx,buffer |
call hd_read ; read directory sector |
cmp [hd_error],0 |
jne delete_no_access_1 |
pop ebx |
delete_notdir: |
call delete_entry_name |
cmp [hd_error],0 |
jne delete_no_access |
mov eax,ecx ; first cluster of file |
call clear_cluster_chain |
cmp [hd_error],0 |
jne delete_no_access |
popad |
xor eax,eax |
ret |
delete_no_access_1: |
add esp,4 |
delete_no_access: |
popad |
mov eax,ERROR_ACCESS_DENIED |
ret |
file_to_delete_not_found: |
cmp [hd_error],0 |
jne delete_no_access |
popad |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
clear_cluster_chain: |
;----------------------------------------------------- |
; input : eax = first cluster |
;----------------------------------------------------- |
push eax ecx edx |
xor ecx,ecx ; cluster count |
mov [f_del],1 ; delete on |
clean_new_chain: |
cmp eax,[LAST_CLUSTER] ; end of file |
ja delete_OK |
cmp eax,2 ; unfinished fat chain or zero length file |
jb delete_OK |
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster |
jz delete_OK |
xor edx,edx |
call set_FAT ; clear fat entry |
cmp [hd_error],0 |
jne access_denied_01 |
inc ecx ; update cluster count |
mov eax,edx ; old cluster |
jmp clean_new_chain |
delete_OK: |
call add_disk_free_space ; add clusters to free disk space |
access_denied_01: |
mov [f_del],0 |
pop edx ecx eax |
ret |
clear_directory: |
;----------------------------------------------------- |
; input : eax = directory cluster |
; ebp = directory deepnes |
; Note : use recursive call |
;----------------------------------------------------- |
pushad |
inc ebp |
cmp ebp,64 ; if over 63 directory deep |
jnb clear_error ; something must be wrong |
clear_new_cluster: |
cmp eax,[LAST_CLUSTER] |
ja clear_end |
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster |
jz clear_end |
mov esi,eax ; esi = current directory cluster |
sub eax,2 |
jb clear_end |
mov ecx,[SECTORS_PER_CLUSTER] |
imul eax,ecx |
add eax,[DATA_START] |
clear_new_sector: |
mov edi,eax ; edi = current directory sector |
mov ebx,deltree_buffer |
call hd_read |
cmp [hd_error],0 |
jne clear_error |
mov edx,512/32 ; count of dir entrys per sector = 16 |
clear_analyze: |
mov al,[ebx+11] ; file attribute |
and al,0xf |
cmp al,0xf |
je clear_long_filename |
cmp byte [ebx],'.' ; parent or current directory |
je clear_next_entry |
cmp byte [ebx],0xe5 ; deleted |
je clear_next_entry |
cmp byte [ebx],0 ; empty |
je clear_write_last |
;je clear_next_entry |
mov eax,[ebx+20-2] ; first cluster of entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
test byte [ebx+11],0x10 ; is it directory? |
jz clear_file ; no |
push eax ebx |
mov eax,edi |
mov ebx,deltree_buffer ; save buffer over recursive call |
call hd_write ; write directory sector to disk |
cmp [hd_error],0 |
jne clear_error |
pop ebx eax |
call clear_directory ; recursive call !!! |
jc clear_error ; exit if error found |
push eax ebx |
mov eax,edi |
mov ebx,deltree_buffer |
call hd_read ; read directory sector again |
cmp [hd_error],0 |
jne clear_error_1 |
pop ebx eax |
clear_file: |
call clear_cluster_chain |
cmp [hd_error],0 |
jne clear_error |
clear_long_filename: |
mov byte [ebx],0xe5 |
clear_next_entry: |
add ebx,32 ; position of next dir entry |
dec edx |
jnz clear_analyze |
mov eax,edi |
mov ebx,deltree_buffer |
call hd_write ; write directory sector to disk |
cmp [hd_error],0 |
jne clear_error |
inc eax ; next sector |
dec ecx |
jnz clear_new_sector |
mov eax,esi |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne clear_error |
jmp clear_new_cluster ; clear it |
clear_write_last: |
mov eax,edi |
mov ebx,deltree_buffer |
call hd_write ; write directory sector to disk |
cmp [hd_error],0 |
jne clear_error |
clear_end: |
popad |
clc |
ret |
clear_error_1: |
add esp,8 |
clear_error: |
popad |
stc |
ret |
delete_entry_name: |
;----------------------------------------------------- |
; input : eax = directory sector |
; ebx = directory pointer in buffer |
; longname_sec = 2 previous directory sectors |
; output : ecx = first cluster |
; change : eax,ebx,edx |
;----------------------------------------------------- |
mov byte [ebx],0xe5 |
mov ecx,[ebx+20-2] ; first cluster of file |
mov cx,[ebx+26] ; 0 length files start cluster = 0 |
and ecx,[fatMASK] |
delete_empty: |
sub ebx,32 |
cmp ebx,buffer |
jnb delete_test_long |
mov ebx,buffer |
call hd_write ; write directory sector back |
cmp [hd_error],0 |
jne delete_name_end |
xor eax,eax |
xchg eax,[longname_sec2] |
xchg eax,[longname_sec1] |
test eax,eax ; is there previous directory sector? |
jz delete_name_end ; no |
mov ebx,buffer |
call hd_read ; read previous sector |
cmp [hd_error],0 |
jne delete_name_end |
mov ebx,buffer+0x1e0 ; start from last entry |
delete_test_long: |
mov dh,[ebx+11] ; file attribute |
and dh,0xf |
cmp dh,0xf |
jne delete_write_buffer |
cmp byte [ebx],0x40 ; end of long dir entry? |
mov byte [ebx],0xe5 |
jb delete_empty |
delete_write_buffer: |
mov ebx,buffer |
call hd_write ; write directory sector back |
delete_name_end: |
ret |
rename: |
;----------------------------------------------------------- |
; input : eax = source directory name |
; edx = source path |
; ebx = dest directory name |
; edi = dest path |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 8 - disk full |
; 10 - access denied |
;----------------------------------------------------------- |
cmp [fat_type],0 |
jnz fat_ok_for_rename |
mov eax,ERROR_UNKNOWN_FS |
ret |
fat_ok_for_rename: |
; call reserve_hd1 |
pushad |
mov ebx,edx ; source path |
call get_cluster_of_a_path |
jc rename_entry_not_found |
mov ebx,PUSHAD_EAX ; source directory name |
call analyze_directory |
jc rename_entry_not_found |
mov [sector_tmp],eax ; save source sector |
mov [entry_pos],ebx |
mov esi,ebx |
mov edi,dir_entry |
mov ecx,32/4 |
cld |
rep movsd ; save entry |
mov ebx,PUSHAD_EDI ; dest path |
call get_cluster_of_a_path |
jc rename_entry_not_found |
mov edx,eax ; save dest directory cluster |
mov ebx,PUSHAD_EBX ; dest directory name |
push [longname_sec1] |
push [longname_sec2] |
call analyze_directory ; check if entry already exist |
cmp [hd_error],0 |
jne rename_entry_already_exist_1 |
pop [longname_sec2] |
pop [longname_sec1] |
jnc rename_entry_already_exist |
mov eax,edx |
call analyze_directory_to_write |
jc rename_disk_full |
mov esi,dir_entry |
mov edi,ebx |
mov ecx,32/4 |
cld |
rep movsd ; copy entry |
mov esi,PUSHAD_EBX ; dest directory name |
mov edi,ebx |
mov ecx,11 |
rep movsb ; copy name |
mov ebx,buffer ; save the directory name,length,cluster |
call hd_write |
test byte [dir_entry+11],0x10 ; is it directory? |
jz rename_not_dir ; no |
mov eax,[dir_entry+20-2] ; FAT entry |
mov ax,[dir_entry+26] |
and eax,[fatMASK] |
call change_2dot_cluster |
cmp [hd_error],0 |
jne rename_entry_already_exist |
rename_not_dir: |
cmp [hd_error],0 |
jne rename_entry_already_exist |
mov eax,[sector_tmp] |
mov ebx,buffer |
call hd_read ; read source directory sector |
cmp [hd_error],0 |
jne rename_entry_already_exist |
mov ebx,[entry_pos] |
call delete_entry_name |
cmp [hd_error],0 |
jne rename_entry_already_exist |
popad |
call update_disk ; write all of cache and fat to hd |
cmp [hd_error],0 |
jne rename_entry_already_exist_2 |
mov [hd1_status],0 |
xor eax,eax |
ret |
rename_entry_not_found: |
cmp [hd_error],0 |
jne rename_entry_already_exist |
popad |
mov [hd1_status],0 |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
rename_entry_already_exist_1: |
add esp,8 |
rename_entry_already_exist: |
popad |
rename_entry_already_exist_2: |
mov [hd1_status],0 |
mov eax,ERROR_ACCESS_DENIED |
ret |
rename_disk_full: |
cmp [hd_error],0 |
jne rename_entry_already_exist |
popad |
mov [hd1_status],0 |
mov eax,ERROR_DISK_FULL |
ret |
change_2dot_cluster: |
;----------------------------------------------------------- |
; input : eax = directory cluster |
; edx = value to save |
; change : eax,ebx,edx |
;----------------------------------------------------------- |
cmp eax,[LAST_CLUSTER] |
ja not_2dot ; too big cluster number, something is wrong |
sub eax,2 |
jb not_2dot |
imul eax,[SECTORS_PER_CLUSTER] |
add eax,[DATA_START] |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne not_2dot |
cmp dword [ebx+32],'.. ' |
jnz not_2dot |
cmp edx,[ROOT_CLUSTER] ; is rootdir cluster? |
jne not_2dot_root |
xor edx,edx ; yes. set it zero |
not_2dot_root: |
mov [ebx+32+26],dx ; 16 bits low of cluster |
shr edx,16 |
mov [ebx+32+20],dx ; 16 bits high of cluster (=0 fat16) |
call hd_write |
not_2dot: |
ret |
get_hd_info: |
;----------------------------------------------------------- |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 10 - access denied |
; edx = cluster size in bytes |
; ebx = total clusters on disk |
; ecx = free clusters on disk |
;----------------------------------------------------------- |
cmp [fat_type],0 |
jnz info_fat_ok |
xor edx,edx |
xor ebx,ebx |
xor ecx,ecx |
mov eax,ERROR_UNKNOWN_FS |
ret |
info_fat_ok: |
; call reserve_hd1 |
xor ecx,ecx ; count of free clusters |
mov eax,2 |
mov ebx,[LAST_CLUSTER] |
info_cluster: |
push eax |
call get_FAT ; get cluster info |
cmp [hd_error],0 |
jne info_access_denied |
test eax,eax ; is it free? |
jnz info_used ; no |
inc ecx |
info_used: |
pop eax |
inc eax |
cmp eax,ebx ; is above last cluster? |
jbe info_cluster ; no. test next cluster |
dec ebx ; cluster count |
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes |
mov [hd1_status],0 |
xor eax,eax |
ret |
info_access_denied: |
add esp,4 |
xor edx,edx |
xor ebx,ebx |
xor ecx,ecx |
mov eax,ERROR_ACCESS_DENIED |
ret |
update_disk: |
;----------------------------------------------------------- |
; write changed fat and cache to disk |
;----------------------------------------------------------- |
cmp [fat_change],0 ; is fat changed? |
je upd_no_change |
call write_fat_sector |
cmp [hd_error],0 |
jne update_disk_acces_denied |
upd_no_change: |
call write_cache |
update_disk_acces_denied: |
ret |
;************************************************************************** |
; |
; 0x600008 - first entry in cache list |
; |
; +0 - lba sector |
; +4 - state of cache sector |
; 0 = empty |
; 1 = used for read ( same as in hd ) |
; 2 = used for write ( differs from hd ) |
; |
; +65536 - cache entries |
; |
;************************************************************************** |
hd_read: |
;----------------------------------------------------------- |
; input : eax = block to read |
; ebx = destination |
;----------------------------------------------------------- |
push ecx esi edi ; scan cache |
mov ecx,cache_max ; entries in cache |
mov esi,0x600000+8 |
mov edi,1 |
hdreadcache: |
cmp dword [esi+4],0 ; empty |
je nohdcache |
cmp [esi],eax ; correct sector |
je yeshdcache |
nohdcache: |
add esi,8 |
inc edi |
dec ecx |
jnz hdreadcache |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne return_01 |
push eax edx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_read_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
inc edx |
inc eax |
out dx,al ; ATASectorCount áç¥â稪 ᥪâ®à®¢ |
inc edx |
mov eax,[esp+4] |
out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
shr eax,8 |
inc edx |
out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
shr eax,8 |
inc edx |
out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
inc edx |
mov al,20h |
out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_read_error |
cli |
push edi |
shl edi,9 |
add edi,0x600000+65536 |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep insw |
pop edi |
sti |
pop edx eax |
blok_read_2: |
lea esi,[edi*8+0x600000] |
mov [esi],eax ; sector number |
mov dword [esi+4],1 ; hd read - mark as same as in hd |
yeshdcache: |
mov esi,edi |
shl esi,9 |
add esi,0x600000+65536 |
mov edi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
return_01: |
pop edi esi ecx |
ret |
hd_write: |
;----------------------------------------------------------- |
; input : eax = block |
; ebx = pointer to memory |
;----------------------------------------------------------- |
push ecx esi edi |
; check if the cache already has the sector and overwrite it |
mov ecx,cache_max |
mov esi,0x600000+8 |
mov edi,1 |
hdwritecache: |
cmp dword [esi+4],0 ; if cache slot is empty |
je not_in_cache_write |
cmp [esi],eax ; if the slot has the sector |
je yes_in_cache_write |
not_in_cache_write: |
add esi,8 |
inc edi |
dec ecx |
jnz hdwritecache |
; sector not found in cache |
; write the block to a new location |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne hd_write_access_denied |
lea esi,[edi*8+0x600000] |
mov [esi],eax ; sector number |
yes_in_cache_write: |
mov dword [esi+4],2 ; write - differs from hd |
shl edi,9 |
add edi,0x600000+65536 |
mov esi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
hd_write_access_denied: |
pop edi esi ecx |
ret |
write_cache: |
;----------------------------------------------------------- |
; write all changed sectors to disk |
;----------------------------------------------------------- |
push eax ecx edx esi edi |
; write difference ( 2 ) from cache to hd |
mov ecx,cache_max |
mov esi,0x600000+8 |
mov edi,1 |
write_cache_more: |
cmp dword [esi+4],2 ; if cache slot is not different |
jne does_not_need_writing |
mov dword [esi+4],1 ; same as in hd |
mov eax,[esi] ; eax = sector to write |
cmp eax,[PARTITION_START] |
jb danger |
cmp eax,[PARTITION_END] |
ja danger |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_write_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esi] ; eax = sector to write |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,30h |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_write_error |
push ecx esi |
cli |
mov esi,edi |
shl esi,9 |
add esi,0x600000+65536 ; esi = from memory position |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep outsw |
sti |
pop esi ecx |
danger: |
does_not_need_writing: |
add esi,8 |
inc edi |
dec ecx |
jnz write_cache_more |
return_02: |
pop edi esi edx ecx eax |
ret |
find_empty_slot: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 10% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
push ecx esi |
search_again: |
mov ecx,cache_max*10/100 |
mov edi,[cache_search_start] |
search_for_empty: |
inc edi |
cmp edi,cache_max |
jbe inside_cache |
mov edi,1 |
inside_cache: |
cmp dword [edi*8+0x600000+4],2 ; get cache slot info |
jb found_slot ; it's empty or read |
dec ecx |
jnz search_for_empty |
call write_cache ; no empty slots found, write all |
cmp [hd_error],0 |
jne found_slot_access_denied |
jmp search_again ; and start again |
found_slot: |
mov [cache_search_start],edi |
found_slot_access_denied: |
pop esi ecx |
ret |
save_hd_wait_timeout: |
push eax |
mov eax,[timer_ticks];[0xfdf0] |
add eax,300 ; 3 sec timeout |
mov [hd_wait_timeout],eax |
pop eax |
ret |
check_hd_wait_timeout: |
push eax |
mov eax,[hd_wait_timeout] |
cmp [timer_ticks], eax ;[0xfdf0],eax |
jg hd_timeout_error |
pop eax |
mov [hd_error],0 |
ret |
iglobal |
hd_timeout_str db 'K : FS - HD timeout',13,10,0 |
hd_read_str db 'K : FS - HD read error',13,10,0 |
hd_write_str db 'K : FS - HD write error',13,10,0 |
hd_lba_str db 'K : FS - HD LBA error',13,10,0 |
endg |
hd_timeout_error: |
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_timeout_str |
call sys_msg_board_str |
; jmp $ |
mov [hd_error],1 |
pop eax |
ret |
hd_read_error: |
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_read_str |
call sys_msg_board_str |
pop edx eax |
jmp return_01 |
; jmp $ |
hd_write_error: |
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_write_str |
call sys_msg_board_str |
jmp return_02 |
; jmp $ |
hd_lba_error: |
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_lba_str |
call sys_msg_board_str |
jmp LBA_read_ret |
wait_for_hd_idle: |
push eax edx |
call save_hd_wait_timeout |
mov edx,[hdbase] |
add edx,0x7 |
wfhil1: |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,128 |
jnz wfhil1 |
@@: |
pop edx eax |
ret |
wait_for_sector_buffer: |
push eax edx |
mov edx,[hdbase] |
add edx,0x7 |
call save_hd_wait_timeout |
hdwait_sbuf: ; wait for sector buffer to be ready |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,8 |
jz hdwait_sbuf |
mov [hd_error],0 |
cmp [hd_setup],1 ; do not mark error for setup request |
je buf_wait_ok |
test al,1 ; previous command ended up with an error |
jz buf_wait_ok |
@@: |
mov [hd_error],1 |
buf_wait_ok: |
pop edx eax |
ret |
read_hd_file: |
;----------------------------------------------------------------- |
; |
; Converting old reading function for hd-application start. |
; |
; IN: |
; |
; eax - pointer to file (0 = read only first sector of drive: eg 'label') |
; ebx - file lenght |
; ecx - start 512 byte block number |
; edx - number of blocks to read |
; esi - pointer to return/work area (atleast 20 000 bytes) |
; |
; For new read function |
; |
; EAX (PAR0) pointer to file-name |
; ECX (PAR1) pointer to buffer |
; EBX (PAR2) vt file blocks to read |
; EDX (PAR3) pointer to path |
; ESI vt first 512 block to read |
; EDI if 0 - return root |
;-------------------------------------------------------------------------- |
push ecx esi edi |
mov esi,eax |
mov edi,startpath |
mov ecx,250 |
cld |
rep movsb |
pop edi esi ecx |
mov eax,startpath |
mov [eax+ebx-12],byte 0 |
push eax ebx ecx edx esi |
pop ecx ; pointer to buffer |
add ecx,1024 |
pop ebx ; number of blocks to read |
pop esi ; first block to read |
dec esi |
pop eax ; file length |
pop edx ; pointer to path |
mov edi,12 |
lea eax,[eax+edx-12+1] |
call file_read |
ret |
; \begin{diamond} |
hd_find_lfn: |
; in: esi->name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry, eax=sector |
; destroys eax |
push esi edi |
push 0 |
push 0 |
push fat16_root_first |
push fat16_root_next |
mov eax, [ROOT_CLUSTER] |
cmp [fat_type], 32 |
jz .fat32 |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
test byte [edi+11], 10h |
jz .notfound |
and dword [esp+12], 0 |
mov eax, [edi+20-2] |
mov ax, [edi+26] ; cluster |
.fat32: |
mov [esp+8], eax |
mov dword [esp+4], fat_notroot_first |
mov dword [esp], fat_notroot_next |
jmp .loop |
.notfound: |
add esp, 16 |
pop edi esi |
stc |
ret |
.found: |
lea eax, [esp+8] |
cmp dword [eax], 0 |
jz .root |
call fat_get_sector |
jmp .cmn |
.root: |
mov eax, [eax+4] |
add eax, [ROOT_START] |
.cmn: |
add esp, 20 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdRead - LFN variant for reading hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdRead: |
cmp [fat_type], 0 |
jnz @f |
or ebx, -1 |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
push edi |
cmp byte [esi], 0 |
jnz @f |
.noaccess: |
pop edi |
.noaccess_2: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.noaccess_3: |
add esp,4 |
.noaccess_1: |
add esp,4 |
.noaccess_4: |
add esp,4*5 |
jmp .noaccess_2 |
@@: |
call hd_find_lfn |
jnc .found |
pop edi |
cmp [hd_error],0 |
jne .noaccess_2 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read directories |
jnz .noaccess |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 |
@@: |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data |
.new_cluster: |
jecxz .new_sector |
test eax, eax |
jz .eof |
cmp eax, [fatRESERVED] |
jae .eof |
mov [cluster_tmp], eax |
dec eax |
dec eax |
mov edi, [SECTORS_PER_CLUSTER] |
imul eax, edi |
add eax, [DATA_START] |
.new_sector: |
test ecx, ecx |
jz .done |
sub ebx, 512 |
jae .skip |
add ebx, 512 |
jnz .force_buf |
cmp ecx, 512 |
jb .force_buf |
; we may read directly to given buffer |
push ebx |
mov ebx, edx |
call hd_read |
cmp [hd_error],0 |
jne .noaccess_1 |
pop ebx |
add edx, 512 |
sub ecx, 512 |
jmp .skip |
.force_buf: |
; we must read sector to temporary buffer and then copy it to destination |
push eax ebx |
mov ebx, buffer |
call hd_read |
cmp [hd_error],0 |
jne .noaccess_3 |
mov eax, ebx |
pop ebx |
add eax, ebx |
push ecx |
add ecx, ebx |
cmp ecx, 512 |
jbe @f |
mov ecx, 512 |
@@: |
sub ecx, ebx |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
pop eax |
xor ebx, ebx |
.skip: |
inc eax |
dec edi |
jnz .new_sector |
mov eax, [cluster_tmp] |
call get_FAT |
cmp [hd_error],0 |
jne .noaccess_4 |
jmp .new_cluster |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
;---------------------------------------------------------------- |
; |
; fs_HdReadFolder - LFN variant for reading hard disk folder |
; |
; esi points to filename |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdReadFolder: |
mov eax, [ROOT_CLUSTER] |
push edi |
cmp byte [esi], 0 |
jz .doit |
call hd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read files |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
mov eax, [edi+20-2] |
mov ax, [edi+26] ; eax=cluster |
.doit: |
push esi ecx |
push ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov esi, edi ; esi points to BDFE |
.new_cluster: |
mov [cluster_tmp], eax |
test eax, eax |
jnz @f |
cmp [fat_type], 32 |
jz .notfound |
mov eax, [ROOT_START] |
push [ROOT_SECTORS] |
push ebx |
jmp .new_sector |
@@: |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
push [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
push ebx |
.new_sector: |
mov ebx, buffer |
mov edi, ebx |
call hd_read |
cmp [hd_error], 0 |
jnz .notfound2 |
add ebx, 512 |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
cmp edi, ebx |
jb .do_bdfe |
pop eax |
inc eax |
dec dword [esp+4] |
jnz @f |
mov eax, [cluster_tmp] |
test eax, eax |
jz .done |
call get_FAT |
cmp [hd_error], 0 |
jnz .notfound2 |
cmp eax, 2 |
jb .done |
cmp eax, [fatRESERVED] |
jae .done |
push eax |
mov eax, [SECTORS_PER_CLUSTER] |
mov [esp+8], eax |
pop eax |
mov [cluster_tmp], eax |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
@@: |
mov ebx, buffer |
mov edi, ebx |
call hd_read |
cmp [hd_error], 0 |
jnz .notfound2 |
add ebx, 512 |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec dword [esp+4] |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
cmp edi, ebx |
jb .l1 |
pop eax |
inc eax |
dec dword [esp+4] |
jnz .new_sector |
mov eax, [cluster_tmp] |
test eax, eax |
jz .done |
call get_FAT |
cmp [hd_error], 0 |
jnz .notfound2 |
cmp eax, 2 |
jb .done |
cmp eax, [fatRESERVED] |
jae .done |
push eax |
mov eax, [SECTORS_PER_CLUSTER] |
mov [esp+8], eax |
pop eax |
pop ebx |
add esp, 4 |
jmp .new_cluster |
.notfound2: |
add esp, 8 |
.notfound: |
add esp, 262*2+4 |
pop ebp ecx esi edi |
mov eax, ERROR_FILE_NOT_FOUND |
or ebx, -1 |
ret |
.done: |
add esp, 262*2+4+8 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi |
ret |
fat16_root_next: |
cmp edi, buffer+0x200-0x20 |
jae fat16_root_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat16_root_next_sector: |
; read next sector |
push ecx |
mov ecx, [eax+4] |
inc ecx |
mov [eax+4], ecx |
cmp ecx, [ROOT_SECTORS] |
pop ecx |
jae fat16_root_first.readerr |
fat16_root_first: |
mov eax, [eax+4] |
add eax, [ROOT_START] |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz .readerr |
ret ; CF=0 |
.readerr: |
stc |
ret |
fat16_root_begin_write: |
push edi eax |
call fat16_root_first |
pop eax edi |
ret |
fat16_root_end_write: |
pusha |
mov eax, [eax+4] |
add eax, [ROOT_START] |
mov ebx, buffer |
call hd_write |
popa |
ret |
fat16_root_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
call fat16_root_end_write |
jmp fat16_root_next_sector |
fat16_root_extend_dir: |
stc |
ret |
fat_notroot_next: |
cmp edi, buffer+0x200-0x20 |
jae fat_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat_notroot_next_sector: |
push ecx |
mov ecx, [eax+4] |
inc ecx |
cmp ecx, [SECTORS_PER_CLUSTER] |
jae fat_notroot_next_cluster |
mov [eax+4], ecx |
jmp @f |
fat_notroot_next_cluster: |
push eax |
mov eax, [eax] |
call get_FAT |
mov ecx, eax |
pop eax |
cmp [hd_error], 0 |
jnz fat_notroot_next_err |
cmp ecx, [fatRESERVED] |
jae fat_notroot_next_err |
mov [eax], ecx |
and dword [eax+4], 0 |
@@: |
pop ecx |
fat_notroot_first: |
call fat_get_sector |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz @f |
ret ; CF=0 |
fat_notroot_next_err: |
pop ecx |
@@: |
stc |
ret |
fat_notroot_begin_write: |
push eax edi |
call fat_notroot_first |
pop edi eax |
ret |
fat_notroot_end_write: |
call fat_get_sector |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
ret |
fat_notroot_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
push eax |
call fat_notroot_end_write |
pop eax |
jmp fat_notroot_next_sector |
fat_notroot_extend_dir: |
push eax |
mov eax, [eax] |
call get_free_FAT |
jnc .found |
pop eax |
ret ; CF=1 |
.found: |
push edx |
mov edx, [fatEND] |
call set_FAT |
mov edx, eax |
mov eax, [esp+4] |
mov eax, [eax] |
push edx |
mov [f_del], 1 |
call set_FAT |
pop edx |
cmp [hd_error], 0 |
jz @f |
pop edx |
pop eax |
stc |
ret |
@@: |
push ecx |
or ecx, -1 |
call add_disk_free_space |
; zero new cluster |
mov ecx, 512/4 |
mov edi, buffer |
push edi |
xor eax, eax |
rep stosd |
pop edi |
pop ecx |
mov eax, [esp+4] |
mov [eax], edx |
and dword [eax+4], 0 |
pop edx |
mov eax, [eax] |
dec eax |
dec eax |
push ebx ecx |
mov ecx, [SECTORS_PER_CLUSTER] |
imul eax, ecx |
add eax, [DATA_START] |
mov ebx, edi |
@@: |
call hd_write |
inc eax |
loop @b |
pop ecx ebx eax |
clc |
ret |
fat_get_sector: |
push ecx |
mov ecx, [eax] |
dec ecx |
dec ecx |
imul ecx, [SECTORS_PER_CLUSTER] |
add ecx, [DATA_START] |
add ecx, [eax+4] |
mov eax, ecx |
pop ecx |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdRewrite - LFN variant for writing hard disk |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fshrad: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fshrfs: |
mov eax, ERROR_UNKNOWN_FS |
xor ebx, ebx |
ret |
fs_HdRewrite: |
cmp [fat_type], 0 |
jz fshrfs |
cmp byte [esi], 0 |
jz fshrad |
pushad |
xor ebp, ebp |
push esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea ebp, [esi-1] |
jmp @b |
@@: |
pop esi |
test ebp, ebp |
jnz .noroot |
mov ebp, [ROOT_CLUSTER] |
cmp [fat_type], 32 |
jz .pushnotroot |
push fat16_root_extend_dir |
push fat16_root_end_write |
push fat16_root_next_write |
push fat16_root_begin_write |
xor ebp, ebp |
push ebp |
push ebp |
push fat16_root_first |
push fat16_root_next |
jmp .common1 |
.noroot: |
; check existence |
mov byte [ebp], 0 |
call hd_find_lfn |
mov byte [ebp], '/' |
lea esi, [ebp+1] |
jnc @f |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
mov ebp, [edi+20-2] |
mov bp, [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
.pushnotroot: |
push fat_notroot_extend_dir |
push fat_notroot_end_write |
push fat_notroot_next_write |
push fat_notroot_begin_write |
push 0 |
push ebp |
push fat_notroot_first |
push fat_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found; must not be directory |
test byte [edi+11], 10h |
jz @f |
add esp, 32 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xor ecx, ecx |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov word [edi+20], cx |
mov word [edi+26], cx |
test eax, eax |
jz .done1 |
mov [f_del], 1 |
@@: |
cmp eax, [fatRESERVED] |
jae .done1 |
push edx |
xor edx, edx |
call set_FAT |
mov eax, edx |
pop edx |
inc ecx |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 32 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+32 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+16+8+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
pop eax |
jnc .scan_dir |
.fsfrfe3: |
add esp, 12+8+12+32 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [hd_error], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax+20] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 12+8+12+32 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+12+8+12+8] |
mov [esp+4], ecx |
mov ecx, [esp+12+8+12+12] |
mov [esp+8], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+12] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+12] |
pop dword [esp+8+12+12] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+12] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+16] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
xor ecx, ecx |
mov word [edi+20], cx ; high word of cluster |
mov word [edi+26], cx ; low word of cluster - to be filled |
mov dword [edi+28], ecx ; file size - to be filled |
.doit: |
lea eax, [esp+8] |
call dword [eax+16] ; flush directory |
push ecx |
mov ecx, [esp+4+32+24] |
push ecx |
push edi |
mov esi, edx |
test ecx, ecx |
jz .done |
mov eax, 2 |
call get_free_FAT |
jc .diskfull |
push eax |
mov [edi+26], ax |
shr eax, 16 |
mov [edi+20], ax |
lea eax, [esp+16+8] |
call dword [eax+16] ; flush directory |
pop eax |
push edx |
mov edx, [fatEND] |
call set_FAT |
pop edx |
.write_cluster: |
push eax |
dec eax |
dec eax |
mov ebp, [SECTORS_PER_CLUSTER] |
imul eax, ebp |
add eax, [DATA_START] |
; write data |
.write_sector: |
mov ecx, 512 |
cmp dword [esp+8], ecx |
jb .writeshort |
; we can write directly from given buffer |
mov ebx, esi |
add esi, ecx |
jmp .writecommon |
.writeshort: |
mov ecx, [esp+8] |
push ecx |
mov edi, buffer |
mov ebx, edi |
rep movsb |
mov ecx, buffer+0x200 |
sub ecx, edi |
push eax |
xor eax, eax |
rep stosb |
pop eax |
pop ecx |
.writecommon: |
call hd_write |
cmp [hd_error], 0 |
jnz .writeerr |
inc eax |
sub dword [esp+8], ecx |
jz .writedone |
dec ebp |
jnz .write_sector |
; allocate new cluster |
pop eax |
mov ecx, eax |
call get_free_FAT |
jc .diskfull |
mov [f_del], 1 |
push edx |
mov edx, [fatEND] |
call set_FAT |
xchg eax, ecx |
mov edx, ecx |
call set_FAT |
pop edx |
xchg eax, ecx |
jmp .write_cluster |
.diskfull: |
mov eax, ERROR_DISK_FULL |
jmp .ret |
.writeerr: |
pop eax |
sub esi, ecx |
mov eax, 11 |
jmp .ret |
.writedone: |
pop eax |
.done: |
xor eax, eax |
.ret: |
pop edi ecx |
mov ebx, esi |
sub ebx, edx |
pop ebp |
mov [esp+32+28], eax |
lea eax, [esp+8] |
call dword [eax+8] |
mov [edi+28], ebx |
call dword [eax+16] |
mov [esp+32+16], ebx |
lea eax, [ebx+511] |
shr eax, 9 |
mov ecx, [SECTORS_PER_CLUSTER] |
lea eax, [eax+ecx-1] |
xor edx, edx |
div ecx |
mov ecx, ebp |
sub ecx, eax |
call add_disk_free_space |
add esp, 32 |
call update_disk |
popad |
ret |
fs_HdGetFileInfo: |
cmp [fat_type], 0 |
jnz @f |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jmp fs_GetFileInfo_finish |
fs_HdSetFileInfo: |
cmp [fat_type], 0 |
jnz @f |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push eax |
call bdfe_to_fat_entry |
pop eax |
mov ebx, buffer |
call hd_write |
call update_disk |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdExecute - LFN variant for executing from harddisk |
; |
; esi points to hd filename (e.g. 'dir1/name') |
; ebp points to full filename (e.g. '/hd0/1/dir1/name') |
; dword [ebx] = flags |
; dword [ebx+4] = cmdline |
; |
; ret ebx,edx destroyed |
; eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
fs_HdExecute: |
mov edx, [ebx] |
mov ebx, [ebx+4] |
test ebx, ebx |
jz @f |
add ebx, std_application_base_address |
@@: |
;---------------------------------------------------------------- |
; |
; fs_HdExecute.flags - second entry |
; |
; esi points to floppy filename (kernel address) |
; ebp points to full filename |
; edx flags |
; ebx cmdline (kernel address) |
; |
; ret eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
.flags: |
cmp [fat_type], 0 |
jnz @f |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
; cannot execute root! |
mov eax, -ERROR_ACCESS_DENIED |
ret |
@@: |
push edi |
call hd_find_lfn |
jnc .found |
pop edi |
mov eax, -ERROR_FILE_NOT_FOUND |
cmp [hd_error], 0 |
jz @f |
mov al, -11 |
@@: |
ret |
.found: |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
push 0 |
push eax |
push dword [edi+28] ; size |
push .DoRead |
call fs_execute |
add esp, 16 |
pop edi |
ret |
.DoRead: |
; read next block |
; in: eax->parameters, edi->buffer |
; out: eax = error code |
pushad |
cmp dword [eax], 0 ; file size |
jz .eof |
add eax, 4 |
call fat_get_sector |
mov ebx, edi |
call hd_read |
cmp [hd_error], 0 |
jnz .err |
mov eax, [esp+28] |
mov ecx, [eax] |
sub ecx, 512 |
jae @f |
lea edi, [edi+ecx+512] |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
@@: |
mov [eax], ecx |
mov edx, [eax+8] |
inc edx |
cmp edx, [SECTORS_PER_CLUSTER] |
jb @f |
push eax |
mov eax, [eax+4] |
call get_FAT |
cmp [hd_error], 0 |
jnz .err |
mov ecx, eax |
pop eax |
mov [eax+4], ecx |
xor edx, edx |
@@: |
mov [eax+8], edx |
popad |
xor eax, eax |
ret |
.eof: |
popad |
mov eax, 6 |
ret |
.err: |
popad |
mov eax, 11 |
ret |
; \end{diamond} |
/kernel/branches/gfx_kernel/fs/fs.inc |
---|
0,0 → 1,1057 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; System service for filesystem call ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; 29.04.2006 Elimination of hangup after the ;; |
;; expiration hd_wait_timeout (for LBA) - Mario79 ;; |
;; xx.04.2006 LFN support - diamond ;; |
;; 15.01.2005 get file size/attr/date, file_append (only for hd) - ATV ;; |
;; 23.11.2004 test if hd/partition is set - ATV ;; |
;; 18.11.2004 get_disk_info and more error codes - ATV ;; |
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;; |
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
dir0: db 'HARDDISK ' |
db 'RAMDISK ' |
db 'FLOPPYDISK ' |
db 0 |
dir1: db 'FIRST ' |
db 'SECOND ' |
db 'THIRD ' |
db 'FOURTH ' |
db 0 |
not_select_IDE db 0 |
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10 |
dd 0x170,0x00,0x170,0x10 |
endg |
file_system: |
; IN: |
; |
; eax = 0 ; read file /RamDisk/First 6 /HardDisk/First 30 |
; eax = 1 ; write file /RamDisk/First 33 /HardDisk/First 56 |
; eax = 2 ; delete file /RamDisk/First 32 /HardDisk/First 57 |
; eax = 3 ; append to a file /RamDisk/First ?? /HardDisk/First ?? |
; eax = 4 ; makedir |
; eax = 5 ; rename file/directory |
; eax = 8 ; lba read |
; eax = 15 ; get_disk_info |
; eax = 16 ; start application |
; |
; OUT: |
; |
; eax = 0 : read ok |
; eax = 1 : no hd base and/or partition defined |
; eax = 2 : function is unsupported for this FS |
; eax = 3 : unknown FS |
; eax = 4 : partition not defined at hd |
; eax = 5 : file not found |
; eax = 6 : end of file |
; eax = 7 : memory pointer not in application area |
; eax = 8 : disk full |
; eax = 9 : fat table corrupted |
; eax = 10 : access denied |
; eax = 11 : disk error |
; |
; ebx = size |
; \begin{diamond}[18.03.2006] |
; for subfunction 16 (start application) error codes must be negative |
; because positive values are valid PIDs |
; so possible return values are: |
; eax > 0 : process created, eax=PID |
; -0x10 <= eax < 0 : -eax is filesystem error code: |
; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined |
; eax = -3 = 0xFFFFFFFD : unknown FS |
; eax = -5 = 0xFFFFFFFB : file not found |
; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file) |
; eax = -9 = 0xFFFFFFF7 : fat table corrupted |
; eax = -10 = 0xFFFFFFF6 : access denied |
; -0x20 <= eax < -0x10: eax is process creation error code: |
; eax = -0x20 = 0xFFFFFFE0 : too many processes |
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable |
; eax = -0x1E = 0xFFFFFFE2 : no memory |
; ebx is not changed |
; \end{diamond}[18.03.2006] |
; Extract parameters |
add eax, std_application_base_address ; abs start of info block |
cmp dword [eax+0],15 ; GET_DISK_INFO |
je fs_info |
cmp dword [eax+0],16 ; RUN - dont care about read&write blocks |
je fs_read |
cmp dword [eax+0],5 ; RENAME - dont care about read&write blocks |
je fs_read |
cmp dword [eax+0],4 ; MAKEDIR - dont care about read&write blocks |
je fs_read |
cmp dword [eax+0],2 ; DELETE - dont care about read&write blocks |
je fs_read |
cmp dword [0x3000],1 ; no memory checks for kernel requests |
jz no_checks_for_kernel |
mov edx,eax |
cmp dword [eax+0],1 |
jz .check_for_write_op |
cmp dword [eax+0],3 |
jnz .usual_check |
.check_for_write_op: |
mov ebx,[eax+12] |
add ebx,std_application_base_address |
mov ecx,[eax+8] |
call check_region |
test eax,eax |
jnz area_in_app_mem |
.error_output: |
mov esi,buffer_failed |
call sys_msg_board_str |
; mov eax,7 |
mov dword [esp+36],7 |
ret |
iglobal |
buffer_failed db 'K : Buffer check failed',13,10,0 |
endg |
.usual_check: |
cmp dword [eax+0],0 |
mov ecx,512 |
jnz .small_size |
mov ecx,[eax+8] |
shl ecx,9 |
.small_size: |
mov ebx,[eax+12] |
add ebx,std_application_base_address |
call check_region |
test eax,eax |
jz .error_output |
area_in_app_mem: |
mov eax,edx |
no_checks_for_kernel: |
cmp dword [eax+0],3 ; APPEND - allow write 0 bytes (truncate) |
je fs_read |
cmp dword [eax+8],0 ; read or write 0 blocks/bytes ? |
jne fs_read |
and dword [esp+36],0 |
ret |
fs_read: |
mov ebx,[eax+20] ; program wants root directory ? |
test bl,bl |
je fs_getroot |
test bh,bh |
jne fs_noroot |
fs_getroot: |
; \begin{diamond}[18.03.2006] |
; root - only read is allowed |
; other operations return "access denied", eax=10 |
; (execute operation returns eax=-10) |
cmp dword [eax], 0 |
jz .read_root |
mov ecx, 10 |
cmp dword [eax], 16 |
jnz @f |
neg ecx |
@@: mov [esp+36], ecx |
ret |
.read_root: |
; \end{diamond}[18.03.2006] |
mov esi,dir0 |
mov edi,[eax+12] |
add edi,std_application_base_address |
mov ecx,11 |
push ecx |
; cld ; already is |
rep movsb |
mov al,0x10 |
stosb |
add edi,32-11-1 |
pop ecx |
rep movsb |
stosb |
and dword [esp+36],0 ; ok read |
mov dword [esp+24],32*2 ; size of root |
ret |
fs_info: ;start of code - Mihasik |
push eax |
cmp [eax+21],byte 'h' |
je fs_info_h |
cmp [eax+21],byte 'H' |
je fs_info_h |
cmp [eax+21],byte 'r' |
je fs_info_r |
cmp [eax+21],byte 'R' |
je fs_info_r |
mov eax,3 ;if unknown disk |
xor ebx,ebx |
xor ecx,ecx |
xor edx,edx |
jmp fs_info1 |
fs_info_r: |
call ramdisk_free_space ;if ramdisk |
mov ecx,edi ;free space in ecx |
shr ecx,9 ;free clusters |
mov ebx,2847 ;total clusters |
mov edx,512 ;cluster size |
xor eax,eax ;always 0 |
jmp fs_info1 |
fs_info_h: ;if harddisk |
call get_hd_info |
fs_info1: |
pop edi |
mov [esp+36],eax |
mov [esp+24],ebx ; total clusters on disk |
mov [esp+32],ecx ; free clusters on disk |
mov [edi],edx ; cluster size in bytes |
ret ;end of code - Mihasik |
fs_noroot: |
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run |
push dword [eax+4] ; 512 block number to read |
push dword [eax+8] ; bytes to write/append or 512 blocks to read |
mov ebx,[eax+12] |
add ebx,std_application_base_address |
push ebx ; abs start of return/save area |
lea esi,[eax+20] ; abs start of dir + filename |
mov edi,[eax+16] |
add edi,std_application_base_address ; abs start of work area |
call expand_pathz |
push edi ; dir start |
push ebx ; name of file start |
mov eax,[edi+1] |
cmp eax,'RD ' |
je fs_yesramdisk |
cmp eax,'RAMD' |
jne fs_noramdisk |
fs_yesramdisk: |
cmp byte [edi+1+11],0 |
je fs_give_dir1 |
mov eax,[edi+1+12] |
cmp eax,'1 ' |
je fs_yesramdisk_first |
cmp eax,'FIRS' |
jne fs_noramdisk |
fs_yesramdisk_first: |
cmp dword [esp+20],8 ; LBA read ramdisk |
jne fs_no_LBA_read_ramdisk |
mov eax,[esp+16] ; LBA block to read |
mov ecx,[esp+8] ; abs pointer to return area |
call LBA_read_ramdisk |
jmp file_system_return |
fs_no_LBA_read_ramdisk: |
cmp dword [esp+20],0 ; READ |
jne fs_noramdisk_read |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+16] ; block start |
inc ebx |
mov ecx,[esp+12] ; block count |
mov edx,[esp+8] ; return |
mov esi,[esp+0] |
sub esi,eax |
add esi,12+1 ; file name length |
call fileread |
jmp file_system_return |
fs_noramdisk_read: |
cmp dword [esp+20],1 ; WRITE |
jne fs_noramdisk_write |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+8] ; buffer |
mov ecx,[esp+12] ; count to write |
mov edx,0 ; create new |
call filesave |
; eax=0 ok - eax=1 not enough free space |
jmp file_system_return |
fs_noramdisk_write: |
cmp dword [esp+20],16 ; START APPLICATION |
jne fs_noramdisk_start_application |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
xor ebx,ebx ; parameters to pass |
cmp dword [esp+12],ebx;0 |
je no_fl_start_param |
mov ebx, [esp+12] |
add ebx, std_application_base_address |
no_fl_start_param: |
mov edx,[esp+16] ; flags |
call start_application_fl |
jmp file_system_startapp_return |
fs_noramdisk_start_application: ;there's new code - Mihasik |
cmp dword [esp+20],2 ;DELETE |
jne fs_noramdisk_delete |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
call filedelete |
jmp file_system_return |
fs_noramdisk_delete: |
fs_noramdisk: |
;******************************************************************** |
mov eax,[edi+1] |
cmp eax,'FD ' |
je fs_yesflpdisk |
cmp eax,'FLOP' |
jne fs_noflpdisk |
fs_yesflpdisk: |
call reserve_flp |
cmp byte [edi+1+11],0 |
je fs_give_dir1 |
mov eax,[edi+1+12] |
cmp eax,'1 ' |
je fs_yesflpdisk_first |
cmp eax,'FIRS' |
je fs_yesflpdisk_first |
cmp eax,'2 ' |
je fs_yesflpdisk_second |
cmp eax,'SECO' |
jne fs_noflpdisk |
jmp fs_yesflpdisk_second |
fs_yesflpdisk_first: |
mov [flp_number],1 |
jmp fs_yesflpdisk_start |
fs_yesflpdisk_second: |
mov [flp_number],2 |
fs_yesflpdisk_start: |
cmp dword [esp+20],0 ; READ |
jne fs_noflpdisk_read |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+16] ; block start |
inc ebx |
mov ecx,[esp+12] ; block count |
mov edx,[esp+8] ; return |
mov esi,[esp+0] |
sub esi,eax |
add esi,12+1 ; file name length |
call floppy_fileread |
jmp file_system_return |
fs_noflpdisk_read: |
cmp dword [esp+20],1 ; WRITE |
jne fs_noflpdisk_write |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+8] ; buffer |
mov ecx,[esp+12] ; count to write |
mov edx,0 ; create new |
call floppy_filesave |
; eax=0 ok - eax=1 not enough free space |
jmp file_system_return |
fs_noflpdisk_write: |
cmp dword [esp+20],2 ; DELETE |
jne fs_noflpdisk_delete |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
call floppy_filedelete |
mov [flp_status],0 |
jmp file_system_return |
fs_noflpdisk_delete: |
cmp dword [esp+20],16 ; START APPLICATION |
jne fs_noflpdisk_start_application |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
xor ebx,ebx ; parameters to pass |
cmp dword [esp+12],ebx;0 |
je no_flp_start_param |
mov ebx,[0x3010] |
mov ebx,[ebx+0x10] |
add ebx,[esp+12] |
no_flp_start_param: |
mov edx,[esp+16] ; flags |
call start_application_floppy |
file_system_startapp_return: |
mov ebx, [esp+24+24] ; do not modify ebx in application |
jmp file_system_return |
fs_noflpdisk_start_application: |
fs_noflpdisk: |
;***************************************************************** |
mov eax,[edi+1] |
cmp eax,'HD0 ' |
je fs_yesharddisk_IDE0 |
cmp eax,'HD1 ' |
je fs_yesharddisk_IDE1 |
cmp eax,'HD2 ' |
je fs_yesharddisk_IDE2 |
cmp eax,'HD3 ' |
je fs_yesharddisk_IDE3 |
jmp old_path_harddisk |
fs_yesharddisk_IDE0: |
call reserve_hd1 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE1: |
call reserve_hd1 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE2: |
call reserve_hd1 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE3: |
call reserve_hd1 |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
fs_yesharddisk_partition: |
; call choice_necessity_partition |
; jmp fs_yesharddisk_all |
jmp fs_for_new_semantic |
choice_necessity_partition: |
mov eax,[edi+1+12] |
call StringToNumber |
mov [fat32part],eax |
choice_necessity_partition_1: |
mov ecx,[hdpos] |
xor eax,eax |
mov [0xfe10], eax ; entries in hd cache |
mov edx,0x40002 |
search_partition_array: |
mov bl,[edx] |
movzx ebx,bl |
add eax,ebx |
inc edx |
loop search_partition_array |
sub eax,ebx |
add eax,[fat32part] |
dec eax |
xor edx,edx |
imul eax,100 |
add eax,0x4000a |
mov [transfer_adress],eax |
call partition_data_transfer_1 |
ret |
old_path_harddisk: |
mov eax,[edi+1] |
cmp eax,'HD ' |
je fs_yesharddisk |
cmp eax,'HARD' |
jne fs_noharddisk |
fs_yesharddisk: |
cmp dword [esp+20],8 ; LBA read |
jne fs_no_LBA_read |
mov eax,[esp+16] ; LBA block to read |
lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH |
mov ecx,[esp+8] ; abs pointer to return area |
call LBA_read |
jmp file_system_return |
fs_no_LBA_read: |
cmp byte [edi+1+11],0 ; directory read |
je fs_give_dir1 |
call reserve_hd1 |
fs_for_new_semantic: |
call choice_necessity_partition |
fs_yesharddisk_all: |
mov eax,1 |
cmp dword [esp+20], 16 |
jnz @f |
neg eax |
@@: mov ebx, [esp+24+24] |
cmp [hdpos],0 ; is hd base set? |
jz hd_err_return |
cmp [fat32part],0 ; is partition set? |
jnz @f |
hd_err_return: |
and [hd1_status], 0 |
jmp file_system_return |
@@: |
cmp dword [esp+20],0 ; READ |
jne fs_noharddisk_read |
mov eax,[esp+0] ; /fname |
lea edi,[eax+12] |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov ebx,[esp+12] ; count to read |
mov ecx,[esp+8] ; buffer |
mov edx,[esp+4] |
add edx,12*2 ; dir start |
sub edi,edx ; path length |
mov esi,[esp+16] ; blocks to read |
call file_read |
mov edi,[esp+0] |
mov byte [edi],'/' |
jmp file_system_return |
fs_noharddisk_read: |
cmp dword [esp+20],1 ; WRITE |
jne fs_noharddisk_write |
mov eax,[esp+0] ; /fname |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov ebx,[esp+12] ; count to write |
mov ecx,[esp+8] ; buffer |
mov edx,[esp+4] |
add edx,12*2 ; path start |
call file_write |
mov edi,[esp+0] |
mov byte [edi],'/' |
; eax=0 ok - eax=1 not enough free space |
jmp file_system_return |
fs_noharddisk_write: |
cmp dword [esp+20],2 ; DELETE |
jne fs_noharddisk_delete |
mov eax,[esp+0] ; /dirname or /filename |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov edx,[esp+4] |
add edx,12*2 ; path start |
call removedir |
mov edi,[esp+0] |
mov byte [edi],'/' |
jmp file_system_return |
fs_noharddisk_delete: |
cmp dword [esp+20],3 ; APPEND |
jne fs_noharddisk_append |
mov eax,[esp+0] ; /dirname or /filename |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov edx,[esp+4] |
add edx,12*2 ; path start |
mov ecx,[esp+8] ; buffer |
mov ebx,[esp+12] ; count to write |
mov esi,[esp+16] ; bytes to skip over |
call file_append |
mov edi,[esp+0] |
mov byte [edi],'/' |
jmp file_system_return |
fs_noharddisk_append: |
cmp dword [esp+20],4 ; MAKEDIR |
jne fs_noharddisk_makedir |
mov eax,[esp+0] ; /dirname |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov edx,[esp+4] |
add edx,12*2 ; path start |
call makedir |
mov edi,[esp+0] |
mov byte [edi],'/' |
jmp file_system_return |
fs_noharddisk_makedir: |
cmp dword [esp+20],5 ; RENAME |
jne fs_noharddisk_rename |
mov edi,[esp+0] ; start of source file name |
add edi,12+1 ; continue after name |
call expand_pathz ; convert destination name |
mov eax,[edi+1] |
cmp eax,'HD ' |
je fs_rename_test1 |
cmp eax,'HARD' |
jne fs_rename_error |
fs_rename_test1: |
mov eax,[edi+1+12] |
cmp eax,'1 ' |
je fs_rename_start |
cmp eax,'FIRS' |
jne fs_rename_error |
fs_rename_start: |
mov byte [ebx],0 ; path to asciiz |
inc ebx ; filename start |
add edi,12*2 ; path start |
cmp byte [ebx],0 |
je fs_rename_error |
cmp byte [ebx],32 |
je fs_rename_error |
mov eax,[esp+0] ; /filename |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov edx,[esp+4] |
add edx,12*2 ; path start |
call rename |
mov edi,[esp+0] |
mov byte [edi],'/' |
jmp file_system_return |
fs_rename_error: |
mov eax,4 ; partition not defined at hd |
jmp file_system_return |
fs_noharddisk_rename: |
cmp dword [esp+20],16 ; START APPLICATION |
jne fs_noharddisk_start_application |
mov eax,[esp+4] ; fname |
add eax,12*2 |
mov ebx,[esp+0] ; length |
sub ebx,eax |
add ebx,12 |
mov ecx,[esp+4] ; work area |
add ecx,512 |
xor ebp,ebp ; parameters to pass |
cmp dword [esp+12],ebp;0 |
je no_hd_start_param |
mov ebp, [esp+12] |
add ebp, std_application_base_address |
no_hd_start_param: |
mov edx,[esp+16] ; flags |
call start_application_hd |
jmp file_system_startapp_return |
fs_noharddisk_start_application: |
fs_noharddisk: |
; \begin{diamond}[18.03.2006] |
mov eax, 5 ; file not found |
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè? |
cmp dword [esp+20], 16 |
jnz @f |
neg eax |
@@: mov ebx, [esp+24+24] ; do not change ebx in application |
; \end{diamond}[18.03.2006] |
file_system_return: |
add esp,24 |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
fs_give_dir1: |
; \begin{diamond}[18.03.2006] |
; /RD,/FD,/HD - only read is allowed |
; other operations return "access denied", eax=10 |
; (execute operation returns eax=-10) |
cmp dword [esp+20], 0 |
jz .read |
add esp, 20 |
pop ecx |
mov eax, 10 |
cmp ecx, 16 |
jnz @f |
neg eax |
@@: mov [esp+36], eax |
ret |
.read: |
; \end{diamond}[18.03.2006] |
mov al,0x10 |
mov ebx,1 |
mov edi,[esp+8] |
mov esi,dir1 |
fs_d1_new: |
mov ecx,11 |
; cld |
rep movsb |
stosb |
add edi,32-11-1 |
dec ebx |
jne fs_d1_new |
add esp,24 |
and dword [esp+36],0 ; ok read |
mov dword [esp+24],32*1 ; dir/data size |
ret |
LBA_read_ramdisk: |
cmp [lba_read_enabled],1 |
je lbarrl1 |
xor ebx,ebx |
mov eax,2 |
ret |
lbarrl1: |
cmp eax,18*2*80 |
jb lbarrl2 |
xor ebx,ebx |
mov eax,3 |
ret |
lbarrl2: |
pushad |
call restorefatchain |
mov edi,ecx |
mov esi,eax |
shl esi,9 |
add esi,0x100000 |
mov ecx,512/4 |
; cld |
rep movsd |
popad |
xor ebx,ebx |
xor eax,eax |
ret |
LBA_read: |
; IN: |
; |
; eax = LBA block to read |
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH |
; ecx = abs pointer to return area |
cmp [lba_read_enabled],1 |
je lbarl1 |
mov eax,2 |
ret |
lbarl1: |
call reserve_hd1 |
push eax |
push ecx |
mov edi,hd_address_table |
mov esi,dir1 |
mov eax,[ebx] |
mov edx,'1 ' |
mov ecx,4 |
blar0: |
cmp eax,[esi] |
je blar2 |
cmp eax,edx |
je blar2 |
inc edx |
add edi,8 |
add esi,11 |
dec ecx |
jnz blar0 |
mov eax,1 |
mov ebx,1 |
jmp LBA_read_ret |
blar2: |
mov eax,[edi+0] |
mov ebx,[edi+4] |
mov [hdbase],eax |
mov [hdid],ebx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_lba_error |
; eax = hd port |
; ebx = set for primary (0x00) or slave (0x10) |
cli |
mov edx,eax |
inc edx |
xor eax,eax |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esp+4] |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,bl |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,20h |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_lba_error |
cli |
mov edi,[esp+0] |
mov ecx,256 |
sub edx,7 |
cld |
rep insw |
sti |
xor eax,eax |
xor ebx,ebx |
LBA_read_ret: |
mov [hd_error],0 |
mov [hd1_status],0 |
add esp,2*4 |
ret |
expand_pathz: |
; IN: |
; esi = asciiz path & file |
; edi = buffer for path & file name |
; OUT: |
; edi = directory & file : / 11 + / 11 + / 11 - zero terminated |
; ebx = /file name - zero terminated |
; esi = pointer after source |
push eax |
push ecx |
push edi ;[esp+0] |
pathz_start: |
mov byte [edi],'/' |
inc edi |
mov al,32 |
mov ecx,11 |
cld |
rep stosb ; clear filename area |
sub edi,11 |
mov ebx,edi ; start of dir/file name |
pathz_new_char: |
mov al,[esi] |
inc esi |
cmp al,0 |
je pathz_end |
cmp al,'/' |
jne pathz_not_path |
cmp edi,ebx ; skip first '/' |
jz pathz_new_char |
lea edi,[ebx+11] ; start of next directory |
jmp pathz_start |
pathz_not_path: |
cmp al,'.' |
jne pathz_not_ext |
lea edi,[ebx+8] ; start of extension |
jmp pathz_new_char |
pathz_not_ext: |
cmp al,'a' |
jb pathz_not_low |
cmp al,'z' |
ja pathz_not_low |
sub al,0x20 ; char to uppercase |
pathz_not_low: |
mov [edi],al |
inc edi |
mov eax,[esp+0] ; start_of_dest_path |
add eax,512 ; keep maximum path under 512 bytes |
cmp edi,eax |
jb pathz_new_char |
pathz_end: |
cmp ebx,edi ; if path end with '/' |
jnz pathz_put_zero ; go back 1 level |
sub ebx,12 |
pathz_put_zero: |
mov byte [ebx+11],0 |
dec ebx ; include '/' char into file name |
pop edi |
pop ecx |
pop eax |
ret |
;******************************************* |
;* string to number |
;* input eax - 4 byte string |
;* output eax - number |
;******************************************* |
StringToNumber: |
; ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ |
; Âõîä: |
; EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh |
; Âûõîä: |
; CF - èíäèêàòîð îøèáîê: |
; 0 - îøèáîê íåò; |
; 1 - îøèáêà |
; Åñëè CF=0, òî AX - ÷èñëî. |
push bx |
push cx |
push dx |
push edi |
mov [partition_string],eax |
mov edi,partition_string |
xor cx,cx |
i1: |
mov al,[edi] |
cmp al,32 ;13 |
je i_exit |
; cmp al,'0' |
; jb err |
; cmp al,'9' |
; ja err |
sub al,48 |
shl cx,1 |
jc err |
mov bx,cx |
shl cx,1 |
jc err |
shl cx,1 |
jc err |
add cx,bx |
jc err |
cbw |
add cx,ax |
jc err |
i3: |
inc edi |
jmp i1 |
i_exit: |
mov ax,cx |
clc |
i4: |
movzx eax,ax |
pop edi |
pop dx |
pop cx |
pop bx |
ret |
err: |
stc |
jmp i4 |
partition_string: dd 0 |
db 32 |
/kernel/branches/gfx_kernel/fs/fs_lfn.inc |
---|
0,0 → 1,661 |
; System function 70 - files with long names (LFN) |
; diamond, 2006 |
iglobal |
; in this table names must be in lowercase |
rootdirs: |
db 2,'rd' |
dd fs_OnRamdisk |
dd fs_NextRamdisk |
db 7,'ramdisk' |
dd fs_OnRamdisk |
dd fs_NextRamdisk |
db 2,'fd' |
dd fs_OnFloppy |
dd fs_NextFloppy |
db 10,'floppydisk' |
dd fs_OnFloppy |
dd fs_NextFloppy |
db 3,'hd0' |
dd fs_OnHd0 |
dd fs_NextHd0 |
db 3,'hd1' |
dd fs_OnHd1 |
dd fs_NextHd1 |
db 3,'hd2' |
dd fs_OnHd2 |
dd fs_NextHd2 |
db 3,'hd3' |
dd fs_OnHd3 |
dd fs_NextHd3 |
;********************************************** |
db 3,'cd0' |
dd fs_OnCd0 |
dd fs_NextCd |
db 3,'cd1' |
dd fs_OnCd1 |
dd fs_NextCd |
db 3,'cd2' |
dd fs_OnCd2 |
dd fs_NextCd |
db 3,'cd3' |
dd fs_OnCd3 |
dd fs_NextCd |
;*********************************************** |
db 0 |
virtual_root_query: |
dd fs_HasRamdisk |
db 'rd',0 |
dd fs_HasFloppy |
db 'fd',0 |
dd fs_HasHd0 |
db 'hd0',0 |
dd fs_HasHd1 |
db 'hd1',0 |
dd fs_HasHd2 |
db 'hd2',0 |
dd fs_HasHd3 |
db 'hd3',0 |
;********************************************** |
dd fs_HasCd0 |
db 'cd0',0 |
dd fs_HasCd1 |
db 'cd1',0 |
dd fs_HasCd2 |
db 'cd2',0 |
dd fs_HasCd3 |
db 'cd3',0 |
;********************************************** |
dd 0 |
endg |
file_system_lfn: |
; in: eax->fileinfo block |
; operation codes: |
; 0 : read file |
; 1 : read folder |
; 2 : create/rewrite file |
; 3 : write/append to file - not implemented yet |
; 4 : set end of file - not implemented yet |
; 5 : get file/directory attributes structure |
; 6 : set file/directory attributes structure |
; 7 : start application |
; 8 : delete file - not implemented yet |
; 9 : create directory - not implemented yet |
; 10: rename file/directory - not implemented yet |
add eax, std_application_base_address |
; parse file name |
xchg ebx, eax |
lea esi, [ebx+20] |
mov ebp, esi ; for 'start app' function full path must be known |
lodsb |
test al, al |
jnz @f |
mov esi, [esi] |
add esi, std_application_base_address |
mov ebp, esi |
lodsb |
@@: |
cmp al, '/' |
jz @f |
.notfound: |
mov dword [esp+36], 5 ; file not found |
ret |
@@: |
cmp byte [esi], 0 |
jz .rootdir |
mov edi, rootdirs-8 |
xor ecx, ecx |
push esi |
.scan1: |
pop esi |
add edi, ecx |
scasd |
scasd |
mov cl, byte [edi] |
jecxz .notfound |
inc edi |
push esi |
@@: |
lodsb |
or al, 20h |
scasb |
loopz @b |
jnz .scan1 |
lodsb |
cmp al, '/' |
jz .found1 |
test al, al |
jnz .scan1 |
pop eax |
; directory /xxx |
.maindir: |
cmp dword [ebx], 1 |
jnz .access_denied |
xor eax, eax |
mov ebp, [ebx+12] |
mov edx, [ebx+16] |
add edx, std_application_base_address |
push dword [ebx+4] ; first block |
mov ebx, [ebx+8] ; flags |
mov esi, [edi+4] |
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler |
mov edi, edx |
mov ecx, 32/4 |
rep stosd |
mov byte [edx], 1 ; version |
.maindir_loop: |
call esi |
jc .maindir_done |
inc dword [edx+8] |
dec dword [esp] |
jns .maindir_loop |
dec ebp |
js .maindir_loop |
inc dword [edx+4] |
mov dword [edi], 0x10 ; attributes: folder |
mov dword [edi+4], 1 ; name type: UNICODE |
push eax |
xor eax, eax |
add edi, 8 |
mov ecx, 40/4-2 |
rep stosd |
pop eax |
push eax edx |
; convert number in eax to decimal UNICODE string |
push edi |
push -'0' |
mov cl, 10 |
@@: |
xor edx, edx |
div ecx |
push edx |
test eax, eax |
jnz @b |
@@: |
pop eax |
add al, '0' |
stosb |
test bl, 1 ; UNICODE name? |
jz .ansi2 |
mov byte [edi], 0 |
inc edi |
.ansi2: |
test al, al |
jnz @b |
mov byte [edi-1], 0 |
pop edi |
; UNICODE name length is 520 bytes, ANSI - 264 |
add edi, 520 |
test bl, 1 |
jnz @f |
sub edi, 520-264 |
@@: |
pop edx eax |
jmp .maindir_loop |
.maindir_done: |
pop eax |
mov ebx, [edx+4] |
xor eax, eax |
dec ebp |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [esp+36], eax |
mov [esp+24], ebx |
ret |
; directory / |
.rootdir: |
cmp dword [ebx], 1 ; read folder? |
jz .readroot |
.access_denied: |
mov dword [esp+36], 10 ; access denied |
ret |
.readroot: |
; virtual root folder - special handler |
mov esi, virtual_root_query |
mov ebp, [ebx+12] |
mov edx, [ebx+16] |
add edx, std_application_base_address |
push dword [ebx+4] ; first block |
mov ebx, [ebx+8] ; flags |
xor eax, eax |
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area |
mov edi, edx |
mov ecx, 32/4 |
rep stosd |
mov byte [edx], 1 ; version |
.readroot_loop: |
cmp dword [esi], eax |
jz .readroot_done |
call dword [esi] |
add esi, 4 |
test eax, eax |
jnz @f |
.readroot_next: |
or ecx, -1 |
xchg esi, edi |
repnz scasb |
xchg esi, edi |
jmp .readroot_loop |
@@: |
xor eax, eax |
inc dword [edx+8] |
dec dword [esp] |
jns .readroot_next |
dec ebp |
js .readroot_next |
inc dword [edx+4] |
mov dword [edi], 0x10 ; attributes: folder |
mov dword [edi+4], 1 ; name type: UNICODE |
add edi, 8 |
mov ecx, 40/4-2 |
rep stosd |
push edi |
@@: |
lodsb |
stosb |
test bl, 1 |
jz .ansi |
mov byte [edi], 0 |
inc edi |
.ansi: |
test eax, eax |
jnz @b |
pop edi |
add edi, 520 |
test bl, 1 |
jnz .readroot_loop |
sub edi, 520-264 |
jmp .readroot_loop |
.readroot_done: |
pop eax |
mov ebx, [edx+4] |
xor eax, eax |
dec ebp |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [esp+36], eax |
mov [esp+24], ebx |
ret |
.found1: |
pop eax |
cmp byte [esi], 0 |
jz .maindir |
; read partition number |
xor ecx, ecx |
xor eax, eax |
@@: |
lodsb |
cmp al, '/' |
jz .done1 |
test al, al |
jz .done1 |
sub al, '0' |
cmp al, 9 |
ja .notfound |
imul ecx, 10 |
add ecx, eax |
jmp @b |
.done1: |
test ecx, ecx |
jz .notfound |
test al, al |
jnz @f |
dec esi |
@@: |
; now [edi] contains handler address, ecx - partition number, |
; esi points to ASCIIZ string - rest of name |
jmp dword [edi] |
; handlers for devices |
; in: ecx = 0 => query virtual directory /xxx |
; in: ecx = partition number |
; esi -> relative (for device) name |
; ebx -> fileinfo |
; out: [esp+36]=image of eax, [esp+24]=image of ebx |
fs_OnRamdisk: |
cmp ecx, 1 |
jnz file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, fs_NumRamdiskServices |
jae .not_impl |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
add edx, std_application_base_address |
add ebx, 4 |
call dword [fs_RamdiskServices + eax*4] |
mov [esp+36], eax |
mov [esp+24], ebx |
ret |
.not_impl: |
mov dword [esp+36], 2 ; not implemented |
ret |
fs_NotImplemented: |
mov eax, 2 |
ret |
fs_RamdiskServices: |
dd fs_RamdiskRead |
dd fs_RamdiskReadFolder |
dd fs_RamdiskRewrite |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_RamdiskGetFileInfo |
dd fs_RamdiskSetFileInfo |
dd fs_RamdiskExecute |
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 |
fs_OnFloppy: |
cmp ecx, 2 |
ja file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, fs_NumFloppyServices |
jae fs_OnRamdisk.not_impl |
call reserve_flp |
mov [flp_number], cl |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
add edx, std_application_base_address |
add ebx, 4 |
call dword [fs_FloppyServices + eax*4] |
and [flp_status], 0 |
mov [esp+36], eax |
mov [esp+24], ebx |
ret |
fs_FloppyServices: |
dd fs_FloppyRead |
dd fs_FloppyReadFolder |
dd fs_FloppyRewrite |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_FloppyGetFileInfo |
dd fs_FloppySetFileInfo |
dd fs_FloppyExecute |
fs_NumFloppyServices = ($ - fs_FloppyServices)/4 |
fs_OnHd0: |
call reserve_hd1 |
mov [hdbase], 0x1F0 |
mov [hdid], 0 |
push 1 |
jmp fs_OnHd |
fs_OnHd1: |
call reserve_hd1 |
mov [hdbase], 0x1F0 |
mov [hdid], 0x10 |
push 2 |
jmp fs_OnHd |
fs_OnHd2: |
call reserve_hd1 |
mov [hdbase], 0x170 |
mov [hdid], 0 |
push 3 |
jmp fs_OnHd |
fs_OnHd3: |
call reserve_hd1 |
mov [hdbase], 0x170 |
mov [hdid], 0x10 |
push 4 |
fs_OnHd: |
call reserve_hd_channel |
pop eax |
mov [hdpos], eax |
cmp ecx, 0x100 |
jae .nf |
cmp cl, [0x40001+eax] |
jbe @f |
.nf: |
call free_hd_channel |
and [hd1_status], 0 |
mov dword [esp+36], 5 ; not found |
ret |
@@: |
mov [fat32part], ecx |
push ebx esi |
call choice_necessity_partition_1 |
pop esi ebx |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
add edx, std_application_base_address |
mov eax, [ebx] |
cmp eax, fs_NumHdServices |
jae .not_impl |
add ebx, 4 |
call dword [fs_HdServices + eax*4] |
call free_hd_channel |
and [hd1_status], 0 |
mov [esp+36], eax |
mov [esp+24], ebx |
ret |
.not_impl: |
call free_hd_channel |
and [hd1_status], 0 |
mov dword [esp+36], 2 ; not implemented |
ret |
fs_HdServices: |
dd fs_HdRead |
dd fs_HdReadFolder |
dd fs_HdRewrite |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_HdGetFileInfo |
dd fs_HdSetFileInfo |
dd fs_HdExecute |
fs_NumHdServices = ($ - fs_HdServices)/4 |
;******************************************************* |
fs_OnCd0: |
call reserve_cd |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
push 6 |
jmp fs_OnCd |
fs_OnCd1: |
call reserve_cd |
mov [ChannelNumber],1 |
mov [DiskNumber],1 |
push 4 |
jmp fs_OnCd |
fs_OnCd2: |
call reserve_cd |
mov [ChannelNumber],2 |
mov [DiskNumber],0 |
push 2 |
jmp fs_OnCd |
fs_OnCd3: |
call reserve_cd |
mov [ChannelNumber],2 |
mov [DiskNumber],1 |
push 0 |
fs_OnCd: |
call reserve_cd_channel |
pop eax |
mov [hdpos], eax |
cmp ecx, 0x100 |
jae .nf |
push cx bx |
mov cl,al |
mov bl,[0x40001] |
shr bl,cl |
test bl,2 |
pop bx cx |
jnz @f |
.nf: |
call free_cd_channel |
and [cd_status], 0 |
mov dword [esp+36], 5 ; not found |
ret |
@@: |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
add edx, std_application_base_address |
mov eax, [ebx] |
cmp eax,fs_NumCdServices |
jae .not_impl |
add ebx, 4 |
call dword [fs_CdServices + eax*4] |
call free_cd_channel |
and [cd_status], 0 |
mov [esp+36], eax |
mov [esp+24], ebx |
ret |
.not_impl: |
call free_cd_channel |
and [cd_status], 0 |
mov dword [esp+36], 2 ; not implemented |
ret |
fs_CdServices: |
dd fs_CdRead |
dd fs_CdReadFolder |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_CdGetFileInfo |
dd fs_NotImplemented |
dd fs_CdExecute |
fs_NumCdServices = ($ - fs_CdServices)/4 |
;******************************************************* |
fs_HasRamdisk: |
mov al, 1 ; we always have ramdisk |
ret |
fs_HasFloppy: |
cmp byte [0x40000], 0 |
setnz al |
ret |
fs_HasHd0: |
mov al, [0x40001] |
and al, 11000000b |
cmp al, 01000000b |
setz al |
ret |
fs_HasHd1: |
mov al, [0x40001] |
and al, 00110000b |
cmp al, 00010000b |
setz al |
ret |
fs_HasHd2: |
mov al, [0x40001] |
and al, 00001100b |
cmp al, 00000100b |
setz al |
ret |
fs_HasHd3: |
mov al, [0x40001] |
and al, 00000011b |
cmp al, 00000001b |
setz al |
ret |
;******************************************************* |
fs_HasCd0: |
mov al, [0x40001] |
and al, 11000000b |
cmp al, 10000000b |
setz al |
ret |
fs_HasCd1: |
mov al, [0x40001] |
and al, 00110000b |
cmp al, 00100000b |
setz al |
ret |
fs_HasCd2: |
mov al, [0x40001] |
and al, 00001100b |
cmp al, 00001000b |
setz al |
ret |
fs_HasCd3: |
mov al, [0x40001] |
and al, 00000011b |
cmp al, 00000010b |
setz al |
ret |
;******************************************************* |
; fs_NextXXX functions: |
; in: eax = partition number, from which start to scan |
; out: CF=1 => no more partitions |
; CF=0 => eax=next partition number |
fs_NextRamdisk: |
; we always have /rd/1 |
test eax, eax |
stc |
jnz @f |
mov al, 1 |
clc |
@@: |
ret |
fs_NextFloppy: |
; we have /fd/1 iff (([0x40000] and 0xF0) != 0) and /fd/2 iff (([0x40000] and 0x0F) != 0) |
test byte [0x40000], 0xF0 |
jz .no1 |
test eax, eax |
jnz .no1 |
inc eax |
ret ; CF cleared |
.no1: |
test byte [0x40000], 0x0F |
jz .no2 |
cmp al, 2 |
jae .no2 |
mov al, 2 |
clc |
ret |
.no2: |
stc |
ret |
; on hdx, we have partitions from 1 to [0x40002+x] |
fs_NextHd0: |
push 0 |
jmp fs_NextHd |
fs_NextHd1: |
push 1 |
jmp fs_NextHd |
fs_NextHd2: |
push 2 |
jmp fs_NextHd |
fs_NextHd3: |
push 3 |
fs_NextHd: |
pop ecx |
movzx ecx, byte [0x40002+ecx] |
cmp eax, ecx |
jae fs_NextFloppy.no2 |
inc eax |
clc |
ret |
;******************************************************* |
fs_NextCd: |
; we always have /cdX/1 |
test eax, eax |
stc |
jnz @f |
mov al, 1 |
clc |
@@: |
ret |
;******************************************************* |
/kernel/branches/gfx_kernel/fs/fs_phys.inc |
---|
0,0 → 1,111 |
hd_phys_read: |
;eax - sector number |
;ebx - destination |
pushad |
call wait_for_hd_idle |
popad |
push edx |
push eax |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
;write sector number. |
mov eax,[esp] |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] ;+0 or +16 |
or al,32+64+128 |
out dx,al |
inc edx |
mov al,0x20 |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jnz hd_read_error |
cli |
push edi |
mov edi,ebx |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep insw |
pop edi |
sti |
pop edx |
pop eax |
ret |
hd_phys_write: |
;eax - sector number |
;ebx - destination |
cmp eax,[partition_start] |
jb .ret |
cmp eax,[partition_end] |
ja .ret |
pushad |
call wait_for_hd_idle |
popad |
push edx |
push eax |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al |
inc edx |
inc eax |
out dx,al |
;write sector number |
inc edx |
mov eax,[esp] |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] ;+0 or +16 |
or al,32+64+128 |
out dx,al |
inc edx |
mov al,0x30 |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jnz hd_write_error |
cli |
push esi |
mov esi,ebx |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep outsw |
pop esi |
sti |
pop edx |
pop eax |
.ret: |
ret |
/kernel/branches/gfx_kernel/fs/iso9660.inc |
---|
0,0 → 1,826 |
uglobal |
cd_current_pointer_of_input dd 0 |
cd_current_pointer_of_input_2 dd 0 |
cd_mem_location dd 0 |
cd_counter_block dd 0 |
IDE_Channel_1 db 0 |
IDE_Channel_2 db 0 |
endg |
CDDataBuf equ 0x7000 |
reserve_cd: |
cli |
cmp [cd_status],0 |
je reserve_ok2 |
sti |
call change_task |
jmp reserve_cd |
reserve_ok2: |
push eax |
mov eax,[0x3000] |
shl eax,5 |
mov eax,[eax+0x3000+TASKDATA.pid] |
mov [cd_status],eax |
pop eax |
sti |
ret |
reserve_cd_channel: |
cmp [ChannelNumber],1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
cli |
cmp [IDE_Channel_1],0 |
je .reserve_ok_1 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.IDE_Channel_2: |
cli |
cmp [IDE_Channel_2],0 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.reserve_ok_1: |
mov [IDE_Channel_1],1 |
ret |
.reserve_ok_2: |
mov [IDE_Channel_2],1 |
ret |
free_cd_channel: |
cmp [ChannelNumber],1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1],0 |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2],0 |
ret |
cd_status dd 0 |
;---------------------------------------------------------------- |
; |
; fs_CdRead - LFN variant for reading CD disk |
; |
; esi points to filename /dir1/dir2/.../dirn/file,0 |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_CdRead: |
push edi |
cmp byte [esi], 0 |
jnz @f |
.noaccess: |
pop edi |
.noaccess_2: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.noaccess_3: |
pop eax edx ecx edi |
jmp .noaccess_2 |
@@: |
call cd_find_lfn |
jnc .found |
pop edi |
cmp [DevErrorCode],0 |
jne .noaccess_2 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
mov edi,[cd_current_pointer_of_input] |
test byte [edi+25],10b ; do not allow read directories |
jnz .noaccess |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; end of file |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 |
@@: |
mov eax,[edi+2] |
mov [CDSectorAddress],eax |
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data |
.new_sector: |
test ecx, ecx |
jz .done |
sub ebx, 2048 |
jae .new_sector |
add ebx, 2048 |
jnz .incomplete_sector |
cmp ecx, 2048 |
jb .incomplete_sector |
; we may read and memmove complete sector |
mov [CDDataBuf_pointer],edx |
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode],0 |
jne .noaccess_3 |
inc dword [CDSectorAddress] |
add edx, 2048 |
sub ecx, 2048 |
jmp .new_sector |
.incomplete_sector: |
; we must read and memmove incomplete sector |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode],0 |
jne .noaccess_3 |
inc dword [CDSectorAddress] |
mov eax,CDDataBuf |
add eax, ebx |
push ecx |
add ecx, ebx |
cmp ecx, 2048 |
jbe @f |
mov ecx, 2048 |
@@: |
sub ecx, ebx |
push edi esi ecx |
mov edi,edx |
mov esi,eax ;0x7000 ; CD data buffer |
cld |
rep movsb |
pop ecx esi edi |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
jmp .new_sector |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
;---------------------------------------------------------------- |
; |
; fs_CdReadFolder - LFN variant for reading CD disk folder |
; |
; esi points to filename /dir1/dir2/.../dirn/file,0 |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_CdReadFolder: |
push edi |
call cd_find_lfn |
jnc .found |
pop edi |
cmp [DevErrorCode],0 |
jne .noaccess_1 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
mov edi,[cd_current_pointer_of_input] |
test byte [edi+25],10b ; do not allow read directories |
jnz .found_dir |
pop edi |
.noaccess_1: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
mov eax,[edi+2] ; eax=cluster |
mov [CDSectorAddress],eax |
mov eax,[edi+10] ; ðàçìåð äèðåêòðîðèè |
.doit: |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov [cd_mem_location],edx |
add [cd_mem_location],32 |
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ |
;.mainloop: |
mov [cd_counter_block],dword 0 |
dec dword [CDSectorAddress] |
push ecx |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè |
cmp [DevErrorCode],0 |
jne .noaccess_1 |
call .get_names_from_buffer |
sub eax,2048 |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
cmp eax,0 |
ja .read_to_buffer |
mov edi,[cd_counter_block] |
mov [edx+8],edi |
mov edi,[ebx] |
sub [edx+4],edi |
pop ecx edi |
mov ebx, [edx+4] |
mov eax,ERROR_SUCCESS |
ret |
.get_names_from_buffer: |
mov [cd_current_pointer_of_input_2],CDDataBuf |
push eax esi edi edx |
.get_names_from_buffer_1: |
call cd_get_name |
jc .end_buffer |
inc dword [cd_counter_block] |
mov eax,[cd_counter_block] |
cmp [ebx],eax |
jae .get_names_from_buffer_1 |
test ecx, ecx |
jz .get_names_from_buffer_1 |
mov edi,[cd_counter_block] |
mov [edx+4],edi |
dec ecx |
mov esi,ebp |
mov edi,[cd_mem_location] |
add edi,40 |
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE |
jnz .unicode |
; jmp .unicode |
.ansi: |
cmp [cd_counter_block],2 |
jbe .ansi_parent_directory |
cld |
lodsw |
xchg ah,al |
call uni2ansi_char |
cld |
stosb |
; ïðîâåðêà êîíöà ôàéëà |
mov ax,[esi] |
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_1 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp esi,eax |
je .cd_get_parameters_of_file_1 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp esi,eax |
jb .ansi |
.cd_get_parameters_of_file_1: |
mov [edi],byte 0 |
call cd_get_parameters_of_file |
add [cd_mem_location],304 |
jmp .get_names_from_buffer_1 |
.ansi_parent_directory: |
cmp [cd_counter_block],2 |
je @f |
mov [edi],byte '.' |
inc edi |
jmp .cd_get_parameters_of_file_1 |
@@: |
mov [edi],word '..' |
add edi,2 |
jmp .cd_get_parameters_of_file_1 |
.unicode: |
cmp [cd_counter_block],2 |
jbe .unicode_parent_directory |
cld |
movsw |
; ïðîâåðêà êîíöà ôàéëà |
mov ax,[esi] |
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_2 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp esi,eax |
je .cd_get_parameters_of_file_2 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp esi,eax |
jb .unicode |
.cd_get_parameters_of_file_2: |
mov [edi],word 0 |
call cd_get_parameters_of_file |
add [cd_mem_location],560 |
jmp .get_names_from_buffer_1 |
.unicode_parent_directory: |
cmp [cd_counter_block],2 |
je @f |
mov [edi],word 2E00h ; '.' |
add edi,2 |
jmp .cd_get_parameters_of_file_2 |
@@: |
mov [edi],dword 2E002E00h ; '..' |
add edi,4 |
jmp .cd_get_parameters_of_file_2 |
.end_buffer: |
pop edx edi esi eax |
ret |
cd_get_parameters_of_file: |
mov edi,[cd_mem_location] |
cd_get_parameters_of_file_1: |
; ïîëó÷àåì àòðèáóòû ôàéëà |
xor eax,eax |
; ôàéë íå àðõèâèðîâàëñÿ |
inc al |
shl eax,1 |
; ýòî êàòàëîã? |
test [ebp-8],byte 2 |
jz .file |
inc al |
.file: |
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò |
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì |
shl eax,3 |
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå) |
test [ebp-8],byte 1 |
jz .hidden |
inc al |
.hidden: |
shl eax,1 |
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD |
inc al |
mov [edi],eax |
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà |
;÷àñ |
movzx eax,byte [ebp-12] |
shl eax,8 |
;ìèíóòà |
mov al,[ebp-11] |
shl eax,8 |
;ñåêóíäà |
mov al,[ebp-10] |
;âðåìÿ ñîçäàíèÿ ôàéëà |
mov [edi+8],eax |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+16],eax |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+24],eax |
; ïîëó÷àåì äàòó äëÿ ôàéëà |
;ãîä |
movzx eax,byte [ebp-15] |
add eax,1900 |
shl eax,8 |
;ìåñÿö |
mov al,[ebp-14] |
shl eax,8 |
;äåíü |
mov al,[ebp-13] |
;äàòà ñîçäàíèÿ ôàéëà |
mov [edi+12],eax |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+20],eax |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+28],eax |
; ïîëó÷àåì òèï äàííûõ èìåíè |
xor eax,eax |
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE |
jnz .unicode_1 |
mov [edi+4],eax |
jmp @f |
.unicode_1: |
inc eax |
mov [edi+4],eax |
@@: |
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ |
xor eax,eax |
mov [edi+32+4],eax |
mov eax,[ebp-23] |
mov [edi+32],eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_CdGetFileInfo - LFN variant for CD |
; get file/directory attributes structure |
; |
;---------------------------------------------------------------- |
fs_CdGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi ebp |
call cd_find_lfn |
pushfd |
cmp [DevErrorCode], 0 |
jz @f |
popfd |
pop ebp edi |
mov eax, 11 |
ret |
@@: |
popfd |
jnc @f |
pop ebp edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
mov edi, edx |
call cd_get_parameters_of_file_1 |
and dword [edi+4], 0 |
pop ebp |
pop ebp edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_CdExecute - LFN variant for executing from CD |
; |
; esi points to hd filename (e.g. 'dir1/name') |
; ebp points to full filename (e.g. '/hd0/1/dir1/name') |
; dword [ebx] = flags |
; dword [ebx+4] = cmdline |
; |
; ret ebx,edx destroyed |
; eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
fs_CdExecute: |
mov edx, [ebx] |
mov ebx, [ebx+4] |
test ebx, ebx |
jz @f |
add ebx, std_application_base_address |
@@: |
;---------------------------------------------------------------- |
; |
; fs_CdExecute.flags - second entry |
; |
; esi points to floppy filename (kernel address) |
; ebp points to full filename |
; edx flags |
; ebx cmdline (kernel address) |
; |
; ret eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
.flags: |
cmp byte [esi], 0 |
jnz @f |
; cannot execute root! |
mov eax, -ERROR_ACCESS_DENIED |
ret |
@@: |
push edi |
call cd_find_lfn |
jnc .found |
pop edi |
mov eax, -ERROR_FILE_NOT_FOUND |
cmp [DevErrorCode], 0 |
jz @f |
mov al, -11 |
@@: |
ret |
.found: |
mov edi,[cd_current_pointer_of_input] |
mov eax,[edi+2] |
push 0 |
push eax |
push dword [edi+10] ; size |
push .DoRead |
call fs_execute |
add esp, 16 |
pop edi |
ret |
.DoRead: |
; read next block |
; in: eax->parameters, edi->buffer |
; out: eax = error code |
pushad |
cmp dword [eax], 0 ; file size |
jz .eof |
cmp [eax+8],dword 0 |
jne @f |
mov ecx,[eax+4] |
inc dword [eax+4] |
mov [CDSectorAddress],ecx |
mov [CDDataBuf_pointer],CDDataBuf ;edi |
call ReadCDWRetr |
cmp [DevErrorCode], 0 |
jnz .err |
@@: |
push esi edi ecx |
mov esi,512 |
imul esi,[eax+8] |
add esi,CDDataBuf |
mov ecx,512/4 |
cld |
rep movsd |
pop ecx edi esi |
mov eax, [esp+28] |
mov ecx, [eax] |
sub ecx, 512 |
jae @f |
lea edi, [edi+ecx+512] |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
@@: |
mov [eax], ecx |
mov edx, [eax+8] |
inc edx |
cmp edx, 4 ; 2048/512=4 |
jb @f |
xor edx, edx |
@@: |
mov [eax+8], edx |
popad |
xor eax, eax |
ret |
.eof: |
popad |
mov eax, 6 |
ret |
.err: |
popad |
mov eax, 11 |
ret |
cd_find_lfn: |
; in: esi->name |
; out: CF=1 - file not found |
; else CF=0 and [cd_current_pointer_of_input] direntry |
push eax esi |
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ |
mov [CDSectorAddress],dword 15 |
.start: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr |
cmp [DevErrorCode],0 |
jne .access_denied |
; ïðîâåðêà íà âøèâîñòü |
cmp [CDDataBuf+1],dword 'CD00' |
jne .access_denied |
cmp [CDDataBuf+5],byte '1' |
jne .access_denied |
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ? |
cmp [CDDataBuf],byte 0xff |
je .access_denied |
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà? |
cmp [CDDataBuf],byte 0x2 |
jne .start |
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà? |
cmp [CDDataBuf+6],byte 0x1 |
jne .start |
; ïàðàìåòðû root äèðåêòðîðèè |
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè |
mov [CDSectorAddress],eax |
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè |
cmp byte [esi], 0 |
jnz @f |
mov [cd_current_pointer_of_input],CDDataBuf+0x9c |
jmp .done |
@@: |
; íà÷èíàåì ïîèñê |
.mainloop: |
dec dword [CDSectorAddress] |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè |
cmp [DevErrorCode],0 |
jne .access_denied |
call cd_find_name_in_buffer |
jnc .found |
sub eax,2048 |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
cmp eax,0 |
ja .read_to_buffer |
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè |
.access_denied: |
pop esi eax |
stc |
ret |
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí |
.found: |
; êîíåö ïóòè ôàéëà |
cmp byte [esi-1], 0 |
jz .done |
mov eax,[cd_current_pointer_of_input] |
add eax,2 |
mov eax,[eax] |
mov [CDSectorAddress],eax ; íà÷àëî äèðåêòîðèè |
add eax,8 |
mov eax,[eax] ; ðàçìåð äèðåêòîðèè |
jmp .mainloop |
; óêàçàòåëü ôàéëà íàéäåí |
.done: |
pop esi eax |
clc |
ret |
cd_find_name_in_buffer: |
mov [cd_current_pointer_of_input_2],CDDataBuf |
.start: |
call cd_get_name |
jc .not_found |
call cd_compare_name |
jc .start |
.found: |
clc |
ret |
.not_found: |
stc |
ret |
cd_get_name: |
push eax |
mov ebp,[cd_current_pointer_of_input_2] |
mov [cd_current_pointer_of_input],ebp |
mov eax,[ebp] |
cmp eax,0 ; âõîäû çàêîí÷èëèñü? |
je .next_sector |
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ? |
jae .next_sector |
movzx eax, byte [ebp] |
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà |
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè |
pop eax |
clc |
ret |
.next_sector: |
pop eax |
stc |
ret |
cd_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
push esi eax edi |
mov edi,ebp |
.loop: |
cld |
lodsb |
push ax |
call char_todown |
call ansi2uni_char |
xchg ah,al |
cld |
scasw |
pop ax |
je .coincides |
call char_toupper |
call ansi2uni_char |
xchg ah,al |
cld |
sub edi,2 |
scasw |
jne .name_not_coincide |
.coincides: |
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
jmp .loop |
.name_not_coincide: |
pop edi eax esi |
stc |
ret |
.done: |
; ïðîâåðêà êîíöà ôàéëà |
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .done_1 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp edi,eax |
je .done_1 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp edi,eax |
jne .name_not_coincide |
.done_1: |
pop edi eax |
add esp,4 |
inc esi |
clc |
ret |
char_todown: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'A' |
jb .ret |
cmp al, 'Z' |
jbe .az |
cmp al, '' |
jb .ret |
cmp al, '' |
jb .rus1 |
cmp al, '' |
ja .ret |
; 0x90-0x9F -> 0xE0-0xEF |
add al, 'à'-'' |
.ret: |
ret |
.rus1: |
; 0x80-0x8F -> 0xA0-0xAF |
.az: |
add al, 0x20 |
ret |
uni2ansi_char: |
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding |
; in: ax=UNICODE character |
; out: al=converted ANSI character |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
ret |
/kernel/branches/gfx_kernel/fs/part_set.inc |
---|
0,0 → 1,351 |
;************************************************************* |
;* 29.04.2006 Elimination of hangup after the * |
;* expiration hd_wait_timeout - Mario79 * |
;* 28.01.2006 find all Fat16/32 partition in all input point * |
;* to MBR - Mario79 * |
;************************************************************* |
align 4 |
;****************************************************** |
; Please do not change this place - variables in text |
; Mario79 |
; START place |
;****************************************************** |
PARTITION_START dd 0x3f |
PARTITION_END dd 0 |
SECTORS_PER_FAT dd 0x1f3a |
NUMBER_OF_FATS dd 0x2 |
SECTORS_PER_CLUSTER dd 0x8 |
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
ROOT_CLUSTER dd 2 ; first rootdir cluster |
FAT_START dd 0 ; start of fat table |
ROOT_START dd 0 ; start of rootdir (only fat16) |
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
DATA_START dd 0 ; start of data area (=first cluster 2) |
LAST_CLUSTER dd 0 ; last availabe cluster |
ADR_FSINFO dd 0 ; used only by fat32 |
fatRESERVED dd 0x0FFFFFF6 |
fatBAD dd 0x0FFFFFF7 |
fatEND dd 0x0FFFFFF8 |
fatMASK dd 0x0FFFFFFF |
fat_type db 0 ; 0=none, 16=fat16, 32=fat32 |
;*************************************************************************** |
; End place |
; Mario79 |
;*************************************************************************** |
iglobal |
partition_types: ; list of fat16/32 partitions |
db 0x04 ; DOS: fat16 <32M |
db 0x06 ; DOS: fat16 >32M |
db 0x0b ; WIN95: fat32 |
db 0x0c ; WIN95: fat32, LBA-mapped |
db 0x0e ; WIN95: fat16, LBA-mapped |
db 0x14 ; Hidden DOS: fat16 <32M |
db 0x16 ; Hidden DOS: fat16 >32M |
db 0x1b ; Hidden WIN95: fat32 |
db 0x1c ; Hidden WIN95: fat32, LBA-mapped |
db 0x1e ; Hidden WIN95: fat16, LBA-mapped |
db 0xc4 ; DRDOS/secured: fat16 <32M |
db 0xc6 ; DRDOS/secured: fat16 >32M |
db 0xcb ; DRDOS/secured: fat32 |
db 0xcc ; DRDOS/secured: fat32, LBA-mapped |
db 0xce ; DRDOS/secured: fat16, LBA-mapped |
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M |
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M |
partition_types_end: |
extended_types: ; list of extended partitions |
db 0x05 ; DOS: extended partition |
db 0x0f ; WIN95: extended partition, LBA-mapped |
db 0xc5 ; DRDOS/secured: extended partition |
db 0xd5 ; Old Multiuser DOS secured: extended partition |
extended_types_end: |
endg |
; Partition chain used: |
; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4 |
;========================================================== |
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +-- |
; extended --+ extended --+ extended --+ extended --+ |
; 0 0 0 0 |
; 0 0 0 0 |
; Notes: |
; - extended partition need to be in second entry on table |
; - it will skip over removed partitions |
set_FAT32_variables: |
mov [0xfe10],dword 0 ; entries in hd cache |
mov [problem_partition],0 |
call reserve_hd1 |
call clear_hd_cache |
cmp dword [hdpos],0 |
je problem_hd |
pushad |
xor ecx,ecx ; partition count |
mov edx,-1 ; flag for partition |
xor eax,eax ; read MBR |
xor ebp,ebp ; extended partition start |
new_partition: |
test ebp,ebp ; is there extended partition? |
jnz extended_already_set ; yes |
xchg ebp,eax ; no. set it now |
extended_already_set: |
add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne problem_hd |
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? |
jnz end_partition_chain |
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition |
jz next_partition |
push eax |
mov al,[ebx+0x1be+4] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition ; no |
mov edx,eax ; start sector |
add edx,[ebx+0x1be+8] ; add relative start |
next_primary_partition: |
push eax |
mov al,[ebx+0x1be+4+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition_1 ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition_1 ; no |
mov edx,eax ; start sector |
add edx,[ebx+0x1be+8+16] ; add relative start |
next_primary_partition_1: |
push eax |
mov al,[ebx+0x1be+4+16+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition_2 ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition_2 ; no |
mov edx,eax ; start sector |
add edx,[ebx+0x1be+8+16+16] ; add relative start |
next_primary_partition_2: |
push eax |
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_partition ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_partition ; no |
mov edx,eax ; start sector |
add edx,[ebx+0x1be+8+16+16+16] ; add relative start |
next_partition: |
push eax |
mov al,[ebx+0x1be+4] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_1 |
mov eax,[ebx+0x1be+8] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
next_partition_1: |
push eax |
mov al,[ebx+0x1be+4+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_2 |
mov eax,[ebx+0x1be+8+16] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
next_partition_2: |
push eax |
mov al,[ebx+0x1be+4+16+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_3 |
mov eax,[ebx+0x1be+8+16+16] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
next_partition_3: |
push eax |
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz end_partition_chain ; no. end chain |
mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
end_partition_chain: |
mov [partition_count],ecx |
cmp edx,-1 ; found wanted partition? |
jnz hd_and_partition_ok ; yes. install it |
jmp problem_partition_or_fat |
scan_partition_types: |
push ecx |
mov edi,partition_types |
mov ecx,partition_types_end-partition_types |
cld |
repne scasb ; is partition type ok? |
pop ecx |
ret |
scan_extended_types: |
push ecx |
mov edi,extended_types |
mov ecx,extended_types_end-extended_types |
cld |
repne scasb ; is it extended partition? |
pop ecx |
ret |
problem_fat_dec_count: ; bootsector is missing or another problem |
dec [partition_count] ; remove it from partition_count |
problem_partition_or_fat: |
popad |
problem_hd: |
mov [fat_type],0 |
mov [hd1_status],0 ; free |
mov [problem_partition],1 |
ret |
hd_and_partition_ok: |
mov eax,edx |
mov [PARTITION_START],eax |
mov [hd_setup],1 |
mov ebx,buffer |
call hd_read ; read boot sector of partition |
cmp [hd_error],0 |
jne problem_fat_dec_count |
mov [hd_setup],0 |
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? |
jnz problem_fat_dec_count |
movzx eax,word [ebx+0xe] ; sectors reserved |
add eax,[PARTITION_START] |
mov [FAT_START],eax ; fat_start = partition_start + reserved |
movzx eax,byte [ebx+0xd] ; sectors per cluster |
mov [SECTORS_PER_CLUSTER],eax |
movzx ecx,word [ebx+0xb] ; bytes per sector |
mov [BYTES_PER_SECTOR],ecx |
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32) |
mov edx,32 |
mul edx |
dec ecx |
add eax,ecx ; round up if not equal count |
inc ecx ; bytes per sector |
div ecx |
mov [ROOT_SECTORS],eax ; count of rootdir sectors |
movzx eax,word [ebx+0x16] ; sectors per fat <65536 |
test eax,eax |
jnz fat16_fatsize |
mov eax,[ebx+0x24] ; sectors per fat |
fat16_fatsize: |
mov [SECTORS_PER_FAT],eax |
movzx eax,byte [ebx+0x10] ; number of fats |
test eax,eax ; if 0 it's not fat partition |
jz problem_fat_dec_count |
mov [NUMBER_OF_FATS],eax |
imul eax,[SECTORS_PER_FAT] |
add eax,[FAT_START] |
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count |
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32 |
mov [DATA_START],eax ; data area = rootdir + rootdir_size |
movzx eax,word [ebx+0x13] ; total sector count <65536 |
test eax,eax |
jnz fat16_total |
mov eax,[ebx+0x20] ; total sector count |
fat16_total: |
add eax,[PARTITION_START] |
dec eax |
mov [PARTITION_END],eax |
inc eax |
sub eax,[DATA_START] ; eax = count of data sectors |
xor edx,edx |
div dword [SECTORS_PER_CLUSTER] |
inc eax |
mov [LAST_CLUSTER],eax |
dec eax ; cluster count |
; limits by Microsoft Hardware White Paper v1.03 |
cmp eax,4085 ; 0xff5 |
jb problem_fat_dec_count ; fat12 not supported |
cmp eax,65525 ; 0xfff5 |
jb fat16_partition |
fat32_partition: |
mov eax,[ebx+0x2c] ; rootdir cluster |
mov [ROOT_CLUSTER],eax |
movzx eax,word [ebx+0x30] ; fs info sector |
add eax,[PARTITION_START] |
mov [ADR_FSINFO],eax |
popad |
mov [fatRESERVED],0x0FFFFFF6 |
mov [fatBAD],0x0FFFFFF7 |
mov [fatEND],0x0FFFFFF8 |
mov [fatMASK],0x0FFFFFFF |
mov [fat_type],32 ; Fat32 |
mov [hd1_status],0 ; free |
ret |
fat16_partition: |
xor eax,eax |
mov [ROOT_CLUSTER],eax |
popad |
mov [fatRESERVED],0x0000FFF6 |
mov [fatBAD],0x0000FFF7 |
mov [fatEND],0x0000FFF8 |
mov [fatMASK],0x0000FFFF |
mov [fat_type],16 ; Fat16 |
mov [hd1_status],0 ; free |
ret |
/kernel/branches/gfx_kernel/gui/button.inc |
---|
0,0 → 1,649 |
max_buttons=4095 |
dececx: |
push edx |
push ecx |
mov edx,2 |
.loop: |
cmp byte [esp+edx],0x20 |
jae @f |
mov [esp+edx],byte 0x20 |
@@: |
sub [esp+edx],byte 0x20 |
dec edx |
jns .loop |
pop ecx |
pop edx |
ret |
incecx: |
push edx |
push ecx |
mov edx,2 |
.loop: |
cmp byte [esp+edx],0xdf |
jbe @f |
mov [esp+edx],byte 0xdf |
@@: |
add [esp+edx],byte 0x20 |
dec edx |
jns .loop |
pop ecx |
pop edx |
ret |
incecx2: |
push edx |
push ecx |
mov edx,2 |
.loop: |
cmp byte [esp+edx],0xeb |
jbe @f |
mov [esp+edx],byte 0xeb |
@@: |
add [esp+edx],byte 0x14 |
dec edx |
jns .loop |
pop ecx |
pop edx |
ret |
drawbuttonframes: |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
shr eax,16 |
shr ebx,16 |
mov edx,[0x3010] |
add eax,[edx-twdw + WDATA.box.left] |
add ebx,[edx-twdw + WDATA.box.top] |
mov cx,ax |
mov dx,bx |
shl eax,16 |
shl ebx,16 |
mov ax,cx |
mov bx,dx |
add ax,word [esp+12] |
mov esi,ebx |
mov edi,0 |
mov ecx,[esp+0] |
call incecx |
call [draw_line] |
movzx edx,word [esp+8] |
add ebx,edx |
shl edx,16 |
add ebx,edx |
mov ecx,[esp+0] |
call dececx |
call [draw_line] |
mov ebx,esi |
push edx |
mov edx,eax |
shr edx,16 |
mov ax,dx |
mov edx,ebx |
shr edx,16 |
mov bx,dx |
mov dx,[esp+8+4] |
add bx,dx |
pop edx |
mov edi,0 |
mov ecx,[esp+0] |
call incecx |
call [draw_line] |
mov esi,edx |
mov dx,[esp+12] |
add ax,dx |
shl edx,16 |
add eax,edx |
add ebx,1*65536 |
mov edx,esi |
mov ecx,[esp+0] |
call dececx |
call [draw_line] |
pop edx |
pop ecx |
pop ebx |
pop eax |
pop edi |
pop esi |
ret |
button_dececx: |
cmp [buttontype],dword 1 |
jne .finish |
; je bdece |
; ret |
; bdece: |
push eax |
mov eax,0x01 |
cmp edi,20 |
jg @f |
mov eax,0x02 |
@@: |
test ecx,0xff |
jz @f |
sub ecx,eax |
@@: |
shl eax,8 |
test ecx,0xff00 |
jz @f |
sub ecx,eax |
@@: |
shl eax,8 |
test ecx,0xff0000 |
jz @f |
sub ecx,eax |
@@: |
pop eax |
.finish: |
ret |
sys_button: |
push edi |
mov edi,[0x3000] |
shl edi,8 |
rol eax,16 |
add ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] |
rol eax,16 |
rol ebx,16 |
add bx,word[edi+0x80000+APPDATA.wnd_clientbox.top] |
rol ebx,16 |
pop edi |
.forced: |
test ecx,0x80000000 |
jnz remove_button |
push esi |
push edi |
push eax ; <x,xs> |
push ebx ; <y,ys> |
push ecx ; <id> |
push edx |
or ax,ax |
jle noaddbutt |
or bx,bx |
jle noaddbutt |
test ecx,0x40000000 |
jnz button_no_draw |
pushad ; button body |
push ebx |
sar eax,16 |
sar ebx,16 |
mov edx,[0x3010] |
mov esi,[edx-twdw + WDATA.box.left] |
mov edi,[edx-twdw + WDATA.box.top] |
add eax,esi |
add ebx,edi |
mov cx,ax |
mov dx,bx |
shl eax,16 |
shl ebx,16 |
mov ax,cx |
mov bx,dx |
add ax,[4+32+esp+12] |
mov ecx,[4+32+esp+0] |
cmp [buttontype],dword 0 |
je @f |
call incecx2 |
@@: |
movzx edi,word [esp] |
pop edx |
and edx, 0xFFFF |
.newline: |
call button_dececx |
push edi |
xor edi, edi |
call [draw_line] |
pop edi |
inc bx |
rol ebx,16 |
inc bx |
dec edx |
jnz .newline |
popad |
call drawbuttonframes |
button_no_draw: |
and ecx,0xffff |
mov edi,[0xfe88] |
movzx eax,word [edi] |
cmp eax,max_buttons |
jge noaddbutt |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[0x3000] |
mov [eax],bx |
add eax,2 ; save button id number |
mov ebx,[esp+4] |
mov [eax],bx ; bits 0-15 |
shr ebx,16 |
mov [eax-2+0xc],bx; bits 16-31 |
add eax,2 ; x start |
mov bx,[esp+12+2] |
mov [eax],bx |
add eax,2 ; x size |
mov bx,[esp+12+0] |
mov [eax],bx |
add eax,2 ; y start |
mov bx,[esp+8+2] |
mov [eax],bx |
add eax,2 ; y size |
mov bx,[esp+8+0] |
mov [eax],bx |
noaddbutt: |
pop edx |
pop ecx |
pop ebx |
pop eax |
pop edi |
pop esi |
ret |
remove_button: |
and ecx,0x7fffffff |
rnewba2: |
mov edi,[0xfe88] |
mov eax,edi |
movzx ebx,word [edi] |
inc bx |
rnewba: |
dec bx |
jz rnmba |
add eax,0x10 |
mov dx,[0x3000] |
cmp dx,[eax] |
jnz rnewba |
cmp cx,[eax+2] |
jnz rnewba |
pushad |
mov ecx,ebx |
inc ecx |
shl ecx,4 |
mov ebx,eax |
add eax,0x10 |
call memmove |
dec dword [edi] |
popad |
jmp rnewba2 |
rnmba: |
ret |
find_pressed_button_frames: |
pushad |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+ WDATA.box.left] ; window x start |
movsx edx,word [eax+4] ; button x start |
add ecx,edx |
push ecx |
movzx edx,word[eax+6] ; button x size |
add ecx,edx |
mov esi,ecx |
inc esi |
mov ecx, [ebx+WDATA.box.top] ; window y start |
movsx edx,word[eax+8] ; button y start |
add ecx,edx |
mov ebx,ecx |
movzx edx,word[eax+10] ; button y size |
add edx,ecx |
inc edx |
pop eax |
; eax x beginning |
; ebx y beginning |
; esi x end |
; edx y end |
; ecx color |
mov [pressed_button_eax],eax |
mov [pressed_button_ebx],ebx |
mov [pressed_button_ecx],ecx |
mov [pressed_button_edx],edx |
mov [pressed_button_esi],esi |
popad |
ret |
uglobal |
pressed_button_eax dd 0 |
pressed_button_ebx dd 0 |
pressed_button_ecx dd 0 |
pressed_button_edx dd 0 |
pressed_button_esi dd 0 |
endg |
; negative button image |
negativebutton: |
; If requested, do not display button |
; boarder on press. |
test ebx,0x20000000 |
jz draw_negative_button |
ret |
draw_negative_button: |
pushad |
mov eax,[pressed_button_eax] |
mov ebx,[pressed_button_ebx] |
mov ecx,[pressed_button_ecx] |
mov edx,[pressed_button_edx] |
mov esi,[pressed_button_esi] |
mov ecx,0x01000000 |
dec edx |
push edx |
inc edx |
dec esi |
push esi |
inc esi |
push eax |
push ebx |
push ecx |
push edx |
push edi |
call [disable_mouse] |
bdbnewline: |
mov edi,1 ; force |
cmp eax,[esp+16] |
jz bneg |
cmp eax,[esp+20] |
jz bneg |
cmp ebx,[esp+12] |
jz bneg |
cmp ebx,[esp+24] |
jnz nbneg |
; jz bneg |
; jmp nbneg |
bneg: |
;;;call [disable_mouse] |
call [putpixel] |
nbneg: |
inc eax |
cmp eax,esi |
jnz bdbnewline |
mov eax,[esp+16] |
inc ebx |
cmp ebx,edx |
jnz bdbnewline |
add esp,28 |
popad |
ret |
; check buttons |
; 0000 word process number |
; 0002 word button id number : bits 0-15 |
; 0004 word x start |
; 0006 word x size |
; 0008 word y start |
; 000A word y size |
; 000C word button id number : bits 16-31 |
; |
; button table in 0x10 increments |
; |
; first at 0x10 |
checkbuttons: |
cmp [0xfb40],byte 0 ; mouse buttons pressed |
jnz @f |
ret |
@@: |
pushad |
xor esi, esi |
mov edi, [0xfe88] |
movzx edx, word [edi] |
test edx, edx |
jne @f |
popad |
ret |
@@: |
push esi |
inc edx |
push edx |
buttonnewcheck: |
pop edx |
pop esi |
inc esi |
cmp edx,esi |
jge bch |
popad ; no button pressed |
ret |
bch: |
push esi |
push edx |
mov eax,esi |
shl eax,4 |
add eax,edi |
;......................start 1/2 : modified by vhanla ............................. |
mov [buttonid],eax |
;......................end 1/2 : modified by vhanla ............................. |
; check that button is at top of windowing stack |
movzx ebx,word [eax] |
movzx ecx,word [0xC000 + ebx * 2] |
cmp ecx,[0x3004] |
jne buttonnewcheck |
; check that button start is inside window x/y end |
movzx ebx,word [eax+0] |
shl ebx,5 |
test [ebx+window_data+WDATA.fl_wstate],WSTATE_MINIMIZED |
jnz buttonnewcheck |
; add ebx,window_data |
; mov ecx,[window_data+ebx+8] ; window end X |
movsx edx,word [eax+4] ; button start X |
cmp edx, [window_data+ebx+WDATA.box.width] ;ecx |
jge buttonnewcheck |
; mov ecx,[window_data+ebx+12] ; window end Y |
movsx edx, word [eax+8] ; button start Y |
cmp edx, [window_data+ebx+WDATA.box.height] ;ecx |
jge buttonnewcheck |
; check coordinates |
; mouse x >= button x ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.left] ; window x start |
movsx edx,word [eax+4] ; button x start |
add edx,ecx |
movzx ecx,word[0xfb0a] |
cmp ecx,edx |
jl buttonnewcheck |
movzx ebx,word [eax+6] ; button x size |
add edx,ebx |
cmp ecx,edx |
jg buttonnewcheck |
; mouse y >= button y ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.top] ; window y start |
movsx edx,word [eax+8] ; button y start |
add edx,ecx |
movzx ecx,word[0xfb0c] |
cmp ecx,edx |
jl buttonnewcheck |
movzx ebx,word [eax+10] ; button y size |
add edx,ebx |
cmp ecx,edx |
jg buttonnewcheck |
; mouse on button |
pop edx |
pop esi |
mov bx,[eax+0xc] ; button id : bits 16-31 |
shl ebx,16 |
mov bx,[eax+2] ; button id : bits 00-16 |
push ebx |
mov [0xfb44],byte 1 ; no mouse down checks |
call find_pressed_button_frames |
call negativebutton |
pushad |
cbwaitmouseup: |
call checkidle |
call [draw_pointer] |
pushad |
call stack_handler |
popad |
cmp [0xfb40],byte 0 ; mouse buttons pressed ? |
jnz cbwaitmouseup |
popad |
call negativebutton |
mov [0xfff4],byte 0 ; no mouse background |
mov [0xfff5],byte 0 ; draw mouse |
;..................................... start 2/2 : modified by vhanla ............................. |
; check coordinates |
jmp afterbuttonid |
buttonid dd 0x0 ;here a will backup the eax value |
afterbuttonid: |
pusha |
; mouse x >= button x ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.left] ; window x start |
movsx edx,word [eax+4] ; button x start |
add edx,ecx |
movzx ecx,word[0xfb0a] |
cmp edx,ecx |
jg no_on_button ;if we release the pointer out of the button area |
movzx ebx,word [eax+6] ; button x size |
add edx,ebx |
cmp ecx,edx |
jg no_on_button |
; mouse y >= button y ? |
movzx ebx,word [eax+0] |
shl ebx,5 |
add ebx,window_data |
mov ecx, [ebx+WDATA.box.top] ; window y start |
movsx edx,word [eax+8] ; button y start |
add edx,ecx |
movzx ecx,word[0xfb0c] |
cmp edx,ecx |
jg no_on_button |
movzx ebx,word [eax+10] ; button y size |
add edx,ebx |
cmp ecx,edx |
jg no_on_button |
popa |
mov [0xf500],byte 1 ; no of buttons in buffer |
pop ebx |
mov [0xf501],ebx ; lets put the button id in buffer |
push ebx |
pusha |
jmp yes_on_button |
no_on_button: |
mov [0xf500],byte 0 ; no of buttons in buffer |
yes_on_button: |
mov [0xfb44],byte 0 ; mouse down -> do not draw |
popa |
pop ebx |
popa |
ret |
;..................................... end 2/2 : modified by vhanla ................................ |
/kernel/branches/gfx_kernel/gui/event.inc |
---|
0,0 → 1,215 |
sys_getevent: |
call get_event_for_app |
mov [esp+36],eax |
ret |
align 4 |
sys_wait_event_timeout: |
mov ebx,[timer_ticks] |
add ebx,eax |
cmp ebx,[timer_ticks] |
jna .swfet2 |
.swfet1: |
call get_event_for_app |
test eax,eax |
jne .eventoccur_time |
call change_task |
cmp ebx,[timer_ticks] |
jg .swfet1 |
.swfet2: |
xor eax,eax |
.eventoccur_time: |
mov [esp+36],eax |
ret |
align 4 |
sys_waitforevent: |
call get_event_for_app |
test eax,eax |
jne eventoccur |
newwait: |
mov eax, [0x3010] |
mov [eax+TASKDATA.state], byte 5 |
call change_task |
mov eax, [event_sched] |
eventoccur: |
mov [esp+36],eax |
ret |
get_event_for_app: |
pushad |
mov edi,[0x3010] ; WINDOW REDRAW |
test [edi+TASKDATA.event_mask],dword 1 |
jz no_eventoccur1 |
;mov edi,[0x3010] |
cmp [edi-twdw+WDATA.fl_redraw],byte 0 |
je no_eventoccur1 |
popad |
mov eax,1 |
ret |
no_eventoccur1: |
;mov edi,[0x3010] ; KEY IN BUFFER |
test [edi+TASKDATA.event_mask],dword 2 |
jz no_eventoccur2 |
mov ecx, [0x3000] |
movzx edx,word [0xC000+ecx*2] |
mov eax, [0x3004] |
cmp eax,edx |
jne no_eventoccur2x |
cmp [0xf400],byte 0 |
je no_eventoccur2x |
eventoccur2: |
popad |
mov eax,2 |
ret |
no_eventoccur2x: |
mov eax, hotkey_buffer |
@@: |
cmp [eax], ecx |
jz eventoccur2 |
add eax, 8 |
cmp eax, hotkey_buffer+120*8 |
jb @b |
no_eventoccur2: |
;mov edi,[0x3010] ; BUTTON IN BUFFER |
test [edi+TASKDATA.event_mask],dword 4 |
jz no_eventoccur3 |
cmp [0xf500],byte 0 |
je no_eventoccur3 |
mov ecx, [0x3000] |
movzx edx, word [0xC000+ecx*2] |
mov eax, [0x3004] |
cmp eax,edx |
jnz no_eventoccur3 |
popad |
mov eax,[0xf501] |
cmp eax,65535 |
je no_event_1 |
mov eax,3 |
ret |
no_event_1: |
mov [window_minimize],1 |
mov [0xf500],byte 0 |
xor eax, eax |
ret |
no_eventoccur3: |
;mov edi,[0x3010] ; mouse event |
test [edi+TASKDATA.event_mask],dword 00100000b |
jz no_mouse_event |
mov eax,[0x3000] |
shl eax,8 |
test [eax+0x80000+APPDATA.event_mask],dword 00100000b |
jz no_mouse_event |
and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-00100000b |
popad |
mov eax,6 |
ret |
no_mouse_event: |
;mov edi,[0x3010] ; DESKTOP BACKGROUND REDRAW |
test [edi+TASKDATA.event_mask],dword 16 |
jz no_eventoccur5 |
cmp [0xfff0],byte 2 |
jnz no_eventoccur5 |
popad |
mov eax,5 |
ret |
no_eventoccur5: |
;mov edi,[0x3010] ; IPC |
test [edi+TASKDATA.event_mask],dword 01000000b |
jz no_ipc |
mov eax,[0x3000] |
shl eax,8 |
test [eax+0x80000+APPDATA.event_mask],dword 01000000b |
jz no_ipc |
and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-01000000b |
popad |
mov eax,7 |
ret |
no_ipc: |
;mov edi,[0x3010] ; STACK |
test [edi+TASKDATA.event_mask],dword 10000000b |
jz no_stack_event |
mov eax,[0x3000] |
shl eax,8 |
test [eax+0x80000+APPDATA.event_mask],dword 10000000b |
jz no_stack_event |
and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-10000000b |
popad |
mov eax,8 |
ret |
no_stack_event: |
test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG |
jz no_debug_event |
mov eax, [0x3000] |
shl eax, 8 |
test byte [eax+0x80000+APPDATA.event_mask+1], byte 1 |
jz no_debug_event |
and byte [eax+0x80000+APPDATA.event_mask+1], not 1 |
popad |
mov eax, 9 |
ret |
no_debug_event: |
cmp dword [edi+TASKDATA.event_mask], 0xFFFF |
jbe no_events |
mov esi,0x2e0000 ; IRQ'S AND DATA |
mov ebx,0x00010000 |
xor ecx, ecx |
irq_event_test: |
mov edi,[0x3010] |
test [edi+TASKDATA.event_mask],ebx |
jz no_irq_event |
mov edi,ecx |
shl edi,2 |
add edi,irq_owner |
mov edx,[edi] |
mov eax,[0x3010] |
mov eax,[eax+TASKDATA.pid] |
cmp edx,eax |
jne no_irq_event |
cmp [esi],dword 0 |
jz no_irq_event |
mov eax,ecx |
add eax,16 |
mov [esp+28],eax |
popad |
ret |
no_irq_event: |
add esi,0x1000 |
shl ebx,1 |
inc ecx |
cmp ecx,16 |
jb irq_event_test |
no_events: |
popad |
xor eax, eax |
ret |
/kernel/branches/gfx_kernel/gui/font.inc |
---|
0,0 → 1,119 |
align 4 |
dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org]) |
; eax x & y |
; ebx font ( 0xX0000000 ) & color ( 0x00RRGGBB ) |
; ecx start of text |
; edx length |
; edi 1 force |
pushad |
mov esi,edx ;esi=length |
mov ebp,ecx ;ebp=ptr to text |
mov ecx,ebx ;ecx=color |
movsx ebx,ax ;ebx=y |
sar eax,16 ;eax=x |
and esi, 0xFF ;limit of text = 255 symbols |
dtext.lnew: |
test esi, esi ; zero length ? |
jnz @f |
jmp dtext.output_end |
@@: |
movzx edx,byte [ebp] ;edx=ascii code |
test edx,edx |
jz dtext.output_end |
test ecx,0x10000000 |
jnz dtext.letnew2 |
align 4 |
.letnew: |
drawletter: ;output char of type 1(monotype) |
;eax - x |
;ebx - y |
;ecx - color |
;edx - ascii code |
pushad |
call [disable_mouse] |
mov esi,9 |
lea ebp,[0x3F600+8*edx+edx] |
.symloop: |
push esi |
mov dl,byte [ebp] |
mov esi,8 |
.pixloop: |
test dl,1 |
jz .nopix |
call [putpixel] |
.nopix: |
shr dl,1 |
inc eax |
dec esi |
jnz .pixloop |
sub eax,8 |
inc ebx |
inc ebp |
pop esi |
dec esi |
jnz .symloop |
popad |
add eax,6 |
inc ebp ;ptr to text |
dec esi ;length |
jnz dtext.lnew |
jmp dtext.output_end |
dtext.letnew2: |
align 4 |
drawletter2: ;output char of type 2(proportional) |
;eax - x |
;ebx - y |
;ecx - color |
;edx - symbol |
;edi - force? |
;result - eax=eax+sym_size |
pushad |
call [disable_mouse] |
shl edx,1 |
mov esi,9 |
lea ebp,[0x3EC00+4*edx+edx+1] |
.symloop: |
push esi |
mov dl,byte [ebp] |
xor esi,esi |
.pixloop: |
test dl,1 |
jz .nopix |
call [putpixel] |
.nopix: |
shr dl,1 |
inc esi |
inc eax |
cmp esi,8 |
jl .pixloop |
sub eax,8 |
inc ebx |
pop esi |
inc ebp |
dec esi |
jnz .symloop |
movzx edx,byte [ebp-10] |
add [esp+32-4],edx |
popad |
inc ebp ;ptr to text |
dec esi ;length |
jnz dtext.lnew |
dtext.output_end: |
popad |
ret |
/kernel/branches/gfx_kernel/gui/mouse.inc |
---|
0,0 → 1,11 |
uglobal |
mouseunder: |
times 32*32*3+1 db ? |
mousecomb = $ - mouseunder |
times 32*32*3+1 db ? |
endg |
uglobal |
mousepointer: |
times 4608 db 0 ; 32*32*4+62 = 4286 |
endg |
/kernel/branches/gfx_kernel/gui/skincode.inc |
---|
0,0 → 1,438 |
include "skindata.inc" |
skin_data = 0x00778000 |
load_skin_file: |
; eax = filename |
; edx = destination |
mov ebx,1 |
or ecx,-1 |
mov esi,12 |
call fileread |
ret |
struct SKIN_HEADER |
.ident dd ? |
.version dd ? |
.params dd ? |
.buttons dd ? |
.bitmaps dd ? |
ends |
struct SKIN_PARAMS |
.skin_height dd ? |
.margin.right dw ? |
.margin.left dw ? |
.margin.bottom dw ? |
.margin.top dw ? |
.colors.inner dd ? |
.colors.outer dd ? |
.colors.frame dd ? |
.colors_1.inner dd ? |
.colors_1.outer dd ? |
.colors_1.frame dd ? |
.dtp.size dd ? |
.dtp.data db 40 dup (?) |
ends |
struct SKIN_BUTTONS |
.type dd ? |
.pos: |
.left dw ? |
.top dw ? |
.size: |
.width dw ? |
.height dw ? |
ends |
struct SKIN_BITMAPS |
.kind dw ? |
.type dw ? |
.data dd ? |
ends |
load_skin: |
pushad |
mov [_skinh],22 |
mov eax,_skin_file |
mov edx,skin_data |
mov [edx+SKIN_HEADER.ident],'????' |
call load_skin_file |
cmp eax,ERROR_SUCCESS |
je @f |
cmp eax,ERROR_END_OF_FILE |
jne .exit |
@@: call parse_skin_data |
.exit: |
popad |
ret |
parse_skin_data: |
mov ebp,skin_data |
cmp [ebp+SKIN_HEADER.ident],'SKIN' |
jne .exit |
mov edi,skin_udata |
mov ecx,(skin_udata.end-skin_udata)/4 |
xor eax,eax |
cld |
rep stosd |
mov ebx,[ebp+SKIN_HEADER.params] |
add ebx,skin_data |
mov eax,[ebx+SKIN_PARAMS.skin_height] |
mov [_skinh],eax |
mov eax,[ebx+SKIN_PARAMS.colors.inner] |
mov [skin_active.colors.inner],eax |
mov eax,[ebx+SKIN_PARAMS.colors.outer] |
mov [skin_active.colors.outer],eax |
mov eax,[ebx+SKIN_PARAMS.colors.frame] |
mov [skin_active.colors.frame],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.inner] |
mov [skin_inactive.colors.inner],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.outer] |
mov [skin_inactive.colors.outer],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.frame] |
mov [skin_inactive.colors.frame],eax |
lea esi,[ebx+SKIN_PARAMS.dtp.data] |
mov edi,common_colours |
mov ecx,[ebx+SKIN_PARAMS.dtp.size] |
and ecx,127 |
rep movsb |
mov eax,dword[ebx+SKIN_PARAMS.margin.right] |
mov dword[_skinmargins+0],eax |
mov eax,dword[ebx+SKIN_PARAMS.margin.bottom] |
mov dword[_skinmargins+4],eax |
mov ebx,[ebp+SKIN_HEADER.bitmaps] |
add ebx,skin_data |
.lp1: cmp dword[ebx],0 |
je .end_bitmaps |
movzx eax,[ebx+SKIN_BITMAPS.kind] |
movzx ecx,[ebx+SKIN_BITMAPS.type] |
dec eax |
jnz .not_left |
xor eax,eax |
mov edx,skin_active.left.data |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.left.data |
@@: jmp .next_bitmap |
.not_left: |
dec eax |
jnz .not_oper |
mov esi,[ebx+SKIN_BITMAPS.data] |
add esi,skin_data |
mov eax,[esi+0] |
neg eax |
mov edx,skin_active.oper.data |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.oper.data |
@@: jmp .next_bitmap |
.not_oper: |
dec eax |
jnz .not_base |
mov eax,[skin_active.left.width] |
mov edx,skin_active.base.data |
or ecx,ecx |
jnz @f |
mov eax,[skin_inactive.left.width] |
mov edx,skin_inactive.base.data |
@@: jmp .next_bitmap |
.not_base: |
add ebx,8 |
jmp .lp1 |
.next_bitmap: |
mov ecx,[ebx+SKIN_BITMAPS.data] |
add ecx,skin_data |
mov [edx+4],eax |
mov eax,[ecx+0] |
mov [edx+8],eax |
add ecx,8 |
mov [edx+0],ecx |
add ebx,8 |
jmp .lp1 |
.end_bitmaps: |
mov ebx,[ebp+SKIN_HEADER.buttons] |
add ebx,skin_data |
.lp2: cmp dword[ebx],0 |
je .end_buttons |
mov eax,[ebx+SKIN_BUTTONS.type] |
dec eax |
jnz .not_close |
mov edx,skin_btn_close |
jmp .next_button |
.not_close: |
dec eax |
jnz .not_minimize |
mov edx,skin_btn_minimize |
jmp .next_button |
.not_minimize: |
add ebx,12 |
jmp .lp2 |
.next_button: |
movsx eax,[ebx+SKIN_BUTTONS.left] |
mov [edx+SKIN_BUTTON.left],eax |
movsx eax,[ebx+SKIN_BUTTONS.top] |
mov [edx+SKIN_BUTTON.top],eax |
movsx eax,[ebx+SKIN_BUTTONS.width] |
mov [edx+SKIN_BUTTON.width],eax |
movsx eax,[ebx+SKIN_BUTTONS.height] |
mov [edx+SKIN_BUTTON.height],eax |
add ebx,12 |
jmp .lp2 |
.end_buttons: |
.exit: |
ret |
sys_putimage_with_check: |
or ebx,ebx |
jz @f |
call [putimage] |
@@: ret |
drawwindow_IV_caption: |
mov ebp,skin_active |
or al,al |
jnz @f |
mov ebp,skin_inactive |
@@: |
mov esi,[esp+4] |
mov eax,[esi+WDATA.box.width] ; window width |
mov edx,[ebp+SKIN_DATA.left.left] |
shl edx,16 |
mov ecx,[ebp+SKIN_DATA.left.width] |
shl ecx,16 |
add ecx,[_skinh] |
mov ebx, [ebp+SKIN_DATA.left.data] |
call sys_putimage_with_check |
mov esi,[esp+4] |
mov eax,[esi+WDATA.box.width] |
sub eax,[ebp+SKIN_DATA.left.width] |
sub eax,[ebp+SKIN_DATA.oper.width] |
cmp eax,[ebp+SKIN_DATA.base.left] |
jng .non_base |
xor edx,edx |
mov ecx,[ebp+SKIN_DATA.base.width] |
jecxz .non_base |
div ecx |
inc eax |
mov ebx,[ebp+SKIN_DATA.base.data] |
mov ecx,[ebp+SKIN_DATA.base.width] |
shl ecx,16 |
add ecx,[_skinh] |
mov edx,[ebp+SKIN_DATA.base.left] |
sub edx,[ebp+SKIN_DATA.base.width] |
shl edx,16 |
.baseskinloop: |
shr edx,16 |
add edx,[ebp+SKIN_DATA.base.width] |
shl edx,16 |
push eax ebx ecx edx |
call sys_putimage_with_check |
pop edx ecx ebx eax |
dec eax |
jnz .baseskinloop |
.non_base: |
mov esi,[esp+4] |
mov edx,[esi+WDATA.box.width] |
sub edx,[ebp+SKIN_DATA.oper.width] |
inc edx |
shl edx,16 |
mov ebx,[ebp+SKIN_DATA.oper.data] |
mov ecx,[ebp+SKIN_DATA.oper.width] |
shl ecx,16 |
add ecx,[_skinh] |
call sys_putimage_with_check |
ret |
;//mike.dld, 2006-08-02 ] |
drawwindow_IV: |
;param1 - aw_yes |
pusha |
push edx |
mov edi,[esp] ; RECTANGLE |
mov ebp,skin_active |
cmp byte [esp+32+4+4],0 |
jne @f |
mov ebp,skin_inactive |
@@: |
mov eax,[edi+WDATA.box.left] |
shl eax,16 |
mov ax,word [edi+WDATA.box.left] |
add ax,word [edi+WDATA.box.width] |
mov ebx,[edi+WDATA.box.top] |
shl ebx,16 |
mov bx,word [edi+WDATA.box.top] |
add bx,word [edi+WDATA.box.height] |
; mov esi,[edi+24] |
; shr esi,1 |
; and esi,0x007f7f7f |
mov esi,[ebp+SKIN_DATA.colors.outer] |
call draw_rectangle |
mov ecx,3 |
_dw3l: |
add eax,1*65536-1 |
add ebx,1*65536-1 |
test ax,ax |
js no_skin_add_button |
test bx,bx |
js no_skin_add_button |
mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24] |
call draw_rectangle |
dec ecx |
jnz _dw3l |
mov esi,[ebp+SKIN_DATA.colors.inner] |
add eax,1*65536-1 |
add ebx,1*65536-1 |
test ax,ax |
js no_skin_add_button |
test bx,bx |
js no_skin_add_button |
call draw_rectangle |
cmp dword[skin_data],'SKIN' |
je @f |
xor eax,eax |
xor ebx,ebx |
mov esi,[esp] |
mov ecx,[esi+WDATA.box.width] |
inc ecx |
mov edx,[_skinh] |
mov edi,[common_colours+4] ; standard grab color |
call [drawbar] |
jmp draw_clientbar |
@@: |
mov al,[esp+32+4+4] |
call drawwindow_IV_caption |
draw_clientbar: |
mov esi,[esp] |
mov edx,[esi+WDATA.box.top] ; WORK AREA |
add edx,21+5 |
mov ebx,[esi+WDATA.box.top] |
add ebx,[esi+WDATA.box.height] |
cmp edx,ebx |
jg _noinside2 |
mov eax,5 |
mov ebx,[_skinh] |
mov ecx,[esi+WDATA.box.width] |
mov edx,[esi+WDATA.box.height] |
sub ecx,4 |
sub edx,4 |
mov edi,[esi+WDATA.cl_workarea] |
call [drawbar] |
_noinside2: |
cmp dword[skin_data],'SKIN' |
jne no_skin_add_button |
;* close button |
mov edi,[0xfe88] |
movzx eax,word [edi] |
cmp eax,1000 |
jge no_skin_add_button |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[0x3000] |
mov [eax],bx |
add eax,2 ; save button id number |
mov bx,1 |
mov [eax],bx |
add eax,2 ; x start |
xor ebx,ebx |
cmp [skin_btn_close.left],0 |
jge _bCx_at_right |
mov ebx,[esp] |
mov ebx,[ebx+WDATA.box.width] |
inc ebx |
_bCx_at_right: |
add ebx,[skin_btn_close.left] |
mov [eax],bx |
add eax,2 ; x size |
mov ebx,[skin_btn_close.width] |
dec ebx |
mov [eax],bx |
add eax,2 ; y start |
mov ebx,[skin_btn_close.top] |
mov [eax],bx |
add eax,2 ; y size |
mov ebx,[skin_btn_close.height] |
dec ebx |
mov [eax],bx |
;* minimize button |
mov edi,[0xfe88] |
movzx eax,word [edi] |
cmp eax,1000 |
jge no_skin_add_button |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[0x3000] |
mov [eax],bx |
add eax,2 ; save button id number |
mov bx,65535 ;999 |
mov [eax],bx |
add eax,2 ; x start |
xor ebx,ebx |
cmp [skin_btn_minimize.left],0 |
jge _bMx_at_right |
mov ebx,[esp] |
mov ebx,[ebx+WDATA.box.width] |
inc ebx |
_bMx_at_right: |
add ebx,[skin_btn_minimize.left] |
mov [eax],bx |
add eax,2 ; x size |
mov ebx,[skin_btn_minimize.width] |
dec ebx |
mov [eax],bx |
add eax,2 ; y start |
mov ebx,[skin_btn_minimize.top] |
mov [eax],bx |
add eax,2 ; y size |
mov ebx,[skin_btn_minimize.height] |
dec ebx |
mov [eax],bx |
no_skin_add_button: |
add esp,4 |
popa |
ret 4 |
/kernel/branches/gfx_kernel/gui/skindata.inc |
---|
0,0 → 1,56 |
; |
; WINDOW SKIN DATA |
; |
iglobal |
_skin_file_default db 'DEFAULT SKN',0 |
endg |
struct SKIN_DATA |
.colors.inner dd ? |
.colors.outer dd ? |
.colors.frame dd ? |
.left.data dd ? |
.left.left dd ? |
.left.width dd ? |
.oper.data dd ? |
.oper.left dd ? |
.oper.width dd ? |
.base.data dd ? |
.base.left dd ? |
.base.width dd ? |
ends |
struct SKIN_BUTTON |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
ends |
uglobal |
align 4 |
skin_udata: |
_skinh dd ? |
_skinmargins: ; rw 4 |
.right dw ? |
.left dw ? |
.bottom dw ? |
.top dw ? |
skin_btn_close SKIN_BUTTON |
skin_btn_minimize SKIN_BUTTON |
skin_active SKIN_DATA |
skin_inactive SKIN_DATA |
_skin_file rb 256 |
align 4 |
skin_udata.end: |
endg |
/kernel/branches/gfx_kernel/gui/window.inc |
---|
0,0 → 1,1494 |
label calc_clipping_rects dword at calculatescreen |
get_titlebar_height: ; edi = window draw_data pointer |
mov al,[edi+WDATA.fl_wstyle] |
and al,0x0F |
cmp al,0x03 |
jne @f |
mov eax,[_skinh] |
ret |
@@: mov eax,21 |
ret |
get_rolledup_height: ; edi = window draw_data pointer |
mov al,[edi+WDATA.fl_wstyle] |
and al,0x0F |
cmp al,0x03 |
jne @f |
mov eax,[_skinh] |
add eax,3 |
ret |
@@: or al,al |
jnz @f |
mov eax,21 |
ret |
@@: mov eax,21+2 |
ret |
setwindowdefaults: |
pushad |
xor eax,eax |
mov ecx,0xc000 |
@@: |
inc eax |
add ecx,2 |
mov [ecx+0x000],ax ; process no |
mov [ecx+0x400],ax ; positions in stack |
cmp ecx,0xc400-2 ; the more high, the more surface |
jnz @b |
popad |
ret |
; eax = cx |
; ebx = cy |
; ecx = ex |
; edx = ey |
; èäåÿ: ïåðåáðàòü âñå îêíà, íà÷èíàÿ ñ ñàìîãî íèæíåãî, |
; è äëÿ ïîïàâøèõ â çàäàííóþ îáëàñòü |
; ÷àñòåé îêîí âûçâàòü setscreen |
align 4 |
__sys_calculatescreen: |
pushad |
pushfd |
cli |
push edx ecx ebx eax |
mov esi, 1 |
xor eax, eax |
xor ebx, ebx |
mov ecx, [0xFE00] |
mov edx, [0xFE04] |
call [setscreen] |
mov ebp, [0x3004] ; number of processes |
cmp ebp, 1 |
jbe .finish |
align 4 |
.new_wnd: |
movzx edi, word [0xC400 + esi * 2] |
shl edi, 5 |
cmp [0x3000+edi+TASKDATA.state], byte 9 |
je .not_wnd |
add edi, window_data |
test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .not_wnd |
mov eax,[edi+WDATA.box.left] |
cmp eax, [esp+RECT.right] |
jg .out_of_bounds |
mov ebx,[edi+WDATA.box.top] |
cmp ebx, [esp+RECT.bottom] |
jg .out_of_bounds |
mov ecx,[edi+WDATA.box.width] |
add ecx, eax |
cmp ecx, [esp+RECT.left] |
jl .out_of_bounds |
mov edx,[edi+WDATA.box.height] |
add edx, ebx |
cmp edx, [esp+RECT.top] |
jl .out_of_bounds |
cmp eax, [esp+RECT.left] |
jge @f |
mov eax, [esp+RECT.left] |
@@: |
cmp ebx, [esp+RECT.top] |
jge @f |
mov ebx, [esp+RECT.top] |
@@: |
cmp ecx, [esp+RECT.right] |
jle @f |
mov ecx, [esp+RECT.right] |
@@: |
cmp edx, [esp+RECT.bottom] |
jle @f |
mov edx, [esp+RECT.bottom] |
@@: |
push esi |
movzx esi, word [0xC400 + esi * 2] |
call [setscreen] |
pop esi |
.not_wnd: |
.out_of_bounds: |
inc esi |
dec ebp |
jnz .new_wnd |
.finish: |
pop eax ebx ecx edx |
popfd |
popad |
ret |
virtual at esp |
ff_x dd ? |
ff_y dd ? |
ff_width dd ? |
ff_xsz dd ? |
ff_ysz dd ? |
ff_scale dd ? |
end virtual |
__sys_setscreen: ret |
display_settings: |
; eax = 0 ; DISPLAY redraw |
; ebx = 0 ; all |
; |
; eax = 1 ; BUTTON type |
; ebx = 0 ; flat |
; ebx = 1 ; 3D |
; eax = 2 ; set WINDOW colours |
; ebx = pointer to table |
; ecx = number of bytes define |
; eax = 3 ; get WINDOW colours |
; ebx = pointer to table |
; ecx = number of bytes wanted |
; eax = 4 ; get skin height |
; input : nothing |
; output : eax = skin height in pixel |
; eax = 5 ; get screen workarea |
; input : nothing |
; output : eax = [left]*65536+[right] |
; ebx = [top]*65536+[bottom] |
; eax = 6 ; set screen workarea |
; input : ecx = [left]*65536+[right] |
; edx = [top]*65536+[bottom] |
; output : nothing |
; eax = 7 ; get skin margins |
; input : nothing |
; output : eax = [left]*65536+[right] |
; ebx = [top]*65536+[bottom] |
; eax = 8 ; set window skin |
; input : ecx = pointer to file info block |
; output : eax = FS error code |
pushad |
test eax, eax ; redraw display |
jnz dspl0 |
test ebx, ebx |
jnz dspl0 |
cmp [windowtypechanged],dword 1 |
jne dspl00 |
mov [windowtypechanged],dword 0 |
redraw_screen_direct: |
mov [dlx],dword 0 |
mov [dly],dword 0 |
mov eax,[0xfe00] |
mov [dlxe],eax |
mov eax,[0xfe04] |
mov [dlye],eax |
mov eax,window_data |
call redrawscreen |
dspl00: |
popad |
ret |
dspl0: |
cmp eax,1 ; button type |
jne dspl1 |
and ebx,1 |
cmp ebx,[buttontype] |
je dspl9 |
mov [buttontype],ebx |
mov [windowtypechanged],dword 1 |
dspl9: |
popad |
ret |
dspl1: |
cmp eax,2 ; set common window colours |
jne no_com_colours |
mov [windowtypechanged],dword 1 |
mov esi,[0x3010] |
add esi,TASKDATA.mem_start |
add ebx,[esi] |
mov esi,ebx |
mov edi,common_colours |
and ecx,127 |
cld |
rep movsb |
popad |
ret |
no_com_colours: |
cmp eax,3 ; get common window colours |
jne no_get_com |
mov esi,[0x3010] |
add esi,TASKDATA.mem_start |
add ebx,[esi] |
mov edi,ebx |
mov esi,common_colours |
and ecx,127 |
cld |
rep movsb |
popad |
ret |
no_get_com: |
cmp eax,4 ; get skin height |
jne no_skin_height |
popad |
mov eax,[_skinh] |
mov [esp+36],eax |
ret |
no_skin_height: |
cmp eax,5 ; get screen workarea |
jne no_get_workarea |
popad |
mov eax,[screen_workarea.left-2] |
mov ax,word[screen_workarea.right] |
mov [esp+36],eax |
mov eax,[screen_workarea.top-2] |
mov ax,word[screen_workarea.bottom] |
mov [esp+24],eax |
ret |
no_get_workarea: |
cmp eax,6 ; set screen workarea |
jne no_set_workarea |
movsx eax,word[esp+16+2] |
movsx ebx,word[esp+16] |
cmp eax,ebx |
jge .lp1 |
or eax,eax;[0xFE00] |
jl @f |
mov [screen_workarea.left],eax |
@@: cmp ebx,[0xFE00] |
jg .lp1 |
mov [screen_workarea.right],ebx |
.lp1: movsx eax,word[esp+24+2] |
movsx ebx,word[esp+24] |
cmp eax,ebx |
jge .lp2 |
or eax,eax;[0xFE04] |
jl @f |
mov [screen_workarea.top],eax |
@@: cmp ebx,[0xFE04] |
jg .lp2 |
mov [screen_workarea.bottom],ebx |
.lp2: call repos_windows |
mov eax, 0 |
mov ebx, 0 |
mov ecx, [0xfe00] |
mov edx, [0xfe04] |
call [calculatescreen] |
; jmp redraw_screen_direct |
.exit: |
popad |
ret |
no_set_workarea: |
cmp eax,7 ; get skin margins |
jne no_get_skinmargins |
popad |
mov eax,dword[_skinmargins+0] |
mov [esp+36],eax |
mov eax,dword[_skinmargins+4] |
mov [esp+24],eax |
ret |
no_get_skinmargins: |
cmp eax,8 ; set window skin |
jne no_set_skin |
mov eax,ebx |
mov edi,[0x3010] |
add ebx,[edi+TASKDATA.mem_start] ; abs start of info block |
pushd [ebx+0] [ebx+4] [ebx+8] [ebx+12] |
mov dword[ebx+0],0 ; read |
mov dword[ebx+4],0 ; from the beginning |
mov dword[ebx+8],64 ; 32 KBytes maximum |
mov ecx,skin_data+64*512 |
sub ecx,[edi+0x10] |
mov dword[ebx+12],ecx ; destination |
push eax |
pushad |
call file_system |
popad |
pop eax |
popd [ebx+12] [ebx+8] [ebx+4] [ebx+0] |
cmp eax,ERROR_SUCCESS |
je @f |
cmp eax,ERROR_END_OF_FILE |
jne .exit |
@@: cmp [skin_data+64*512+SKIN_HEADER.ident],'SKIN' |
mov eax,ERROR_UNKNOWN_FS |
jne .exit |
mov esi,skin_data+64*512 |
mov edi,skin_data |
mov ecx,(64*512)/4 |
rep movsd |
call parse_skin_data |
pushad |
mov eax, 0 |
mov ebx, 0 |
mov ecx, [0xfe00] |
mov edx, [0xfe04] |
call [calculatescreen] |
popad |
mov dword[esp+32+36],0 |
jmp redraw_screen_direct |
.exit: |
mov [esp+32+36],eax |
popad |
ret |
no_set_skin: |
popad |
ret |
repos_windows: |
mov ecx,[0x3004] |
mov esi,0x20*2 |
mov byte[0x0000fff0],1 |
dec ecx |
jge @f |
ret |
@@: mov [esi+WDATA.fl_redraw],1 |
test [esi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jz .lp2 |
mov eax,[screen_workarea.left] |
mov [esi+WDATA.box.left],eax |
sub eax,[screen_workarea.right] |
neg eax |
mov [esi+WDATA.box.width],eax |
mov eax,[screen_workarea.top] |
mov [esi+WDATA.box.top],eax |
test [esi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz .lp1 |
sub eax,[screen_workarea.bottom] |
neg eax |
mov [esi+WDATA.box.height],eax |
.lp1: add esi,0x20 |
loop @b |
ret |
.lp2: mov eax,[esi+WDATA.box.left] |
add eax,[esi+WDATA.box.width] |
mov ebx,[0x0000fe00] |
; inc ebx |
cmp eax,ebx |
jle .lp4 |
mov eax,[esi+WDATA.box.width] |
sub eax,ebx |
jle .lp3 |
mov [esi+WDATA.box.width],ebx |
.lp3: sub ebx,[esi+WDATA.box.width] |
mov [esi+WDATA.box.left],ebx |
.lp4: mov eax,[esi+WDATA.box.top] |
add eax,[esi+WDATA.box.height] |
mov ebx,[0x0000fe04] |
; inc ebx |
cmp eax,ebx |
jle .lp6 |
mov eax,[esi+WDATA.box.height] |
sub eax,ebx |
jle .lp5 |
mov [esi+WDATA.box.height],ebx |
.lp5: sub ebx,[esi+WDATA.box.height] |
mov [esi+WDATA.box.top],ebx |
.lp6: add esi,0x20 |
loop @b |
ret |
uglobal |
common_colours: |
times 128 db 0x0 |
endg |
check_window_position: |
ret |
uglobal |
new_window_starting dd 0 |
endg |
sys_window_mouse: |
push eax |
mov eax,[timer_ticks] |
cmp [new_window_starting],eax |
jb swml1 |
mov [0xfff4],byte 0 ; no mouse background |
mov [0xfff5],byte 0 ; draw mouse |
mov [new_window_starting],eax |
swml1: |
pop eax |
ret |
drawwindow_I_caption: |
mov ecx,[edx+WDATA.cl_titlebar] ; grab bar |
push ecx |
mov esi,edx |
mov edx,[esi+WDATA.box.top] |
add edx,1 |
mov ebx,[esi+WDATA.box.top] |
add ebx,21 |
mov eax,[esi+WDATA.box.top] |
add eax,[esi+WDATA.box.height] |
cmp ebx,eax |
jb .wdsizeok |
mov ebx,eax |
.wdsizeok: |
push ebx |
.drwi: |
mov ebx,edx |
shl ebx,16 |
add ebx,edx |
mov eax,[esi+WDATA.box.left] |
inc eax |
shl eax,16 |
add eax,[esi+WDATA.box.left] |
add eax,[esi+WDATA.box.width] |
sub eax,1 |
mov ecx,[esi+WDATA.cl_titlebar] |
test ecx,0x80000000 |
jz .nofa |
sub ecx,0x00040404 |
mov [esi+WDATA.cl_titlebar],ecx |
.nofa: |
.faj: |
and ecx,0x00ffffff |
mov edi,0 |
call [draw_line] |
inc edx |
cmp edx,[esp] |
jl .drwi |
add esp,4 |
pop ecx |
mov [esi+WDATA.cl_titlebar],ecx |
ret |
drawwindow_I: |
pushad |
mov esi,[edx+WDATA.cl_frames] ; rectangle |
mov eax,[edx+WDATA.box.left] |
shl eax,16 |
add eax,[edx+WDATA.box.left] |
add eax,[edx+WDATA.box.width] |
mov ebx,[edx+WDATA.box.top] |
shl ebx,16 |
add ebx,[edx+WDATA.box.top] |
add ebx,[edx+WDATA.box.height] |
call draw_rectangle |
call drawwindow_I_caption |
mov edx,[esi+WDATA.box.top] ; inside work area |
add edx,21+5 |
mov ebx,[esi+WDATA.box.top] |
add ebx,[esi+WDATA.box.height] |
cmp edx,ebx |
jg noinside |
mov eax,1 |
mov ebx,21 |
mov ecx,[esi+WDATA.box.width] |
mov edx,[esi+WDATA.box.height] |
mov edi,[esi+WDATA.cl_workarea] |
call [drawbar] |
noinside: |
popad |
ret |
draw_rectangle: |
r_eax equ [esp+28] ; x start |
r_ax equ [esp+30] ; x end |
r_ebx equ [esp+16] ; y start |
r_bx equ [esp+18] ; y end |
;esi ; color |
pushad |
mov ecx,esi ; yb,xb -> yb,xe |
mov eax, r_eax |
rol eax, 16 |
mov ebx,r_ebx |
shl ebx,16 |
mov bx,r_ebx |
xor edi, edi |
call [draw_line] |
mov ebx,r_bx ; ye,xb -> ye,xe |
shl ebx,16 |
mov bx,r_bx |
call [draw_line] |
mov ecx,esi ; ya,xa -> ye,xa |
mov eax,r_eax |
shl eax,16 |
mov ax,r_eax |
mov ebx,r_ebx |
shl ebx,16 |
mov bx,r_bx |
mov edi,0 |
call [draw_line] |
mov eax,r_ax ; ya,xe -> ye,xe |
shl eax,16 |
mov ax,r_ax |
call [draw_line] |
popad |
ret |
drawwindow_III_caption: |
mov ecx,[edx+WDATA.cl_titlebar] ; GRAB BAR |
push ecx |
mov esi,edx |
mov edx,[esi+WDATA.box.top] |
add edx,4 |
mov ebx,[esi+WDATA.box.top] |
add ebx,20 |
mov eax,[esi+WDATA.box.top] |
add eax,[esi+WDATA.box.height] |
cmp ebx,eax |
jl .wdsizeok |
mov ebx,eax |
.wdsizeok: |
push ebx |
.drwi: |
mov ebx,edx |
shl ebx,16 |
add ebx,edx |
mov eax,[esi+WDATA.box.left] |
shl eax,16 |
add eax,[esi+WDATA.box.left] |
add eax,[esi+WDATA.box.width] |
add eax,4*65536-4 |
mov ecx,[esi+WDATA.cl_titlebar] |
test ecx,0x40000000 |
jz .nofa |
add ecx,0x040404 |
.nofa: |
test ecx,0x80000000 |
jz .nofa2 |
sub ecx,0x040404 |
.nofa2: |
mov [esi+WDATA.cl_titlebar],ecx |
and ecx,0xffffff |
xor edi, edi |
call [draw_line] |
inc edx |
cmp edx,[esp] |
jl .drwi |
add esp,4 |
pop ecx |
mov [esi+WDATA.cl_titlebar],ecx |
ret |
drawwindow_III: |
pushad |
mov edi,edx ; RECTANGLE |
mov eax,[edi+WDATA.box.left] |
shl eax,16 |
mov ax, word [edi+WDATA.box.left] |
add ax, word [edi+WDATA.box.width] |
mov ebx,[edi+WDATA.box.top] |
shl ebx,16 |
mov bx, word [edi+WDATA.box.top] |
add bx, word [edi+WDATA.box.height] |
mov esi,[edi+WDATA.cl_frames] |
shr esi,1 |
and esi,0x007f7f7f |
push esi |
call draw_rectangle |
mov ecx,3 |
dw3l: |
add eax,1*65536-1 |
add ebx,1*65536-1 |
mov esi,[edi+WDATA.cl_frames] |
call draw_rectangle |
dec ecx |
jnz dw3l |
pop esi |
add eax,1*65536-1 |
add ebx,1*65536-1 |
call draw_rectangle |
call drawwindow_III_caption |
mov edx,[esi+WDATA.box.top] ; WORK AREA |
add edx,21+5 |
mov ebx,[esi+WDATA.box.top] |
add ebx,[esi+WDATA.box.height] |
cmp edx,ebx |
jg noinside2 |
mov eax,5 |
mov ebx,20 |
mov ecx,[esi+WDATA.box.width] |
mov edx,[esi+WDATA.box.height] |
sub ecx,4 |
sub edx,4 |
mov edi,[esi+WDATA.cl_workarea] |
call [drawbar] |
noinside2: |
popad |
ret |
; activate window |
align 4 |
windowactivate: |
; esi = abs mem position in stack 0xC400+ |
pushad |
; if type of current active window is 3, |
; it must be redrawn |
mov eax, [0x3004] |
movzx eax, word [0xC400 + eax*2] |
shl eax, 5 |
add eax, window_data |
mov ebx, [eax + WDATA.cl_workarea] |
and ebx, 0x0f000000 |
cmp ebx, 0x03000000 |
jne @f |
mov [eax + WDATA.fl_redraw], byte 1 |
@@: |
push esi |
movzx eax, word [esi] ; ax <- process no |
movzx eax, word [0xC000+eax*2] ; ax <- position in window stack |
xor esi, esi ; drop others |
waloop: |
cmp esi, dword [0x3004] |
jae wacont |
inc esi |
lea edi, [0xC000 + esi*2] |
mov bx, [edi] ; position of the current process |
cmp bx, ax |
jbe @f |
dec bx ; upper? => drop! |
mov [edi], bx |
@@: |
jmp waloop |
wacont: |
; set to no 1 |
pop esi ; esi = pointer at 0xC400 |
movzx eax, word [esi] |
mov bx, [0x3004] ; number of processes |
mov [0xC000+eax*2], bx ; this is the last (and the upper) |
; update on screen -window stack |
xor esi, esi |
waloop2: |
cmp esi,[0x3004] |
jae wacont2 |
inc esi |
movzx ebx, word [esi*2 + 0xC000] |
mov [ebx*2 + 0xC400], si |
jmp waloop2 |
wacont2: |
mov [0xf400], byte 0 ; empty keyboard buffer |
mov [0xf500], byte 0 ; empty button buffer |
popad |
ret |
; check if window is necessary to draw |
checkwindowdraw: |
; edi = position in window_data+ |
mov eax, [edi + WDATA.cl_workarea] |
and eax, 0x0f000000 |
cmp eax, 0x03000000 |
je .return_yes ; window type 3 |
mov esi, edi |
sub esi, window_data |
shr esi, 5 |
; esi = process number |
movzx eax, word [0xC000 + esi * 2] ; get value of the curr process |
lea esi, [0xC400 + eax * 2] ; get address of this process at 0xC400 |
push esi |
.new_check: |
pop esi |
add esi, 2 |
push esi |
mov eax, [0x3004] |
lea eax, word [0xC400 + eax * 2] ; number of the upper window |
cmp esi, eax |
ja .all_wnds_to_top |
movzx eax, word [esi] |
shl eax, 5 |
cmp [0x3000 + eax + TASKDATA.state], byte 9 |
je .new_check ; skip dead windows |
lea esi, [eax+window_data] |
mov ebx, [edi+WDATA.box.top] ; y0 |
mov edx, [edi+WDATA.box.height] |
add edx, ebx ; y0e |
mov ecx, [esi+WDATA.box.top] ; y ; y check |
cmp ecx, edx |
jae .new_check ; y < y0e |
mov eax, [esi+WDATA.box.height] |
add ecx, eax ; ye |
cmp ebx, ecx ; y0 >= ye |
ja .new_check |
mov eax, [edi+WDATA.box.left] ; x0 |
mov ecx, [edi+WDATA.box.width] |
add ecx, eax ; x0e |
mov edx, [esi+WDATA.box.left] ; x ; x check |
cmp edx, ecx |
jae .new_check ; x < x0e |
mov ecx, [esi+WDATA.box.width] |
add edx, ecx |
cmp eax, edx |
ja .new_check |
pop esi |
.return_yes: |
mov ecx,1 ; overlap some window |
ret |
.all_wnds_to_top: |
pop esi |
xor ecx, ecx ; passed all windows to top |
ret |
waredraw: ; if redraw necessary at activate |
pushad |
call checkwindowdraw ; draw window on activation ? |
test ecx, ecx |
jz .do_not_draw |
popad |
mov [0xfb44], byte 1 ; do draw mouse |
call windowactivate |
; update screen info |
call [calc_clipping_rects] |
pushad |
mov edi, [0x3004] ; the last process (number) |
movzx esi, word [0xC400 + edi * 2] |
shl esi, 5 |
add esi, window_data |
; coordinates of the upper window |
mov eax, [esi + WDATA.box.left] ; cx |
mov ebx, [esi + WDATA.box.top] ; cy |
mov ecx, [esi + WDATA.box.width] ; sx |
mov edx, [esi + WDATA.box.height] ; sy |
add ecx, eax ; ecx = x_end |
add edx, ebx ; edx = y_end |
mov edi, [0x3004] |
movzx esi, word [0xC400 + edi * 2] |
call [setscreen] |
popad |
mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app |
mov [0xfb44],byte 0 ; mouse down checks |
ret |
.do_not_draw: |
popad |
call windowactivate |
mov [0xfb44],byte 0 ; mouse down checks |
mov [0xfff4],byte 0 ; no mouse background |
mov [0xfff5],byte 0 ; draw mouse |
ret |
; eax = window number on screen |
; corrupts registers and [dl*] |
minimize_window: |
movzx eax, word [0xC400+eax*2] |
shl eax, 5 |
add eax, window_data |
test [eax+WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .skip_redrawings |
pushfd |
cli |
or [eax+WDATA.fl_wstate], WSTATE_MINIMIZED |
mov edi, eax |
;call calculatescreen |
mov eax, [edi+WDATA.box.left] |
mov [dlx], eax |
mov ecx, eax |
add ecx, [edi+WDATA.box.width] |
mov [dlxe], ecx |
mov ebx, [edi+WDATA.box.top] |
mov [dly], ebx |
mov edx, ebx |
add edx, [edi+WDATA.box.height] |
mov [dlye], edx |
call [calculatescreen] |
xor esi, esi |
xor eax, eax |
call redrawscreen |
popfd |
.skip_redrawings: |
ret |
; eax = window number on screen |
; corrupts registers and [dl*] |
restore_minimized_window: |
pushfd |
cli |
movzx esi, word [0xC400+eax*2] |
mov edi, esi |
shl edi, 5 |
add edi, window_data |
test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED |
jz .skip_redrawings |
mov [edi+WDATA.fl_redraw], 1 |
and [edi+WDATA.fl_wstate], not WSTATE_MINIMIZED |
cmp eax, [0x3004] ; the uppermost window |
jnz .no_uppermost |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, eax |
mov edx, ebx |
add ecx, [edi+WDATA.box.width] |
add edx, [edi+WDATA.box.height] |
call [setscreen] |
jmp .done |
.no_uppermost: |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, eax |
mov edx, ebx |
add ecx, [edi+WDATA.box.width] |
add edx, [edi+WDATA.box.height] |
call [calculatescreen] |
.done: |
mov [0xfff4],byte 0 ; no mouse under |
.skip_redrawings: |
popfd |
ret |
iglobal |
window_moving db 'K : Window - move/resize',13,10,0 |
window_moved db 'K : Window - done',13,10,0 |
endg |
; check window touch |
align 4 |
checkwindows: |
pushad |
cmp [window_minimize], 0 |
je .no_minimizing |
mov eax, [0x3004] ; the uppermost window |
mov bl, 0 |
xchg [window_minimize], bl |
cmp bl, 1 |
jne .restore |
call minimize_window |
jmp .continue |
.restore: |
call restore_minimized_window |
.continue: |
.no_minimizing: |
cmp [0xfb40],byte 0 ; mouse buttons pressed ? |
jne .mouse_buttons_pressed |
popad |
ret |
.mouse_buttons_pressed: |
mov esi,[0x3004] |
inc esi |
cwloop: |
cmp esi,2 |
jb .exit |
dec esi |
movzx edi, word [0xC400 + esi * 2] ; ebx |
shl edi, 5 |
add edi, window_data |
; mov edi, ebx |
mov ecx, [edi + WDATA.box.left] |
mov edx, [edi + WDATA.box.top] |
mov eax,ecx |
mov ebx,edx |
test [edi+WDATA.fl_wstate],WSTATE_MINIMIZED |
jnz cwloop |
movzx eax, word [0xfb0a] |
movzx ebx, word [0xfb0c] |
cmp eax,ecx |
jl cwloop |
cmp ebx,edx |
jl cwloop |
add ecx, [edi + WDATA.box.width] |
add edx, [edi + WDATA.box.height] |
cmp eax, ecx |
jg cwloop |
cmp ebx, edx |
jg cwloop |
pushad |
mov eax, esi |
mov ebx, [0x3004] |
cmp eax, ebx ; is this window active? |
jz .move_resize_window |
; eax = position in windowing stack |
; redraw must ? |
lea esi, [0xC400 + esi * 2] |
call waredraw |
add esp, 32 |
.exit: |
popad |
ret |
.move_resize_window: ; MOVE OR RESIZE WINDOW |
popad |
; Check for user enabled fixed window |
mov edx, [edi + WDATA.cl_titlebar] |
and edx, 0x0f000000 |
cmp edx, 0x01000000 |
jne .window_move_enabled_for_user |
popad |
ret |
.window_move_enabled_for_user: |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz .no_resize_2 |
mov [do_resize_from_corner],byte 0 ; resize for skinned window |
mov edx, [edi + WDATA.cl_workarea] |
and edx, 0x0f000000 |
cmp edx, 0x02000000 |
jb .no_resize_2 ; not type 2 wnd |
mov edx, [edi + WDATA.box.top] |
add edx, [edi + WDATA.box.height] |
sub edx, 6 ; edx = y_end - 6 |
cmp ebx, edx ; ebx = mouse_y |
jl .no_resize_2 |
mov [do_resize_from_corner],byte 1 |
jmp .continue |
.no_resize_2: |
push eax |
call get_titlebar_height |
add eax,[edi + WDATA.box.top] |
cmp ebx,eax |
pop eax |
jae .exit |
.continue: |
push esi |
mov esi, window_moving |
call sys_msg_board_str |
pop esi |
mov ecx, [timer_ticks] ; double-click ? |
mov edx, ecx |
sub edx, [latest_window_touch] |
mov [latest_window_touch], ecx |
mov [latest_window_touch_delta], edx |
mov cl, [0xfb40] ; save for shade check |
mov [do_resize], cl |
no_emulation_righ_button: |
mov ecx, [edi + WDATA.box.left] |
mov edx, [edi + WDATA.box.top] |
push eax ecx edx |
mov [dlx], ecx ; save for drawlimits |
mov [dly], edx |
add ecx, [edi + WDATA.box.width] |
add edx, [edi + WDATA.box.height] |
mov [dlxe], ecx |
mov [dlye], edx |
pop edx ecx eax |
sub eax, ecx |
sub ebx, edx |
mov esi, [0xfb0a] |
mov [0xf300], esi |
push eax;ad ; wait for putimages to finish |
; mov eax,5 |
; call delay_hs |
mov eax,[edi + WDATA.box.left] |
mov [npx],eax |
mov eax,[edi + WDATA.box.top] |
mov [npy],eax |
; save old coordinates |
mov eax, [edi + WDATA.box.left] |
mov [oldc+BOX.left], eax |
mov eax, [edi + WDATA.box.top] |
mov [oldc+BOX.top], eax |
mov eax, [edi + WDATA.box.width] |
mov [oldc+BOX.width], eax |
mov [npxe], eax |
mov eax, [edi + WDATA.box.height] |
mov [oldc+BOX.height], eax |
mov [npye], eax |
pop eax |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz @f |
call drawwindowframes |
@@: |
mov [reposition],0 |
mov [0xfb44],byte 1 ; no reaction to mouse up/down |
; move window |
newchm: |
mov [0xfff5],byte 1 |
call checkidle |
call checkVga_N13 |
mov [0xfff4],byte 0 |
call [draw_pointer] |
pushad |
call stack_handler |
popad |
mov esi,[0xf300] |
cmp esi,[0xfb0a] |
je cwb |
movzx ecx,word[0xfb0a] |
movzx edx,word[0xfb0c] |
sub ecx,eax |
sub edx,ebx |
push eax |
push ebx |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz @f |
call drawwindowframes |
@@: |
mov ax,[0xfe00] |
mov bx,[0xfe04] |
cmp [do_resize_from_corner],1 |
je no_new_position |
mov [reposition],1 |
movsx ecx,cx |
mov [npx],ecx |
noreposx: |
mov [reposition],1 |
movsx edx,dx |
mov [npy],edx |
noreposy: |
no_new_position: |
cmp [do_resize_from_corner],0 ; resize from right corner |
je norepos_size |
pushad |
mov edx,edi |
sub edx,window_data |
;shr edx,5 |
;shl edx,8 |
;add edx,0x80000 ; process base at 0x80000+ |
lea edx, [0x80000 + edx*8] |
movzx eax,word [0xfb0a] |
cmp eax,[edi + WDATA.box.left] |
jl nnepx |
sub eax,[edi + WDATA.box.left] |
cmp eax,32 ; [edx+0x90+8] |
jge nnepx2 |
mov eax,32 ; [edx+0x90+8] |
nnepx2: |
mov [npxe],eax |
nnepx: |
call get_rolledup_height |
mov ebx,eax |
movzx eax,word [0xfb0c] |
cmp eax,[edi + WDATA.box.top] |
jl nnepy |
sub eax,[edi + WDATA.box.top] |
cmp eax,ebx ; [edx+0x90+12] |
jge nnepy2 |
mov eax,ebx ; [edx+0x90+12] |
nnepy2: |
mov [npye],eax |
nnepy: |
mov [reposition],1 |
popad |
norepos_size: |
pop ebx |
pop eax |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz @f |
call drawwindowframes |
@@: |
mov esi,[0xfb0a] |
mov [0xf300],esi |
cwb: |
cmp [0xfb40],byte 0 |
jne newchm |
; new position done |
mov [0xfff5],byte 1 |
mov cl,0 |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz @f |
mov cl,[reposition] |
call drawwindowframes |
mov eax,[npx] |
mov [edi + WDATA.box.left],eax |
mov eax,[npy] |
mov [edi + WDATA.box.top],eax |
mov eax,[npxe] |
mov [edi + WDATA.box.width],eax |
mov eax,[npye] |
mov [edi + WDATA.box.height],eax |
@@: mov [reposition],cl |
cmp [reposition],1 ; save new position and size |
jne no_bounds_save |
push esi edi ecx |
mov esi,edi |
mov ecx,2 |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP or WSTATE_MAXIMIZED |
jnz @f |
add ecx,2 |
@@: sub edi,window_data |
shr edi,5 |
shl edi,8 |
add edi,0x80000+APPDATA.saved_box |
cld |
rep movsd |
pop ecx edi esi |
no_bounds_save: |
pushad ; WINDOW SHADE/FULLSCREEN |
cmp [reposition],1 |
je no_window_sizing |
mov edx,edi |
sub edx,window_data |
shr edx,5 |
shl edx,8 |
add edx,0x80000 ; process base at 0x80000+ |
cmp [do_resize],2 ; window shade ? |
jne no_window_shade |
mov [reposition],1 |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz wnd_rolldown |
wnd_rollup: |
or [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
call get_rolledup_height |
jmp @f |
wnd_rolldown: |
and [edi+WDATA.fl_wstate],not WSTATE_ROLLEDUP |
mov eax,[edx + APPDATA.saved_box.height] ; 0x90+BOX.height |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jz @f |
mov eax,[screen_workarea.bottom] |
sub eax,[screen_workarea.top] |
@@: mov [edi+WDATA.box.height],eax |
no_window_shade: |
cmp [do_resize],1 ; fullscreen/restore ? |
jne no_fullscreen_restore |
cmp [latest_window_touch_delta],dword 50 |
jg no_fullscreen_restore |
mov [reposition],1 |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz restore_from_fullscreen |
or [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
mov eax,[screen_workarea.left] |
mov [edi+WDATA.box.left],eax |
sub eax,[screen_workarea.right] |
neg eax |
mov [edi+WDATA.box.width],eax |
mov eax,[screen_workarea.top] |
mov [edi+WDATA.box.top],eax |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz @f |
sub eax,[screen_workarea.bottom] |
neg eax |
mov [edi+WDATA.box.height],eax |
@@: |
jmp no_fullscreen_restore |
restore_from_fullscreen: |
and [edi+WDATA.fl_wstate],not WSTATE_MAXIMIZED |
push [edi+WDATA.box.height] |
push edi ; restore |
lea esi, [edx + APPDATA.saved_box] |
mov ecx,4 |
cld |
rep movsd |
pop edi |
pop eax |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jz @f |
mov [edi+WDATA.box.height],eax |
@@: |
no_fullscreen_restore: |
no_window_sizing: |
popad |
cmp [reposition],0 |
je retwm |
mov [0xfff5],byte 1 ; no mouse |
call [calc_clipping_rects] |
mov eax,edi |
call redrawscreen |
mov [edi+WDATA.fl_redraw],1 |
mov ecx,100 ; wait to avoid mouse residuals |
waitre2: |
mov [0xfff5],byte 1 |
call checkidle |
cmp [edi+WDATA.fl_redraw],0 |
jz retwm |
loop waitre2 |
retwm: |
mov [0xfff5],byte 0 ; mouse pointer |
mov [0xfff4],byte 0 ; no mouse under |
mov [0xfb44],byte 0 ; react to mouse up/down |
mov esi,window_moved |
call sys_msg_board_str |
popad |
ret |
uglobal |
add_window_data dd 0 |
do_resize_from_corner db 0x0 |
reposition db 0x0 |
latest_window_touch dd 0x0 |
latest_window_touch_delta dd 0x0 |
do_resize db 0x0 |
oldc dd 0x0,0x0,0x0,0x0 |
dlx dd 0x0 |
dly dd 0x0 |
dlxe dd 0x0 |
dlye dd 0x0 |
npx dd 0x0 |
npy dd 0x0 |
npxe dd 0x0 |
npye dd 0x0 |
mpx dd 0x0 |
mpy dd 0x0 |
endg |
; draw negative window frames |
drawwindowframes: |
pushad |
mov eax,[npx] |
shl eax,16 |
add eax,[npx] |
add eax,[npxe] |
add eax,65536*1-1 |
mov ebx,[npy] |
shl ebx,16 |
add ebx,[npy] |
mov ecx,0x01000000 |
push edi |
mov edi,1 |
call [draw_line] |
pop edi |
mov eax,[npx] |
shl eax,16 |
add eax,[npx] |
add eax,[npxe] |
add eax,65536*1-1 |
mov ebx,[npy] |
add ebx,[npye] |
shl ebx,16 |
add ebx,[npy] |
add ebx,[npye] |
mov ecx,0x01000000 |
push edi |
mov edi,1 |
call [draw_line] |
pop edi |
mov eax,[npx] |
shl eax,16 |
add eax,[npx] |
mov ebx,[npy] |
shl ebx,16 |
add ebx,[npy] |
add ebx,[npye] |
mov ecx,0x01000000 |
push edi |
mov edi,1 |
call [draw_line] |
pop edi |
mov eax,[npx] |
add eax,[npxe] |
shl eax,16 |
add eax,[npx] |
add eax,[npxe] |
mov ebx,[npy] |
shl ebx,16 |
add ebx,[npy] |
add ebx,[npye] |
mov ecx,0x01000000 |
push edi |
mov edi,1 |
call [draw_line] |
mov edi,[0x3000] |
shl edi,5 |
add edi,window_data |
mov [edi+WDATA.fl_wdrawn],byte 1 |
pop edi |
popad |
ret |
random_shaped_window: |
; |
; eax = 0 giving address of data area |
; ebx address |
; eax = 1 shape area scale |
; ebx 2^ebx scale |
test eax, eax |
jne rsw_no_address |
mov eax,[0x3000] |
shl eax,8 |
mov [eax+0x80000+APPDATA.wnd_shape],ebx |
rsw_no_address: |
cmp eax,1 |
jne rsw_no_scale |
mov eax,[0x3000] |
shl eax,8 |
mov byte [eax+0x80000+APPDATA.wnd_shape_scale], bl |
rsw_no_scale: |
ret |
/kernel/branches/gfx_kernel/hid/keyboard.inc |
---|
0,0 → 1,293 |
;// mike.dld [ |
VKEY_LSHIFT = 0000000000000001b |
VKEY_RSHIFT = 0000000000000010b |
VKEY_LCONTROL = 0000000000000100b |
VKEY_RCONTROL = 0000000000001000b |
VKEY_LALT = 0000000000010000b |
VKEY_RALT = 0000000000100000b |
VKEY_CAPSLOCK = 0000000001000000b |
VKEY_NUMLOCK = 0000000010000000b |
VKEY_SCRLOCK = 0000000100000000b |
VKEY_SHIFT = 0000000000000011b |
VKEY_CONTROL = 0000000000001100b |
VKEY_ALT = 0000000000110000b |
uglobal |
align 4 |
kb_state dd 0 |
ext_code db 0 |
keyboard_mode db 0 |
keyboard_data db 0 |
altmouseb db 0 |
ctrl_alt_del db 0 |
kb_lights db 0 |
align 4 |
hotkey_scancodes rd 256 ; we have 256 scancodes |
hotkey_list rd 256*4 ; max 256 defined hotkeys |
hotkey_buffer rd 120*2 ; buffer for 120 hotkeys |
endg |
iglobal |
hotkey_tests dd hotkey_test0 |
dd hotkey_test1 |
dd hotkey_test2 |
dd hotkey_test3 |
dd hotkey_test4 |
hotkey_tests_num = 5 |
endg |
hotkey_test0: |
test al, al |
setz al |
ret |
hotkey_test1: |
test al, al |
setnp al |
ret |
hotkey_test2: |
cmp al, 3 |
setz al |
ret |
hotkey_test3: |
cmp al, 1 |
setz al |
ret |
hotkey_test4: |
cmp al, 2 |
setz al |
ret |
hotkey_do_test: |
push eax |
mov edx, [kb_state] |
shr edx, cl |
add cl, cl |
mov eax, [eax+4] |
shr eax, cl |
and eax, 15 |
cmp al, hotkey_tests_num |
jae .fail |
xchg eax, edx |
and al, 3 |
call [hotkey_tests + edx*4] |
cmp al, 1 |
pop eax |
ret |
.fail: |
stc |
pop eax |
ret |
align 4 |
irq1: |
save_ring3_context |
mov ax, os_data |
mov ds, ax |
mov es, ax |
mov eax, [0x3004] ; top window process |
movzx eax,word[0xC400+eax*2] |
shl eax,8 |
mov al,[0x80000+eax+APPDATA.keyboard_mode] |
mov [keyboard_mode],al |
in al,0x60 |
mov [keyboard_data],al |
; ch = scancode |
; cl = ext_code |
; bh = 0 - normal key |
; bh = 1 - modifier (Shift/Ctrl/Alt) |
; bh = 2 - extended code |
mov ch,al |
cmp al,0xE0 |
je @f |
cmp al,0xE1 |
jne .normal_code |
@@: |
mov bh, 2 |
mov [ext_code], al |
jmp .writekey |
.normal_code: |
mov cl, 0 |
xchg cl, [ext_code] |
and al,0x7F |
mov bh, 1 |
@@: cmp al,0x2A |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_LSHIFT |
jmp .modifier |
@@: cmp al,0x36 |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_RSHIFT |
jmp .modifier |
@@: cmp al,0x38 |
jne @f |
mov eax, VKEY_LALT |
test cl, cl |
jz .modifier |
mov al, VKEY_RALT |
jmp .modifier |
@@: cmp al,0x1D |
jne @f |
mov eax, VKEY_LCONTROL |
test cl, cl |
jz .modifier |
mov al, VKEY_RCONTROL |
cmp cl, 0xE0 |
jz .modifier |
mov [ext_code], cl |
jmp .writekey |
@@: cmp al,0x3A |
jne @f |
mov bl,4 |
mov eax,VKEY_CAPSLOCK |
jmp .no_key.xor |
@@: cmp al,0x45 |
jne @f |
test cl, cl |
jnz .writekey |
mov bl,2 |
mov eax,VKEY_NUMLOCK |
jmp .no_key.xor |
@@: cmp al,0x46 |
jne @f |
mov bl,1 |
mov eax,VKEY_SCRLOCK |
jmp .no_key.xor |
@@: |
test ch,ch |
js .writekey |
movzx eax,ch ; plain key |
mov bl,[keymap+eax] |
mov edx,[kb_state] |
test dl,VKEY_CONTROL ; ctrl alt del |
jz .noctrlaltdel |
test dl,VKEY_ALT |
jz .noctrlaltdel |
cmp ch,53h |
jne .noctrlaltdel |
mov [ctrl_alt_del],1 |
.noctrlaltdel: |
test dl,VKEY_CONTROL ; ctrl on ? |
jz @f |
sub bl,0x60 |
@@: test dl,VKEY_SHIFT ; shift on ? |
jz @f |
mov bl,[keymap_shift+eax] |
@@: test dl,VKEY_ALT ; alt on ? |
jz @f |
mov bl,[keymap_alt+eax] |
@@: |
mov bh, 0 |
jmp .writekey |
.modifier: |
test ch, ch |
js .modifier.up |
or [kb_state], eax |
jmp .writekey |
.modifier.up: |
not eax |
and [kb_state], eax |
jmp .writekey |
.no_key.xor: |
mov bh, 0 |
test ch, ch |
js .writekey |
xor [kb_state], eax |
xor [kb_lights], bl |
call set_lights |
.writekey: |
; test for system hotkeys |
movzx eax, ch |
cmp bh, 1 |
ja .nohotkey |
jb @f |
xor eax, eax |
@@: |
mov eax, [hotkey_scancodes + eax*4] |
.hotkey_loop: |
test eax, eax |
jz .nohotkey |
mov cl, 0 |
call hotkey_do_test |
jc .hotkey_cont |
mov cl, 2 |
call hotkey_do_test |
jc .hotkey_cont |
mov cl, 4 |
call hotkey_do_test |
jnc .hotkey_found |
.hotkey_cont: |
mov eax, [eax] |
jmp .hotkey_loop |
.hotkey_found: |
mov eax, [eax+8] |
; put key in buffer for process in slot eax |
mov edi, hotkey_buffer |
@@: |
cmp dword [edi], 0 |
jz .found_free |
add edi, 8 |
cmp edi, hotkey_buffer+120*8 |
jb @b |
; no free space - replace first entry |
mov edi, hotkey_buffer |
.found_free: |
mov [edi], eax |
movzx eax, ch |
cmp bh, 1 |
jnz @f |
xor eax, eax |
@@: |
mov [edi+4], ax |
mov eax, [kb_state] |
mov [edi+6], ax |
jmp .exit.irq1 |
.nohotkey: |
cmp [keyboard_mode],0 ; return from keymap |
jne .scancode |
test bh, bh |
jnz .exit.irq1 |
test bl, bl |
jz .exit.irq1 |
jmp .dowrite |
.scancode: |
mov bl, ch |
.dowrite: |
movzx eax,byte[0xF400] |
cmp al,120 |
jae .exit.irq1 |
inc eax |
mov [0xF400],al |
mov [0xF400+eax],bl |
.exit.irq1: |
mov [check_idle_semaphore],5 |
mov al,0x20 ; ready for next irq |
out 0x20,al |
restore_ring3_context |
iret |
set_lights: |
mov al,0xED |
call kb_write |
mov al,[kb_lights] |
call kb_write |
ret |
;// mike.dld ] |
/kernel/branches/gfx_kernel/hid/m_com1.inc |
---|
0,0 → 1,130 |
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà |
MouseByteNumber DB 0 |
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ |
FirstByte DB 0 |
SecondByte DB 0 |
ThirdByte DB 0 |
timer_ticks_com dd 0 |
;*************************************** |
;* ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ * |
;*************************************** |
check_mouse_data_com1: |
; cmp [com1_mouse_detected],0 |
; je @@EndMouseInterrupt |
; Ïðîâåðèòü íàëè÷èå äàííûõ |
mov DX,3F8h ;[COMPortBaseAddr] |
add DX,5 ;xFDh |
in AL,DX |
test AL,1 ;Äàííûå ãîòîâû? |
jz @@Error |
; Ââåñòè äàííûå |
mov DX,3F8h ;[COMPortBaseAddr] ;xF8h |
in AL,DX |
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò |
and AL,01111111b |
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà |
cmp [MouseByteNumber],0 |
je @@FirstByte |
cmp [MouseByteNumber],1 |
je @@SecondByte |
cmp [MouseByteNumber],2 |
je @@ThirdByte |
jmp @@Error |
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ |
@@FirstByte: |
test AL,1000000b ;Ïåðâûé áàéò ïîñûëêè? |
jz @@Error |
mov [FirstByte],AL |
inc [MouseByteNumber] ;óâåëè÷èòü ñ÷åò÷èê |
jmp @@EndMouseInterrupt |
; Ñîõðàíèòü âòîðîé áàéò äàííûõ |
@@SecondByte: |
test AL,1000000b |
jnz @@Error |
mov [SecondByte],AL |
inc [MouseByteNumber] ;óâåëè÷èòü ñ÷åò÷èê |
jmp @@EndMouseInterrupt |
; Ñîõðàíèòü òðåòèé áàéò äàííûõ |
@@ThirdByte: |
test AL,1000000b |
jnz @@Error |
mov [ThirdByte],AL ;óâåëè÷èòü ñ÷åò÷èê |
mov [MouseByteNumber],0 |
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ). |
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè |
mov al,[FirstByte] ;[0xfb01] |
mov ah,al |
shr al,3 |
and al,2 |
shr ah,5 |
and ah,1 |
add al,ah |
mov [0xfb40],al |
mov [mouse_active],1 |
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X |
mov AL,[FirstByte] |
shl AL,6 |
or AL,[SecondByte] |
cbw |
call mouse_acceleration_com1 |
add AX,[0xFB0A] ;[XCoordinate] |
; Êóðñîð íå äîëæåí âûõîäèòü çà ëåâóþ èëè |
; ïðàâóþ ãðàíèöó ýêðàíà |
js @@X1 |
cmp AX,[0xFE00] ;ScreenLength |
jb @@X2 |
; Óñòàíîâèòü êîîðäèíàòó X ïî ïðàâîé ãðàíèöå |
mov AX,[0xFE00] ;ScreenLength-1 |
dec ax |
jmp @@X2 |
@@X1: |
; Óñòàíîâèòü êîîðäèíàòó X ïî ëåâîé ãðàíèöå |
xor AX,AX |
@@X2: |
mov [0xFB0A],AX ;[XCoordinate] |
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y |
mov AL,[FirstByte] |
and AL,00001100b |
shl AL,4 |
or AL,[ThirdByte] |
cbw |
call mouse_acceleration_com1 |
add AX,[0xFB0C] ;[YCoordinate] |
; Êóðñîð íå äîëæåí âûõîäèòü çà âåðõíþþ èëè |
; íèæíþþ ãðàíèöó ýêðàíà |
js @@Y1 |
cmp AX,[0xFE04] ;ScreenHeigth |
jb @@Y2 |
; Óñòàíîâèòü êîîðäèíàòó X ïî íèæíåé ãðàíèöå |
mov AX,[0xFE04] ;ScreenHeigth-1 |
dec ax |
jmp @@Y2 |
@@Y1: |
; Óñòàíîâèòü êîîðäèíàòó X ïî âåðõíåé ãðàíèöå |
xor AX,AX |
@@Y2: |
mov [0xFB0C],AX ;[YCoordinate] |
mov eax,[timer_ticks] |
mov [timer_ticks_com],eax |
jmp @@EndMouseInterrupt |
@@Error: |
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò |
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ |
mov [MouseByteNumber],0 |
@@EndMouseInterrupt: |
call ready_for_next_irq |
ret |
mouse_acceleration_com1: |
push eax |
mov eax,[timer_ticks] |
sub eax,[timer_ticks_com] |
cmp eax,[mouse_delay] |
pop eax |
ja @f |
shl ax,1 |
@@: |
ret |
/kernel/branches/gfx_kernel/hid/m_com2.inc |
---|
0,0 → 1,130 |
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà |
MouseByteNumber_1 DB 0 |
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ |
FirstByte_1 DB 0 |
SecondByte_1 DB 0 |
ThirdByte_1 DB 0 |
timer_ticks_com_1 dd 0 |
;*************************************** |
;* ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ * |
;*************************************** |
check_mouse_data_com2: |
; cmp [com2_mouse_detected],0 |
; je @@EndMouseInterrupt_1 |
; Ïðîâåðèòü íàëè÷èå äàííûõ |
mov DX,2F8h ;[COMPortBaseAddr] |
add DX,5 ;xFDh |
in AL,DX |
test AL,1 ;Äàííûå ãîòîâû? |
jz @@Error_1 |
; Ââåñòè äàííûå |
mov DX,2F8h ;[COMPortBaseAddr] ;xF8h |
in AL,DX |
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò |
and AL,01111111b |
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà |
cmp [MouseByteNumber_1],0 |
je @@FirstByte_1 |
cmp [MouseByteNumber_1],1 |
je @@SecondByte_1 |
cmp [MouseByteNumber_1],2 |
je @@ThirdByte_1 |
jmp @@Error_1 |
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ |
@@FirstByte_1: |
test AL,1000000b ;Ïåðâûé áàéò ïîñûëêè? |
jz @@Error_1 |
mov [FirstByte_1],AL |
inc [MouseByteNumber_1] ;óâåëè÷èòü ñ÷åò÷èê |
jmp @@EndMouseInterrupt_1 |
; Ñîõðàíèòü âòîðîé áàéò äàííûõ |
@@SecondByte_1: |
test AL,1000000b |
jnz @@Error_1 |
mov [SecondByte_1],AL |
inc [MouseByteNumber_1] ;óâåëè÷èòü ñ÷åò÷èê |
jmp @@EndMouseInterrupt_1 |
; Ñîõðàíèòü òðåòèé áàéò äàííûõ |
@@ThirdByte_1: |
test AL,1000000b |
jnz @@Error_1 |
mov [ThirdByte_1],AL ;óâåëè÷èòü ñ÷åò÷èê |
mov [MouseByteNumber_1],0 |
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ). |
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè |
mov al,[FirstByte_1] ;[0xfb01] |
mov ah,al |
shr al,3 |
and al,2 |
shr ah,5 |
and ah,1 |
add al,ah |
mov [0xfb40],al |
mov [mouse_active],1 |
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X |
mov AL,[FirstByte_1] |
shl AL,6 |
or AL,[SecondByte_1] |
cbw |
call mouse_acceleration_com2 |
add AX,[0xFB0A] ;[XCoordinate] |
; Êóðñîð íå äîëæåí âûõîäèòü çà ëåâóþ èëè |
; ïðàâóþ ãðàíèöó ýêðàíà |
js @@X1_1 |
cmp AX,[0xFE00] ;ScreenLength |
jb @@X2_1 |
; Óñòàíîâèòü êîîðäèíàòó X ïî ïðàâîé ãðàíèöå |
mov AX,[0xFE00] ;ScreenLength-1 |
dec ax |
jmp @@X2_1 |
@@X1_1: |
; Óñòàíîâèòü êîîðäèíàòó X ïî ëåâîé ãðàíèöå |
xor AX,AX |
@@X2_1: |
mov [0xFB0A],AX ;[XCoordinate] |
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y |
mov AL,[FirstByte_1] |
and AL,00001100b |
shl AL,4 |
or AL,[ThirdByte_1] |
cbw |
call mouse_acceleration_com2 |
add AX,[0xFB0C] ;[YCoordinate] |
; Êóðñîð íå äîëæåí âûõîäèòü çà âåðõíþþ èëè |
; íèæíþþ ãðàíèöó ýêðàíà |
js @@Y1_1 |
cmp AX,[0xFE04] ;ScreenHeigth |
jb @@Y2_1 |
; Óñòàíîâèòü êîîðäèíàòó X ïî íèæíåé ãðàíèöå |
mov AX,[0xFE04] ;ScreenHeigth-1 |
dec ax |
jmp @@Y2_1 |
@@Y1_1: |
; Óñòàíîâèòü êîîðäèíàòó X ïî âåðõíåé ãðàíèöå |
xor AX,AX |
@@Y2_1: |
mov [0xFB0C],AX ;[YCoordinate] |
mov eax,[timer_ticks] |
mov [timer_ticks_com_1],eax |
jmp @@EndMouseInterrupt_1 |
@@Error_1: |
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò |
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ |
mov [MouseByteNumber_1],0 |
@@EndMouseInterrupt_1: |
call ready_for_next_irq |
ret |
mouse_acceleration_com2: |
push eax |
mov eax,[timer_ticks] |
sub eax,[timer_ticks_com_1] |
cmp eax,[mouse_delay] |
pop eax |
ja @f |
shl ax,1 |
@@: |
ret |
/kernel/branches/gfx_kernel/hid/m_ps2.inc |
---|
0,0 → 1,170 |
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà |
MouseByteNumber_2 DB 0 |
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ |
FirstByte_2 DB 0 |
SecondByte_2 DB 0 |
ThirdByte_2 DB 0 |
timer_ticks_ps2 dd 0 |
;************************************** |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ PS/2 * |
;************************************** |
check_mouse_data_ps2: |
cmp [ps2_mouse_detected],0 |
je @@EndMouseInterrupt_2 |
call Wait8042BufferEmpty ;î÷èñòêà áóôåðà |
in AL,0x60 ;ïîëó÷èòü ñêýí-êîä |
; Âûáèðàòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà |
cmp [MouseByteNumber_2],0 |
je @@SaveFirstByte |
cmp [MouseByteNumber_2],1 |
je @@SaveSecondByte |
cmp [MouseByteNumber_2],2 |
je @@SaveThirdByte |
jmp @@Error_2 |
; Çàïèñàòü ïåðâûé áàéò ïîñûëêè |
@@SaveFirstByte: |
test AL,1000b ;ïåðâûé áàéò ïîñûëêè? |
jz @@Error_2 ;ñáîé ñèíõðîíèçàöèè |
mov [FirstByte_2],AL |
inc [MouseByteNumber_2] |
jmp @@EndMouseInterrupt_2 |
; Çàïèñàòü âòîðîé áàéò ïîñûëêè |
@@SaveSecondByte: |
mov [SecondByte_2],AL |
inc [MouseByteNumber_2] |
jmp @@EndMouseInterrupt_2 |
; Çàïèñàòü òðåòèé áàéò ïîñûëêè |
@@SaveThirdByte: |
mov [ThirdByte_2],AL |
mov [MouseByteNumber_2],0 |
; (ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ) |
; Çàïèñàòü íîâîå çíà÷åíèå áàéòà ñîñòîÿíèÿ êíîïîê |
mov al,[FirstByte_2] ;[0xfb01] |
and eax,3 |
mov [0xfb40],al |
mov [mouse_active],1 |
; Âû÷èñëèòü íîâóþ X-êîîðäèíàòó êóðñîðà |
; Çàíåñòè â AX ïåðåìåùåíèå ïî X |
mov AH,0 ;äóáëèðóåì çíàê âî âñå ðàçðÿäû AH |
mov AL,[FirstByte_2] |
test AL,10000b |
jz @@M0 |
mov AH,0FFh |
; Çàíåñòè â AL ìëàäøèé áàéò |
@@M0: |
mov AL,[SecondByte_2] |
call mouse_acceleration_ps2 |
; Âû÷èñëèòü íîâîå çíà÷åíèå êîîðäèíàòû |
; êóðñîðà ïî X |
add AX,[0xFB0A] ;[XCoordinate] |
cmp AX,0 |
jge @@M1 |
mov AX,0 |
jmp @@M2 |
@@M1: |
cmp AX,[0xFE00] ;ScreenLength |
jl @@M2 |
mov AX,[0xFE00] ;ScreenLength-1 |
dec ax |
@@M2: |
mov [0xFB0A],AX ;[XCoordinate] |
; Âû÷èñëÿåì íîâóþ Y-êîîðäèíàòó êóðñîðà |
; Çàíåñòè â AX ïåðåìåùåíèå ïî Y |
mov AH,0 ;äóáëèðóåì çíàê âî âñå ðàçðÿäû AH |
mov AL,[FirstByte_2] |
test AL,100000b |
jz @@M3 |
mov AH,0FFh |
; Çàíåñòè â AL ìëàäøèé áàéò |
@@M3: |
mov AL,[ThirdByte_2] |
call mouse_acceleration_ps2 |
; Âû÷èñëèòü íîâîå çíà÷åíèå êîîðäèíàòû êóðñîðà |
; ïî Y (Y-êîîðäèíàòà ìûøè PS/2 íàïðàâëåíà |
; ïðîòèâîïîëîæíî ýêðàííîé) |
neg AX |
add AX,[0xFB0C] ;[YCoordinate] |
cmp AX,0 |
jge @@M4 |
mov AX,0 |
jmp @@M5 |
@@M4: |
cmp AX,[0xFE04] ;ScreenHeigth |
jl @@M5 |
mov AX,[0xFE04] ;ScreenHeigth-1 |
dec ax |
@@M5: |
mov [0xFB0C],AX ;[YCoordinate] |
; Ïîêàçàòü êóðñîð â íîâîé ïîçèöèè |
mov eax,[timer_ticks] |
mov [timer_ticks_ps2],eax |
jmp @@EndMouseInterrupt_2 |
; Îáíàðóæåí ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò ìûøè |
@@Error_2: |
mov [MouseByteNumber_2],0 |
; Íîðìàëüíîå çàâåðøåíèå ïðåðûâàíèÿ |
@@EndMouseInterrupt_2: |
call ready_for_next_irq_1 |
ret |
mouse_acceleration_ps2: |
push eax |
mov eax,[timer_ticks] |
sub eax,[timer_ticks_ps2] |
cmp eax,[mouse_delay] |
pop eax |
ja @f |
imul ax,[mouse_speed_factor] |
@@: |
ret |
;*********************************************** |
;* ÎÆÈÄÀÍÈÅ Î×ÈÑÒÊÈ ÂÕÎÄÍÎÃÎ ÁÓÔÅÐÀ I8042 * |
;* Ïðè âûõîäå èç ïðîöåäóðû: * |
;* ôëàã ZF óñòàíîâëåí - íîðìàëüíîå çàâåðøåíèå, * |
;* ôëàã ZF ñáðîøåí - îøèáêà òàéì-àóòà. * |
;*********************************************** |
Wait8042BufferEmpty: |
; push CX |
; mov CX,0FFFFh ;çàäàòü ÷èñëî öèêëîâ îæèäàíèÿ |
;@@kb: |
; in AL,64h ;ïîëó÷èòü ñòàòóñ |
; test AL,10b ;áóôåð i8042 ñâîáîäåí? |
; loopnz @@kb ;åñëè íåò, òî öèêë |
; pop CX |
push ecx |
xor ecx,ecx |
@@: |
in al,64h |
test al,00000010b |
loopnz @b |
pop ecx |
;Åñëè ïðè âûõîäå èç ïîäïðîãðàììû ñáðîøåí |
;ôëàã ZF - îøèáêà |
ret ;âîçâðàò â ïîäïðîãðàììó |
;*************************************** |
;* ÎÆÈÄÀÍÈÅ ÏÎÑÒÓÏËÅÍÈß ÄÀÍÍÛÕ ÎÒ ÌÛØÈ * |
;*************************************** |
WaitMouseData: |
; push CX |
; mov CX,0FFFFh ;çàäàòü ÷èñëî öèêëîâ îæèäàíèÿ |
;@@mouse: |
; in AL,64h ;îïðîñèòü ðåãèñòð ñòàòóñà |
; test AL,100000b ;äàííûå ïîñòóïèëè? |
; loopz @@mouse ;åñëè íåò, òî öèêë |
; pop CX |
push ecx |
mov ECX,0FFFFh |
@@: |
in al,64h |
test al,100000b |
loopz @b |
pop ecx |
;Åñëè ïðè âûõîäå èç ïîäïðîãðàììû óñòàíîâëåí |
;ôëàã ZF - îøèáêà |
ret |
/kernel/branches/gfx_kernel/hid/mousedrv.inc |
---|
0,0 → 1,366 |
; check mouse |
; |
; |
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y |
; FB10 -> FB17 mouse color mem |
; FB21 x move |
; FB22 y move |
; FB30 color temp |
; FB28 high bits temp |
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under |
; FC00 -> FCFE com1/ps2 buffer |
; FCFF com1/ps2 buffer count starting from FC00 |
uglobal |
mousecount dd 0x0 |
mousedata dd 0x0 |
endg |
mouse_delay dd 10 |
mouse_speed_factor dw 3 |
include 'm_ps2.inc' |
include 'm_com1.inc' |
include 'm_com2.inc' |
;test_mario79: |
; push esi |
; push eax |
; mov [write_error_to],process_test_m79+43 |
; movzx eax,al ;[DevErrorCode] |
; call writehex |
; mov esi,process_test_m79 |
; call sys_msg_board_str |
; pop eax |
; pop esi |
; ret |
;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0 |
__sys_draw_mouse_under: |
; return old picture |
pushad |
xor ecx,ecx |
xor edx,edx |
mov esi,mouseunder-4 |
align 4 |
mres: |
add esi,4 |
movsx eax,word[0xfb4a] |
add eax,ecx |
js .skip |
movsx ebx,word[0xfb4c] |
add ebx,edx |
js .skip |
push ecx |
push edx |
mov ecx,[esi] |
mov edi,1 ;force |
push esi |
call [putpixel] |
pop esi |
pop edx |
pop ecx |
.skip: |
inc ecx |
cmp ecx,32 |
jnz mres |
xor ecx, ecx |
inc edx |
cmp edx,32 |
jnz mres |
popad |
ret |
save_draw_mouse: |
pushad |
; save & draw |
mov [0xfb4a],ax |
mov [0xfb4c],bx |
push eax |
push ebx |
xor ecx,ecx |
mov edx,ecx |
mov esi,mouseunder-4;3 |
mov edi,mousepointer+62-4 |
mov dword[0x6900],mouseunder+mousecomb |
drm: |
add esi,4;3 |
add edi,4 |
push eax ebx ecx edx |
push eax ebx |
add eax,ecx ; save picture under mouse |
js @f |
add ebx,edx |
js @f |
push esi edi |
call [getpixel] |
pop edi esi |
mov [esi],ecx |
pop ebx eax |
push esi edi |
call combine_colors |
pop edi esi |
mov [0xfb10],ecx |
pop edx ecx ebx eax |
xchg esi,[0x6900] |
push dword[0xFB10] |
pop dword[esi] |
add esi,3 |
xchg esi,[0x6900] |
jc mnext |
add eax,ecx ; we have x coord+cycle |
js mnext |
add ebx,edx ; and y coord+cycle |
js mnext |
push ecx edi esi |
mov ecx, [0xfb10] |
mov edi, 1 |
call [putpixel] |
pop esi edi ecx |
jmp mnext |
@@: add esp,8 |
pop edx ecx ebx eax |
mnext: |
mov ebx,[esp+0] ; pure y coord again |
mov eax,[esp+4] ; and x |
inc ecx ; +1 cycle |
cmp ecx,32 |
jnz drm |
xor ecx,ecx |
inc edx |
cmp edx,32 |
jnz drm |
pop ebx |
pop eax |
popad |
ret |
combine_colors: |
; in |
; ecx - color ( 00 RR GG BB ) |
; edi - ref to new color byte |
; esi - ref to alpha byte |
; |
; out |
; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) ) |
; colors: |
; [esp] = background: |
; [edi] = cursor |
; <ecx> = combined |
cmp byte[edi+3],0 |
jne @f |
stc |
ret |
@@: |
cmp byte[edi+3],255 |
jne @f |
mov ecx,[edi] |
and ecx,0x00FFFFFF |
clc |
ret |
@@: |
push ecx |
xor ecx,ecx |
movzx eax,byte[edi+2] |
movzx ebx,byte[esp+2] |
sub eax,ebx |
movzx ebx,byte[edi+3] |
imul ebx |
xor edx,edx |
mov ebx,255 |
div ebx |
add al,[esp+2] |
mov cl,al |
shl ecx,8 |
movzx eax,byte[edi+1] |
movzx ebx,byte[esp+1] |
sub eax,ebx |
movzx ebx,byte[edi+3] |
imul ebx |
xor edx,edx |
mov ebx,255 |
div ebx |
add al,[esp+1] |
mov cl,al |
shl ecx,8 |
movzx eax,byte[edi+0] |
movzx ebx,byte[esp+0] |
sub eax,ebx |
movzx ebx,byte[edi+3] |
imul ebx |
xor edx,edx |
mov ebx,255 |
div ebx |
add al,[esp+0] |
mov cl,al |
add esp,4 |
clc |
ret |
__sys_disable_mouse: |
cmp dword [0xf204],dword 0 |
je @f |
ret |
@@: |
pushad |
cmp [0x3000],dword 1 |
je disable_m |
mov edx,[0x3000] |
shl edx,5 |
add edx,window_data |
movzx eax,word[0xfb0a] |
movzx ecx,word[mousepointer+10] |
sub eax,ecx |
movzx ebx,word[0xfb0c] |
movzx ecx,word[mousepointer+12] |
sub ebx,ecx |
mov ecx,[0xfe00] |
imul ecx,ebx |
add ecx,eax |
add ecx, display_data |
; mov eax, [0x3000] |
movzx eax, byte [edx+twdw+0xe] |
movzx ebx, byte [ecx] |
cmp eax,ebx |
je yes_mouse_disable |
movzx ebx, byte [ecx+32] |
cmp eax,ebx |
je yes_mouse_disable |
mov ebx,[0xfe00] |
inc ebx |
imul ebx,32 |
add ecx,ebx |
movzx ebx, byte [ecx] |
cmp eax,ebx |
je yes_mouse_disable |
movzx ebx, byte [ecx+32] |
cmp eax,ebx |
je yes_mouse_disable |
jmp no_mouse_disable |
yes_mouse_disable: |
mov edx,[0x3000] |
shl edx,5 |
add edx,window_data |
movzx eax, word [0xfb0a] |
movzx ebx, word [0xfb0c] |
movzx ecx,word[mousepointer+10] |
sub eax,ecx |
movzx ecx,word[mousepointer+12] |
sub ebx,ecx |
mov ecx,[edx+0] ; mouse inside the area ? |
add eax,32 |
cmp eax,ecx |
jl no_mouse_disable |
sub eax,32 |
add ecx,[edx+8] |
cmp eax,ecx |
jg no_mouse_disable |
mov ecx,[edx+4] |
add ebx,32 |
cmp ebx,ecx |
jl no_mouse_disable |
sub ebx,32 |
add ecx,[edx+12] |
cmp ebx,ecx |
jg no_mouse_disable |
disable_m: |
cmp dword [0xf204],dword 0 |
jne no_mouse_disable |
cli |
call [draw_mouse_under] |
sti |
mov [0xf204],dword 1 |
no_mouse_disable: |
popad |
ret |
__sys_draw_pointer: |
cmp [mouse_pause],0 |
je @f |
ret |
@@: |
push eax |
mov eax,[timer_ticks] |
sub eax,[MouseTickCounter] |
cmp eax,1 |
ja @f |
pop eax |
ret |
@@: |
mov eax,[timer_ticks] |
mov [MouseTickCounter],eax |
pop eax |
pushad |
cmp dword [0xf204],dword 0 ; mouse visible ? |
je chms00 |
mov [0xf204], dword 0 |
movzx ebx,word [0xfb0c] |
movzx eax,word [0xfb0a] |
movzx esi,word[mousepointer+10] |
sub eax,esi |
movzx esi,word[mousepointer+12] |
sub ebx,esi |
cli |
call save_draw_mouse |
sti |
nodmu2: |
popad |
ret |
chms00: |
movsx ecx,word[0xfb4a] |
movsx edx,word[0xfb4c] |
movzx ebx,word [0xfb0c] |
movzx eax,word [0xfb0a] |
movzx esi,word[mousepointer+10] |
sub eax,esi |
movzx esi,word[mousepointer+12] |
sub ebx,esi |
cmp eax,ecx |
jne redrawmouse |
cmp ebx,edx |
jne redrawmouse |
jmp nodmp |
redrawmouse: |
cli |
call [draw_mouse_under] |
call save_draw_mouse |
sti |
nodmp: |
popad |
ret |
/kernel/branches/gfx_kernel/hid/set_dtc.inc |
---|
0,0 → 1,191 |
;setting date,time,clock and alarm-clock |
;add sys_settime at servetable as for ex. 22 fcn: |
; 22 - SETTING DATE TIME, CLOCK AND ALARM-CLOCK |
; ebx =0 - set time ecx - 00SSMMHH |
; ebx =1 - set date ecx=00DDMMYY |
; ebx =2 - set day of week ecx- 1-7 |
; ebx =3 - set alarm-clock ecx - 00SSMMHH |
; out: 0 -Ok 1 -wrong format 2 -battery low |
sys_settime: |
mov ecx,eax |
cli |
mov al,0x0d |
out 0x70,al |
in al,0x71 |
bt ax,7 |
jnc bat_low |
cmp ecx,2 ;day of week |
jne nosetweek |
test ebx,ebx ;test day of week |
je wrongtime |
cmp ebx,7 |
ja wrongtime |
mov dx,0x70 |
call startstopclk |
dec edx |
mov al,6 |
out dx,al |
inc edx |
mov al,bl |
out dx,al |
jmp endsettime |
nosetweek: ;set date |
cmp ecx,1 |
jne nosetdate |
cmp bl,0x99 ;test year |
ja wrongtime |
shl ebx,4 |
cmp bl,0x90 |
ja wrongtime |
cmp bh,0x99 ;test month |
ja wrongtime |
shr ebx,4 |
test bh,bh |
je wrongtime |
cmp bh,0x12 |
ja wrongtime |
shl ebx,8 |
bswap ebx ;ebx=00YYMMDD |
test bl,bl ;test day |
je wrongtime |
shl ebx,4 |
cmp bl,0x90 |
ja wrongtime |
shr ebx,4 |
cmp bh,2 ;February |
jne testday |
cmp bl,0x29 |
ja wrongtime |
jmp setdate |
testday: |
cmp bh,8 |
jb testday1 ;Aug-Dec |
bt bx,8 |
jnc days31 |
jmp days30 |
testday1: |
bt bx,8 ;Jan-Jul ex.Feb |
jnc days30 |
days31: |
cmp bl,0x31 |
ja wrongtime |
jmp setdate |
days30: |
cmp bl,0x30 |
ja wrongtime |
setdate: |
mov dx,0x70 |
call startstopclk |
dec edx |
mov al,7 ;set days |
out dx,al |
inc edx |
mov al,bl |
out dx,al |
dec edx |
mov al,8 ;set months |
out dx,al |
inc edx |
mov al,bh |
out dx,al |
dec edx |
mov al,9 ;set years |
out dx,al |
inc edx |
shr ebx,8 |
mov al,bh |
out dx,al |
jmp endsettime |
nosetdate: ;set time or alarm-clock |
cmp ecx,3 |
ja wrongtime |
cmp bl,0x23 |
ja wrongtime |
cmp bh,0x59 |
ja wrongtime |
shl ebx,4 |
cmp bl,0x90 |
ja wrongtime |
cmp bh,0x92 |
ja wrongtime |
shl ebx,4 |
bswap ebx ;00HHMMSS |
cmp bl,0x59 |
ja wrongtime |
shl ebx,4 |
cmp bl,0x90 |
ja wrongtime |
shr ebx,4 |
mov dx,0x70 |
call startstopclk |
dec edx |
cmp ecx,3 |
je setalarm |
xor eax,eax ;al=0-set seconds |
out dx,al |
inc edx |
mov al,bl |
out dx,al |
dec edx |
mov al,2 ;set minutes |
out dx,al |
inc edx |
mov al,bh |
out dx,al |
dec edx |
mov al,4 ;set hours |
out dx,al |
inc edx |
shr ebx,8 |
mov al,bh |
out dx,al |
jmp endsettime |
setalarm: |
mov al,1 ;set seconds for al. |
out dx,al |
inc edx |
mov al,bl |
out dx,al |
dec edx |
mov al,3 ;set minutes for al. |
out dx,al |
inc edx |
mov al,bh |
out dx,al |
dec edx |
mov al,5 ;set hours for al. |
out dx,al |
inc edx |
shr ebx,8 |
mov al,bh |
out dx,al |
dec edx |
mov al,0x0b ;enable irq's |
out dx,al |
inc dx |
in al,dx |
bts ax,5 ;set bit 5 |
out dx,al |
endsettime: |
dec edx |
call startstopclk |
sti |
mov [esp+36],dword 0 |
ret |
bat_low: |
sti |
mov [esp+36],dword 2 |
ret |
wrongtime: |
sti |
mov [esp+36],dword 1 |
ret |
startstopclk: |
mov al,0x0b |
out dx,al |
inc dx |
in al,dx |
btc ax,7 |
out dx,al |
ret |
/kernel/branches/gfx_kernel/kernel.asm |
---|
0,0 → 1,5309 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Kolibri OS - based on source code Menuet OS, but not 100% compatible. |
;; |
;; See file COPYING or GNU.TXT for details with these additional details: |
;; - All code written in 32 bit x86 assembly language |
;; - No external code (eg. bios) at process execution time |
;; |
;; |
;; Compile with last version FASM |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include "kglobals.inc" |
include "lang.inc" |
WinMapAddress equ 0x460000 |
display_data = 0x460000 |
max_processes equ 255 |
window_data equ 0x0000 |
tss_data equ 0xD20000 |
;tss_step equ (128+2048) ; tss & i/o - 16384 ports, * 256=557056 |
tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 |
draw_data equ 0xC00000 |
sysint_stack_data equ 0xC03000 |
twdw equ (0x3000-window_data) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Included files: |
;; |
;; Kernel16.inc |
;; - Booteng.inc English text for bootup |
;; - Bootcode.inc Hardware setup |
;; - Pci16.inc PCI functions |
;; |
;; Kernel32.inc |
;; - Sys32.inc Process management |
;; - Shutdown.inc Shutdown and restart |
;; - Fat32.inc Read / write hd |
;; - Vesa12.inc Vesa 1.2 driver |
;; - Vesa20.inc Vesa 2.0 driver |
;; - Vga.inc VGA driver |
;; - Stack.inc Network interface |
;; - Mouse.inc Mouse pointer |
;; - Scincode.inc Window skinning |
;; - Pci32.inc PCI functions |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 16 BIT ENTRY FROM BOOTSECTOR ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
use16 |
org 0x0 |
jmp start_of_code |
; mike.dld { |
org $+0x10000 |
db 0 |
dd servetable-0x10000 |
draw_line dd __sys_draw_line |
disable_mouse dd __sys_disable_mouse |
draw_pointer dd __sys_draw_pointer |
draw_mouse_under dd __sys_draw_mouse_under |
drawbar dd __sys_drawbar.forced |
putpixel dd __sys_putpixel |
getpixel dd __sys_getpixel |
putimage dd __sys_putimage |
drawbackground dd __sys_drawbackground |
calculatescreen dd __sys_calculatescreen |
setscreen dd __sys_setscreen |
; } mike.dld |
version db 'Kolibri OS version 0.5.8.1 ',13,10,13,10,0 |
;dd endofcode-0x10000 |
;db 'Boot02' |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
include "boot/preboot.inc" |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
preboot_lfb db 0 |
preboot_bootlog db 0 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 16 BIT INCLUDED FILES ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include "kernel16.inc" |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SWITCH TO 32 BIT PROTECTED MODE ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
os_data = os_data_l-gdts ; GDTs |
os_code = os_code_l-gdts |
int_code equ int_code_l-gdts |
int_data equ int_data_l-gdts |
tss0sys equ tss0sys_l-gdts |
graph_data equ 3+graph_data_l-gdts |
tss0 equ tss0_l-gdts |
app_code equ 3+app_code_l-gdts |
app_data equ 3+app_data_l-gdts |
; CR0 Flags - Protected mode and Paging |
mov ecx,0x00000001 |
;and ebx,65535 |
;cmp ebx,00100000000000000b ; lfb -> paging |
;jb no_paging |
;mov ax,0x0000 |
;mov es,ax |
;mov al,[es:0x901E] |
;cmp al,1 |
;je no_paging |
;or ecx, 0x80000000 |
;no_paging: |
; Enabling 32 bit protected mode |
sidt [cs:old_ints_h-0x10000] |
cli ; disable all irqs |
cld |
mov al,255 ; mask all irqs |
out 0xa1,al |
out 0x21,al |
l.5: in al, 0x64 ; Enable A20 |
test al, 2 |
jnz l.5 |
mov al, 0xD1 |
out 0x64, al |
l.6: in al, 0x64 |
test al, 2 |
jnz l.6 |
mov al, 0xDF |
out 0x60, al |
lgdt [cs:gdts-0x10000] ; Load GDT |
mov eax, cr0 ; Turn on paging // protected mode |
or eax, ecx |
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled |
mov cr0, eax |
jmp $+2 |
org $+0x10000 |
mov ax,os_data ; Selector for os |
mov ds,ax |
mov es,ax |
mov fs,ax |
mov gs,ax |
mov ss,ax |
mov esp,0x3ec00 ; Set stack |
jmp pword os_code:B32 ; jmp to enable 32 bit mode |
use32 |
iglobal |
boot_memdetect db 'Determining amount of memory',0 |
boot_fonts db 'Fonts loaded',0 |
boot_tss db 'Setting TSSs',0 |
boot_cpuid db 'Reading CPUIDs',0 |
boot_devices db 'Detecting devices',0 |
boot_timer db 'Setting timer',0 |
boot_irqs db 'Reprogramming IRQs',0 |
boot_setmouse db 'Setting mouse',0 |
boot_windefs db 'Setting window defaults',0 |
boot_bgr db 'Calculating background',0 |
boot_resirqports db 'Reserving IRQs & ports',0 |
boot_setrports db 'Setting addresses for IRQs',0 |
boot_setostask db 'Setting OS task',0 |
boot_allirqs db 'Unmasking all IRQs',0 |
boot_tsc db 'Reading TSC',0 |
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 |
boot_pal_vga db 'Setting VGA 640x480 palette',0 |
boot_mtrr db 'Setting MTRR',0 |
boot_tasking db 'All set - press ESC to start',0 |
endg |
iglobal |
boot_y dd 10 |
endg |
boot_log: |
pushad |
mov edx,esi |
.bll3: inc edx |
cmp [edx],byte 0 |
jne .bll3 |
sub edx,esi |
mov eax,10*65536 |
mov ax,word [boot_y] |
add [boot_y],dword 10 |
mov ebx,0xffffff |
mov ecx,esi |
mov edi,1 |
call dtext |
mov [novesachecksum],1000 |
call checkVga_N13 |
cmp [preboot_blogesc],byte 1 |
je .bll2 |
cmp esi,boot_tasking |
jne .bll2 |
; begin ealex 04.08.05 |
; in al,0x61 |
; and al,01111111b |
; out 0x61,al |
; end ealex 04.08.05 |
.bll1: in al,0x60 ; wait for ESC key press |
cmp al,129 |
jne .bll1 |
.bll2: popad |
ret |
uglobal |
cpuid_0 dd 0,0,0,0 |
cpuid_1 dd 0,0,0,0 |
cpuid_2 dd 0,0,0,0 |
cpuid_3 dd 0,0,0,0 |
endg |
iglobal |
firstapp db 'LAUNCHER ' |
char db 'CHAR MT ' |
char2 db 'CHAR2 MT ' |
bootpath db '/KOLIBRI ' |
bootpath2 db 0 |
vmode db 'VMODE MDR' |
cur_file db 'ARROW CUR' |
vrr_m db 'VRR_M ' |
endg |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 32 BIT ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
B32: |
; CLEAR 0x280000-0xF00000 |
xor eax,eax |
mov edi,0x280000 |
mov ecx,(0x100000*0xF-0x280000) / 4 |
cld |
rep stosd |
; CLEAR 0x80000-0x90000 |
; xor eax,eax |
mov edi,0x80000 |
mov ecx,(0x90000-0x80000)/4 |
; cld |
rep stosd |
; CLEAR KERNEL UNDEFINED GLOBALS |
mov edi, endofcode |
mov ecx, (uglobals_size/4)+4 |
rep stosd |
; SAVE & CLEAR 0-0xffff |
mov esi,0x0000 |
mov edi,0x2F0000 |
mov ecx,0x10000 / 4 |
cld |
rep movsd |
xor eax,eax |
mov edi,0 |
mov ecx,0x10000 / 4 |
cld |
rep stosd |
; SAVE REAL MODE VARIABLES |
; --------------- APM --------------------- |
mov eax, [0x2f0000 + 0x9040] ; entry point |
mov dword[apm_entry], eax |
mov word [apm_entry + 4], apm_code_32 - gdts |
mov eax, [0x2f0000 + 0x9044] ; version & flags |
mov [apm_vf], eax |
; ----------------------------------------- |
; movzx eax,byte [0x2f0000+0x9010] ; mouse port |
; mov [0xF604],byte 1 ;al |
mov al,[0x2f0000+0x9000] ; bpp |
mov [0xFBF1],al |
movzx eax,word [0x2f0000+0x900A] ; X max |
; dec eax |
mov [0xfe00],eax |
mov [screen_workarea.right],eax |
movzx eax,word [0x2f0000+0x900C] ; Y max |
; dec eax |
mov [0xfe04],eax |
mov [screen_workarea.bottom],eax |
movzx eax,word [0x2f0000+0x9008] ; screen mode |
mov [0xFE0C],eax |
mov eax,[0x2f0000+0x9014] ; Vesa 1.2 bnk sw add |
mov [0xE030],eax |
mov [0xfe08],word 640*4 ; Bytes PerScanLine |
cmp [0xFE0C],word 0x13 ; 320x200 |
je @f |
cmp [0xFE0C],word 0x12 ; VGA 640x480 |
je @f |
mov ax,[0x2f0000+0x9001] ; for other modes |
mov [0xfe08],ax |
mov al,[0x2F0000+0x9034] ; vesa major version number (ascii) |
mov [0xE034],al |
mov al,[0x2F0000+0x9035] ; card vendor (intel=1, s3=2, other=3) |
mov [0xE035],al |
@@: |
; GRAPHICS ADDRESSES |
;mov eax,0x100000*8 ; LFB address |
;cmp [0xfe0c],word 0x13 |
;je no_d_lfb |
;cmp [0xfe0c],word 0x12 |
;je no_d_lfb |
;cmp [0x2f0000+0x901e],byte 1 |
;jne no_d_lfb |
mov byte [0x2f0000+0x901e],0x0 |
mov eax,[0x2f0000+0x9018] |
;no_d_lfb: |
mov [0xfe80],eax |
cmp [0xfe0c],word 0100000000000000b |
jge setvesa20 |
cmp [0xfe0c],word 0x13 |
je v20ga32 |
mov [0xe020],dword Vesa12_putpixel24 ; Vesa 1.2 |
mov [0xe024],dword Vesa12_getpixel24 |
cmp [0xfbf1],byte 24 |
jz ga24 |
mov [0xe020],dword Vesa12_putpixel32 |
mov [0xe024],dword Vesa12_getpixel32 |
ga24: |
jmp v20ga24 |
setvesa20: |
mov [0xe020],dword Vesa20_putpixel24 ; Vesa 2.0 |
mov [0xe024],dword Vesa20_getpixel24 |
cmp [0xfbf1],byte 24 |
jz v20ga24 |
v20ga32: |
mov [0xe020],dword Vesa20_putpixel32 |
mov [0xe024],dword Vesa20_getpixel32 |
v20ga24: |
cmp [0xfe0c],word 0x12 ; 16 C VGA 640x480 |
jne no_mode_0x12 |
mov [0xe020],dword VGA_putpixel |
mov [0xe024],dword Vesa20_getpixel32 |
no_mode_0x12: |
; MEMORY MODEL |
; mov [0xfe84],dword 0x100000*16 ; apps mem base address |
; movzx ecx,byte [0x2f0000+0x9030] |
; dec ecx |
; mov eax,16*0x100000 ; memory-16 |
; shl eax,cl |
; mov [0xfe8c],eax ; memory for use |
; cmp eax,16*0x100000 |
; jne no16mb |
; mov [0xfe84],dword 0xD80000 ; !!! 10 !!! |
; no16mb: |
; init: |
; 1) 0xFE84 - applications base |
; 2) 0xFE8C - total amount of memory |
xor edi, edi |
m_GMS_loop: |
add edi, 0x400000 |
mov eax, dword [edi] |
mov dword [edi], 'TEST' |
wbinvd |
cmp dword [edi], 'TEST' |
jne m_GMS_exit |
cmp dword [0], 'TEST' |
je m_GMS_exit |
mov dword [es:edi], eax |
jmp m_GMS_loop |
m_GMS_exit: |
mov [edi], eax |
; now edi contains the EXACT amount of memory |
mov eax, 0x100000*16 |
cmp edi, eax ;0x100000*16 |
jb $ ; less than 16 Mb |
mov dword [0xFE84], eax ;0x100000*16 |
cmp edi, eax ;0x100000*16 |
jne @f |
mov dword [0xFE84], 0xD80000 ; =0x100000*13.5 |
@@: |
mov dword [0xFE8C], edi |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'detect/disks.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
; CHECK EXTRA REGION |
; ENABLE PAGING |
mov eax,cr0 |
or eax,0x80000000 |
mov cr0,eax |
jmp $+2 |
call MEM_Init |
;add 0x800000-0xc00000 area |
cmp word [0xfe0c],0x13 |
jle .less_memory |
mov eax,0x800000 ;linear address |
mov ebx,0x400000 shr 12 ;size in pages (4Mb) |
mov ecx,0x800000 ;physical address |
jmp .end_first_block |
.less_memory: |
mov eax,0x980000 ;linear address |
mov ebx,0x280000 shr 12 ;size in pages (2.5Mb) |
mov ecx,0x980000 ;physical address |
.end_first_block: |
call MEM_Add_Heap ;nobody can lock mutex yet |
call create_general_page_table |
;add 0x1000000(0xd80000)-end_of_memory area |
mov eax,second_base_address |
mov ebx,[0xfe8c] |
mov ecx,[0xfe84] |
sub ebx,ecx |
shr ebx,12 |
add eax,ecx |
call MEM_Add_Heap |
;init physical memory manager. |
call Init_Physical_Memory_Manager |
mov dword [0xfe80],0x80000000 ;0x800000 |
;Set base of graphic segment to linear address of LFB |
mov eax,[0xfe80] ; set for gs |
mov [graph_data_l+2],ax |
shr eax,16 |
mov [graph_data_l+4],al |
mov [graph_data_l+7],ah |
; READ RAMDISK IMAGE FROM HD |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'boot/rdload.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
; mov [dma_hdd],1 |
; CALCULATE FAT CHAIN FOR RAMDISK |
call calculatefatchain |
; LOAD VMODE DRIVER |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeld.inc' |
mov ebx,6 |
call 0x00760100 |
;!!!!!!!!!!!!!!!!!!!!!!! |
; LOAD FONTS I and II |
mov [0x3000],dword 1 |
mov [0x3004],dword 1 |
mov [0x3010],dword 0x3020 |
mov eax,char |
mov esi,12 |
xor ebx,ebx |
mov ecx,2560;26000 |
mov edx,0x3F600;0x37000 |
call fileread |
mov eax,char2 |
mov esi,12 |
xor ebx,ebx |
mov ecx,2560;26000 |
mov edx,0x3EC00;0x30000 |
call fileread |
mov esi,boot_fonts |
call boot_log |
; PRINT AMOUNT OF MEMORY |
mov esi, boot_memdetect |
call boot_log |
movzx ecx, word [boot_y] |
or ecx, (10+29*6) shl 16 ; "Determining amount of memory" |
sub ecx, 10 |
mov edx, 0xFFFFFF |
mov ebx, [0xFE8C] |
shr ebx, 20 |
mov edi, 1 |
mov eax, 0x00040000 |
call display_number |
; CHECK EXTENDED REGION |
; mov dword [0x80000000],0x12345678 |
; cmp dword [0x80000000],0x12345678 |
; jz extended_region_found |
; mov esi,boot_ext_region |
; call boot_log |
; jmp $ |
;extended_region_found: |
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f |
mov esi,boot_irqs |
call boot_log |
call rerouteirqs |
mov esi,boot_tss |
call boot_log |
; BUILD SCHEDULER |
call build_scheduler ; sys32.inc |
; LOAD IDT |
lidt [cs:idtreg] |
; READ CPUID RESULT |
mov esi,boot_cpuid |
call boot_log |
pushfd ; get current flags |
pop eax |
mov ecx,eax |
xor eax,0x00200000 ; attempt to toggle ID bit |
push eax |
popfd |
pushfd ; get new EFLAGS |
pop eax |
push ecx ; restore original flags |
popfd |
and eax,0x00200000 ; if we couldn't toggle ID, |
and ecx,0x00200000 ; then this is i486 |
cmp eax,ecx |
jz nopentium |
; It's Pentium or later. Use CPUID |
mov edi,cpuid_0 |
mov esi,0 |
cpuid_new_read: |
mov eax,esi |
cpuid |
call cpuid_save |
add edi,4*4 |
cmp esi,3 |
jge cpuid_done |
cmp esi,[cpuid_0] |
jge cpuid_done |
inc esi |
jmp cpuid_new_read |
cpuid_save: |
mov [edi+00],eax |
mov [edi+04],ebx |
mov [edi+8],ecx |
mov [edi+12],edx |
ret |
cpuid_done: |
nopentium: |
; CR4 flags - enable fxsave / fxrstore |
; |
; finit |
; mov eax,1 |
; cpuid |
; test edx,1000000h |
; jz fail_fpu |
; mov eax,cr4 |
; or eax,200h ; Enable fxsave/fxstor |
; mov cr4,eax |
; fail_fpu: |
;The CPU to this moment should be already in PM, |
;and bit MP of the register cr0 should be installed in 1. |
finit ;reset of the FPU (finit, instead of fninit) |
fsetpm ;enable PM of the FPU |
finit ;reset the registers, contents which are still equal RM |
;Now FPU too in PM |
; DETECT DEVICES |
mov esi,boot_devices |
call boot_log |
call detect_devices |
; TIMER SET TO 1/100 S |
mov esi,boot_timer |
call boot_log |
mov al,0x34 ; set to 100Hz |
out 0x43,al |
mov al,0x9b ; lsb 1193180 / 1193 |
out 0x40,al |
mov al,0x2e ; msb |
out 0x40,al |
; SET MOUSE |
mov eax,cur_file |
mov esi,12 |
mov ebx,0 |
mov ecx,26000 |
mov edx,mousepointer |
call fileread |
mov esi,mousepointer+62+32*31*4 |
mov edi,mousepointer+62 |
mov ecx,16 |
.mpl_1: push ecx |
mov ecx,16 |
.mpl_2: pushd [esi] [esi+4] [edi] [edi+4] |
popd [esi+4] [esi] [edi+4] [edi] |
add esi,8 |
add edi,8 |
loop .mpl_2 |
sub esi,32*4*2 |
pop ecx |
loop .mpl_1 |
mov esi,boot_setmouse |
call boot_log |
call setmouse |
; SET PRELIMINARY WINDOW STACK AND POSITIONS |
mov esi,boot_windefs |
call boot_log |
call setwindowdefaults |
; SET BACKGROUND DEFAULTS |
mov esi,boot_bgr |
call boot_log |
call calculatebackground |
; RESERVE SYSTEM IRQ'S JA PORT'S |
mov esi,boot_resirqports |
call boot_log |
call reserve_irqs_ports |
; SET PORTS FOR IRQ HANDLERS |
mov esi,boot_setrports |
call boot_log |
call setirqreadports |
; SET UP OS TASK |
mov esi,boot_setostask |
call boot_log |
; name for OS/IDLE process |
mov dword [0x80000+256+APPDATA.app_name], dword 'OS/I' |
mov dword [0x80000+256+APPDATA.app_name+4], dword 'DLE ' |
; task list |
mov [0x3020+TASKDATA.wnd_number], 1 ; on screen number |
mov [0x3020+TASKDATA.pid], 1 ; process id number |
mov [0x3020+TASKDATA.mem_start], 0 ; process base address |
;---------------------- |
mov eax,[0xfe00] |
mov ebx,[0xfe04] |
xor ecx,ecx |
mov [0],ecx |
mov [4],ecx |
mov [8],eax |
mov [12],ebx |
mov [256+0],ecx |
mov [256+4],ecx |
mov [256+8],eax |
mov [256+12],ebx |
;---------------------- |
; set default flags & stacks |
mov [l.eflags],dword 0x11202 ; sti and resume |
mov [l.ss0], os_data |
; osloop - TSS |
mov eax,cr3 |
mov [l.cr3],eax |
mov [l.eip],osloop |
mov [l.esp],sysint_stack_data + 4096*2 ; uses slot 1 stack |
mov [l.cs],os_code |
mov [l.ss],os_data |
mov [l.ds],os_data |
mov [l.es],os_data |
mov [l.fs],os_data |
mov [l.gs],os_data |
; move tss to tss_data+tss_step |
mov esi,tss_sceleton |
mov edi,tss_data+tss_step |
mov ecx,120/4 |
cld |
rep movsd |
mov ax,tss0 |
ltr ax |
; READ TSC / SECOND |
mov esi,boot_tsc |
call boot_log |
call _rdtsc |
mov ecx,eax |
mov esi,250 ; wait 1/4 a second |
call delay_ms |
call _rdtsc |
sub eax,ecx |
shl eax,2 |
mov [0xf600],eax ; save tsc / sec |
; SET VARIABLES |
call set_variables |
; STACK AND FDC |
call stack_init |
call fdc_init |
; PALETTE FOR 320x200 and 640x480 16 col |
cmp [0xfe0c],word 0x12 |
jne no_pal_vga |
mov esi,boot_pal_vga |
call boot_log |
call paletteVGA |
no_pal_vga: |
cmp [0xfe0c],word 0x13 |
jne no_pal_ega |
mov esi,boot_pal_ega |
call boot_log |
call palette320x200 |
no_pal_ega: |
; LOAD DEFAULT SKIN |
mov esi,_skin_file_default |
mov edi,_skin_file |
movsd |
movsd |
movsd |
call load_skin |
; MTRR'S |
call enable_mtrr |
; LOAD FIRST APPLICATION |
mov [0x3000],dword 1 |
mov [0x3004],dword 1 |
cli |
mov al,[0x2f0000+0x9030] |
cmp al,1 |
jne no_load_vrr_m |
mov eax,vrr_m |
xor ebx,ebx ; no parameters |
xor edx,edx ; no flags |
call start_application_fl |
cmp eax,2 ; if vrr_m app found (PID=2) |
je first_app_found |
no_load_vrr_m: |
mov eax,firstapp |
xor ebx,ebx ; no parameters |
xor edx,edx ; no flags |
call start_application_fl |
cmp eax,2 ; continue if a process has been loaded |
je first_app_found |
mov eax, 0xDEADBEEF ; otherwise halt |
hlt |
first_app_found: |
cli |
;mov [0x3004],dword 2 |
mov [0x3000],dword 1 ; set OS task fisrt |
; SET KEYBOARD PARAMETERS |
mov al, 0xf6 ; reset keyboard, scan enabled |
call kb_write |
; wait until 8042 is ready |
; xor ecx,ecx |
; @@: |
; in al,64h |
; and al,00000010b |
; loopnz @b |
call Wait8042BufferEmpty |
; mov al, 0xED ; svetodiody - only for testing! |
; call kb_write |
; call kb_read |
; mov al, 111b |
; call kb_write |
; call kb_read |
mov al, 0xF3 ; set repeat rate & delay |
call kb_write |
call kb_read |
mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 |
call kb_write |
call kb_read |
;// mike.dld [ |
call set_lights |
;// mike.dld ] |
; START MULTITASKING |
mov esi,boot_tasking |
call boot_log |
mov [0xe000],byte 1 ; multitasking enabled |
; UNMASK ALL IRQ'S |
mov esi,boot_allirqs |
call boot_log |
cli ;guarantee forbidance of interrupts. |
mov al,0 ; unmask all irq's |
out 0xA1,al |
out 0x21,al |
mov ecx,32 |
ready_for_irqs: |
mov al,0x20 ; ready for irqs |
out 0x20,al |
out 0xa0,al |
loop ready_for_irqs ; flush the queue |
; mov [dma_hdd],1 |
sti |
jmp $ ; wait here for timer to take control |
; Fly :) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; MAIN OS LOOP START ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
osloop: |
call [draw_pointer] |
call checkbuttons |
call checkwindows |
; call check_window_move_request |
call checkmisc |
call checkVga_N13 |
call stack_handler |
call checkidle |
call check_fdd_motor_status |
jmp osloop |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; MAIN OS LOOP END ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
checkidle: |
pushad |
cmp [check_idle_semaphore],0 |
jne no_idle_state |
call change_task |
mov eax,[idlemem] |
mov ebx,[timer_ticks] ;[0xfdf0] |
cmp eax,ebx |
jnz idle_exit |
call _rdtsc |
mov ecx,eax |
idle_loop: |
hlt |
cmp [check_idle_semaphore],0 |
jne idle_loop_exit |
mov eax,[timer_ticks] ;[0xfdf0] |
cmp ebx,eax |
jz idle_loop |
idle_loop_exit: |
mov [idlemem],eax |
call _rdtsc |
sub eax,ecx |
mov ebx,[idleuse] |
add ebx,eax |
mov [idleuse],ebx |
popad |
ret |
idle_exit: |
mov ebx,[timer_ticks] ;[0xfdf0] |
mov [idlemem],ebx |
call change_task |
popad |
ret |
no_idle_state: |
dec [check_idle_semaphore] |
mov ebx,[timer_ticks] ;[0xfdf0] |
mov [idlemem],ebx |
call change_task |
popad |
ret |
uglobal |
idlemem dd 0x0 |
idleuse dd 0x0 |
idleusesec dd 0x0 |
check_idle_semaphore dd 0x0 |
endg |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; INCLUDED SYSTEM FILES ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include "kernel32.inc" |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; KERNEL FUNCTIONS ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
enable_mtrr: |
pushad |
cmp [0x2f0000+0x901c],byte 2 |
je no_mtrr |
mov eax,[0xFE0C] ; if no LFB then no MTRR |
test eax,0100000000000000b |
jz no_mtrr |
mov edx,[cpuid_1+3*4] ; edx - MTRR's supported ? |
test edx,1000000000000b |
jz no_mtrr |
call find_empty_mtrr |
cmp ecx,0 |
jz no_mtrr |
mov esi,boot_mtrr ; 'setting mtrr' |
call boot_log |
mov edx,0x0 ; LFB , +8 M , write combine |
mov eax,[0x2f9018] |
or eax,1 |
wrmsr |
inc ecx |
mov edx,0xf |
mov eax,0xff800800 |
wrmsr |
mov ecx,0x2ff ; enable mtrr's |
rdmsr |
or eax,100000000000b ; set |
wrmsr |
no_mtrr: |
popad |
ret |
find_empty_mtrr: ; 8 pairs checked |
mov ecx,0x201-2 |
mtrr_find: |
add ecx,2 |
cmp ecx,0x200+8*2 |
jge no_free_mtrr |
rdmsr |
test eax,0x0800 |
jnz mtrr_find |
dec ecx |
ret |
no_free_mtrr: |
mov ecx,0 |
ret |
reserve_irqs_ports: |
pushad |
mov [irq_owner+4*0],byte 1 ; timer |
mov [irq_owner+4*1],byte 1 ; keyboard |
mov [irq_owner+4*5],byte 1 ; sound blaster |
mov [irq_owner+4*6],byte 1 ; floppy diskette |
mov [irq_owner+4*13],byte 1 ; math co-pros |
mov [irq_owner+4*14],byte 1 ; ide I |
mov [irq_owner+4*15],byte 1 ; ide II |
; movzx eax,byte [0xf604] ; mouse irq |
; dec eax |
; add eax,mouseirqtable |
; movzx eax,byte [eax] |
; shl eax,2 |
; mov [irq_owner+eax],byte 1 |
; RESERVE PORTS |
mov edi,1 ; 0x00-0xff |
mov [0x2d0000],edi |
shl edi,4 |
mov [0x2d0000+edi+0],dword 1 |
mov [0x2d0000+edi+4],dword 0x0 |
mov [0x2d0000+edi+8],dword 0xff |
; cmp [0xf604],byte 2 ; com1 mouse -> 0x3f0-0x3ff |
; jne ripl1 |
; inc dword [0x2d0000] |
; mov edi,[0x2d0000] |
; shl edi,4 |
; mov [0x2d0000+edi+0],dword 1 |
; mov [0x2d0000+edi+4],dword 0x3f0 |
; mov [0x2d0000+edi+8],dword 0x3ff |
; ripl1: |
; cmp [0xf604],byte 3 ; com2 mouse -> 0x2f0-0x2ff |
; jne ripl2 |
; inc dword [0x2d0000] |
; mov edi,[0x2d0000] |
; shl edi,4 |
; mov [0x2d0000+edi+0],dword 1 |
; mov [0x2d0000+edi+4],dword 0x2f0 |
; mov [0x2d0000+edi+8],dword 0x2ff |
; ripl2: |
popad |
ret |
iglobal |
mouseirqtable db 12 ; ps2 |
db 4 ; com1 |
db 3 ; com2 |
endg |
setirqreadports: |
mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte |
mov [irq12read+4],dword 0 ; end of port list |
mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte |
mov [irq04read+4],dword 0 ; end of port list |
mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte |
mov [irq03read+4],dword 0 ; end of port list |
ret |
iglobal |
process_number dd 0x1 |
endg |
set_variables: |
mov ecx,0x100 ; flush port 0x60 |
.fl60: in al,0x60 |
loop .fl60 |
mov [0xfcff],byte 0 ; mouse buffer |
mov [0xf400],byte 0 ; keyboard buffer |
mov [0xf500],byte 0 ; button buffer |
; mov [0xfb0a],dword 100*65536+100 ; mouse x/y |
push eax |
mov ax,[0x2f0000+0x900c] |
shr ax,1 |
shl eax,16 |
mov ax,[0x2f0000+0x900A] |
shr ax,1 |
mov [0xfb0a],eax |
pop eax |
mov byte [SB16_Status],0 ; Minazzi Paolo |
mov [display_data-12],dword 1 ; tiled background |
mov [0xfe88],dword 0x2C0000 ; address of button list |
;!! IP 04.02.2005: |
mov [next_usage_update], 100 |
mov byte [0xFFFF], 0 ; change task if possible |
ret |
;* mouse centered - start code- Mario79 |
mouse_centered: |
push eax |
mov eax,[0xFE00] |
shr eax,1 |
mov [0xFB0A],ax |
mov eax,[0xFE04] |
shr eax,1 |
mov [0xFB0C],ax |
pop eax |
ret |
;* mouse centered - end code- Mario79 |
align 4 |
sys_outport: |
mov edi,ebx ; separate flag for read / write |
and ebx,65535 |
mov ecx,[0x2d0000] |
test ecx,ecx |
jne sopl8 |
mov [esp+36],dword 1 |
ret |
sopl8: |
mov edx,[0x3010] |
mov edx,[edx+0x4] |
and ebx,65535 |
cld |
sopl1: |
mov esi,ecx |
shl esi,4 |
add esi,0x2d0000 |
cmp edx,[esi+0] |
jne sopl2 |
cmp ebx,[esi+4] |
jb sopl2 |
cmp ebx,[esi+8] |
jg sopl2 |
jmp sopl3 |
sopl2: |
dec ecx |
jnz sopl1 |
mov [esp+36],dword 1 |
ret |
sopl3: |
test edi,0x80000000 ; read ? |
jnz sopl4 |
mov dx,bx ; write |
out dx,al |
mov [esp+36],dword 0 |
ret |
sopl4: |
mov dx,bx ; read |
in al,dx |
and eax,0xff |
mov [esp+36],dword 0 |
mov [esp+24],eax |
ret |
align 4 |
sys_sb16: |
cmp word [sb16],word 0 |
jnz sb16l1 |
mov [esp+36],dword 1 |
ret |
sb16l1: |
mov [esp+36],dword 0 |
cmp eax,1 ; set volume - main |
jnz sb16l2 |
mov dx,word [sb16] |
add dx,4 |
mov al,0x22 |
out dx,al |
mov esi,1 |
call delay_ms |
mov eax,ebx |
inc edx |
out dx,al |
ret |
sb16l2: |
cmp eax,2 ; set volume - cd |
jnz sb16l3 |
mov dx,word [sb16] |
add dx,4 |
mov al,0x28 |
out dx,al |
mov esi,1 |
call delay_ms |
mov eax,ebx |
add edx,1 |
out dx,al |
ret |
sb16l3: |
mov [esp+36],dword 2 |
ret |
align 4 |
sys_sb16II: |
cmp word [sb16],word 0 |
jnz IIsb16l1 |
mov [esp+36],dword 1 |
ret |
IIsb16l1: |
cmp eax,1 ; set volume - main |
jnz IIsb16l2 |
; L |
mov dx,word [sb16] |
add dx,4 |
mov al,0x30 |
out dx,al |
mov eax,ebx |
inc edx |
out dx,al |
; R |
mov dx,word [sb16] |
add dx,4 |
mov al,0x31 |
out dx,al |
mov eax,ebx |
inc edx |
out dx,al |
mov [esp+36],dword 0 |
ret |
IIsb16l2: |
cmp eax,2 ; set volume - cd |
jnz IIsb16l3 |
; L |
mov dx,word [sb16] |
add dx,4 |
mov al,0x36 |
out dx,al |
mov eax,ebx |
inc edx |
out dx,al |
; R |
mov dx,word [sb16] |
add dx,4 |
mov al,0x37 |
out dx,al |
mov eax,ebx |
inc edx |
out dx,al |
mov [esp+36],dword 0 |
ret |
IIsb16l3: |
mov [esp+36],dword 2 |
ret |
align 4 |
sys_wss: |
cmp word [wss],word 0 |
jnz wssl1 |
mov [esp+36],dword 1 |
ret |
wssl1: |
cmp eax,1 ; set volume - main |
jnz wssl2 |
mov [esp+36],dword 0 |
ret |
wssl2: |
cmp eax,2 ; set volume - cd |
jnz wssl3 |
; L |
mov dx,word [wss] |
add dx,4 |
mov al,0x2 |
out dx,al |
mov esi,1 |
call delay_ms |
mov eax,ebx |
inc edx |
out dx,al |
; R |
mov dx,word [wss] |
add dx,4 |
mov al,0x3 |
out dx,al |
mov esi,1 |
call delay_ms |
mov eax,ebx |
inc edx |
out dx,al |
mov [esp+36],dword 0 |
ret |
wssl3: |
mov [esp+36],dword 2 |
ret |
display_number: |
; eax = print type, al=0 -> ebx is number |
; al=1 -> ebx is pointer |
; ah=0 -> display decimal |
; ah=1 -> display hexadecimal |
; ah=2 -> display binary |
; eax bits 16-21 = number of digits to display (0-32) |
; eax bits 22-31 = reserved |
; |
; ebx = number or pointer |
; ecx = x shl 16 + y |
; edx = color |
cmp eax,0xffff ; length > 0 ? |
jge cont_displ |
ret |
cont_displ: |
cmp eax,61*0x10000 ; length <= 60 ? |
jb cont_displ2 |
ret |
cont_displ2: |
pushad |
cmp al,1 ; ecx is a pointer ? |
jne displnl1 |
mov edi,[0x3010] |
mov edi,[edi+TASKDATA.mem_start] |
mov ebx,[edi+ebx] |
displnl1: |
sub esp,64 |
cmp ah,0 ; DECIMAL |
jne no_display_desnum |
shr eax,16 |
and eax,0x3f |
push eax |
mov edi,esp |
add edi,4+64 |
mov ecx,eax |
mov eax,ebx |
mov ebx,10 |
d_desnum: |
xor edx,edx |
div ebx |
add dl,48 |
mov [edi],dl |
dec edi |
loop d_desnum |
pop eax |
call draw_num_text |
add esp,64 |
popad |
ret |
no_display_desnum: |
cmp ah,0x01 ; HEXADECIMAL |
jne no_display_hexnum |
shr eax,16 |
and eax,0x3f |
push eax |
mov edi,esp |
add edi,4+64 |
mov ecx,eax |
mov eax,ebx |
mov ebx,16 |
d_hexnum: |
xor edx,edx |
div ebx |
add edx,hexletters |
mov dl,[edx] |
mov [edi],dl |
dec edi |
loop d_hexnum |
pop eax |
call draw_num_text |
add esp,64 |
popad |
ret |
no_display_hexnum: |
cmp ah,0x02 ; BINARY |
jne no_display_binnum |
shr eax,16 |
and eax,0x3f |
push eax |
mov edi,esp |
add edi,4+64 |
mov ecx,eax |
mov eax,ebx |
mov ebx,2 |
d_binnum: |
xor edx,edx |
div ebx |
add dl,48 |
mov [edi],dl |
dec edi |
loop d_binnum |
pop eax |
call draw_num_text |
add esp,64 |
popad |
ret |
no_display_binnum: |
add esp,64 |
popad |
ret |
draw_num_text: |
; dtext |
; |
; eax x & y |
; ebx color |
; ecx start of text |
; edx length |
; edi 1 force |
mov edx,eax |
mov ecx,65 |
sub ecx,eax |
add ecx,esp |
add ecx,4 |
mov eax,[esp+64+32-8+4] |
mov ebx,[esp+64+32-12+4] |
push edx ; add window start x & y |
push ebx |
mov edx,[0x3010] |
mov ebx,[edx-twdw+WDATA.box.left] |
shl ebx,16 |
add ebx,[edx-twdw+WDATA.box.top] |
add eax,ebx |
pop ebx |
pop edx |
mov edi,0 |
call dtext |
ret |
read_string: |
; eax read_area |
; ebx color of letter |
; ecx color of background |
; edx number of letters to read |
; esi [x start]*65536 + [y_start] |
ret |
align 4 |
sys_setup: |
; 1=roland mpu midi base , base io address |
; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus |
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 4=sb16 base , base io address |
; 5=system language, 1eng 2fi 3ger 4rus |
; 6=wss base , base io address |
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 8=fat32 partition in hd |
; 9 |
; 10 = sound dma channel |
; 11 = enable lba read |
; 12 = enable pci access |
mov [esp+36],dword 0 |
cmp eax,1 ; MIDI |
jnz nsyse1 |
cmp ebx,0x100 |
jb nsyse1 |
mov edx,65535 |
cmp edx,ebx |
jb nsyse1 |
mov [midi_base],bx |
mov word [mididp],bx |
inc bx |
mov word [midisp],bx |
ret |
midi_base dw 0 |
nsyse1: |
cmp eax,2 ; KEYBOARD |
jnz nsyse2 |
cmp ebx,1 |
jnz kbnobase |
mov edi,[0x3010] |
add ecx,[edi+TASKDATA.mem_start] |
mov eax,ecx |
mov ebx,keymap |
mov ecx,128 |
call memmove |
ret |
kbnobase: |
cmp ebx,2 |
jnz kbnoshift |
mov edi,[0x3010] |
add ecx,[edi+TASKDATA.mem_start] |
mov eax,ecx |
mov ebx,keymap_shift |
mov ecx,128 |
call memmove |
ret |
kbnoshift: |
cmp ebx,3 |
jne kbnoalt |
mov edi,[0x3010] |
add ecx,[edi+TASKDATA.mem_start] |
mov eax,ecx |
mov ebx,keymap_alt |
mov ecx,128 |
call memmove |
ret |
kbnoalt: |
cmp ebx,9 |
jnz kbnocountry |
mov word [keyboard],cx |
ret |
kbnocountry: |
mov [esp+36],dword 1 |
ret |
nsyse2: |
cmp eax,3 ; CD |
jnz nsyse3 |
test ebx,ebx |
jz nosesl |
cmp ebx, 4 |
ja nosesl |
mov [cd_base],bl |
cmp ebx,1 |
jnz noprma |
mov [cdbase],0x1f0 |
mov [cdid],0xa0 |
noprma: |
cmp ebx,2 |
jnz noprsl |
mov [cdbase],0x1f0 |
mov [cdid],0xb0 |
noprsl: |
cmp ebx,3 |
jnz nosema |
mov [cdbase],0x170 |
mov [cdid],0xa0 |
nosema: |
cmp ebx,4 |
jnz nosesl |
mov [cdbase],0x170 |
mov [cdid],0xb0 |
nosesl: |
ret |
cd_base db 0 |
nsyse3: |
cmp eax,4 ; SB |
jnz nsyse4 |
cmp ebx,0x100 |
jb nsyse4 |
mov edx,65535 |
cmp edx,ebx |
jb nsyse4 |
mov word [sb16],bx |
ret |
nsyse4: |
cmp eax,5 ; SYSTEM LANGUAGE |
jnz nsyse5 |
mov [syslang],ebx |
ret |
nsyse5: |
cmp eax,6 ; WSS |
jnz nsyse6 |
cmp ebx,0x100 |
jb nsyse6 |
mov [wss],ebx |
ret |
wss_temp dd 0 |
nsyse6: |
cmp eax,7 ; HD BASE |
jne nsyse7 |
test ebx,ebx |
jz nosethd |
cmp ebx,4 |
ja nosethd |
mov [hd_base],bl |
cmp ebx,1 |
jnz noprmahd |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
; call set_FAT32_variables |
noprmahd: |
cmp ebx,2 |
jnz noprslhd |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
; call set_FAT32_variables |
noprslhd: |
cmp ebx,3 |
jnz nosemahd |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
; call set_FAT32_variables |
nosemahd: |
cmp ebx,4 |
jnz noseslhd |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
; call set_FAT32_variables |
noseslhd: |
mov [0xfe10],dword 0 |
call reserve_hd1 |
call clear_hd_cache |
mov [hd1_status],0 ; free |
nosethd: |
ret |
hd_base db 0 |
nsyse7: |
cmp eax,8 ; HD PARTITION |
jne nsyse8 |
mov [fat32part],ebx |
; call set_FAT32_variables |
call reserve_hd1 |
call clear_hd_cache |
pusha |
call choice_necessity_partition_1 |
popa |
mov [hd1_status],0 ; free |
ret |
nsyse8: |
cmp eax,10 ; SOUND DMA CHANNEL |
jne no_set_sound_dma |
cmp ebx,3 |
ja sys_setup_err |
mov [sound_dma],ebx |
ret |
no_set_sound_dma: |
cmp eax,11 ; ENABLE LBA READ |
jne no_set_lba_read |
and ebx,1 |
mov [lba_read_enabled],ebx |
ret |
no_set_lba_read: |
cmp eax,12 ; ENABLE PCI ACCESS |
jne no_set_pci_access |
and ebx,1 |
mov [pci_access_enabled],ebx |
ret |
no_set_pci_access: |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeint.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
sys_setup_err: |
mov [esp+36],dword -1 |
ret |
align 4 |
sys_getsetup: |
; 1=roland mpu midi base , base io address |
; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus |
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 4=sb16 base , base io address |
; 5=system language, 1eng 2fi 3ger 4rus |
; 6=wss base |
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave |
; 8=fat32 partition in hd |
; 9=get hs timer tic |
cmp eax,1 |
jne ngsyse1 |
movzx eax,[midi_base] |
mov [esp+36],eax |
ret |
ngsyse1: |
cmp eax,2 |
jne ngsyse2 |
cmp ebx,1 |
jnz kbnobaseret |
mov edi,[0x3010] |
add ecx,[edi+TASKDATA.mem_start] |
mov ebx,ecx |
mov eax,keymap |
mov ecx,128 |
call memmove |
ret |
kbnobaseret: |
cmp ebx,2 |
jnz kbnoshiftret |
mov edi,[0x3010] |
add ecx,[edi+TASKDATA.mem_start] |
mov ebx,ecx |
mov eax,keymap_shift |
mov ecx,128 |
call memmove |
ret |
kbnoshiftret: |
cmp ebx,3 |
jne kbnoaltret |
mov edi,[0x3010] |
add ecx,[edi+TASKDATA.mem_start] |
mov ebx,ecx |
mov eax,keymap_alt |
mov ecx,128 |
call memmove |
ret |
kbnoaltret: |
cmp ebx,9 |
jnz ngsyse2 |
movzx eax,word [keyboard] |
mov [esp+36],eax |
ret |
ngsyse2: |
cmp eax,3 |
jnz ngsyse3 |
movzx eax,[cd_base] |
mov [esp+36],eax |
ret |
ngsyse3: |
cmp eax,4 |
jne ngsyse4 |
mov eax,[sb16] |
mov [esp+36],eax |
ret |
ngsyse4: |
cmp eax,5 |
jnz ngsyse5 |
mov eax,[syslang] |
mov [esp+36],eax |
ret |
ngsyse5: |
cmp eax,6 |
jnz ngsyse6 |
mov eax,[wss] |
mov [esp+36],eax |
ret |
ngsyse6: |
cmp eax,7 |
jnz ngsyse7 |
movzx eax,[hd_base] |
mov [esp+36],eax |
ret |
ngsyse7: |
cmp eax,8 |
jnz ngsyse8 |
mov eax,[fat32part] |
mov [esp+36],eax |
ret |
ngsyse8: |
cmp eax,9 |
jne ngsyse9 |
mov eax,[timer_ticks] ;[0xfdf0] |
mov [esp+36],eax |
ret |
ngsyse9: |
cmp eax,10 |
jnz ngsyse10 |
mov eax,[sound_dma] |
mov [esp+36],eax |
ret |
ngsyse10: |
cmp eax,11 |
jnz ngsyse11 |
mov eax,[lba_read_enabled] |
mov [esp+36],eax |
ret |
ngsyse11: |
cmp eax,12 |
jnz ngsyse12 |
mov eax,[pci_access_enabled] |
mov [esp+36],eax |
ret |
ngsyse12: |
mov [esp+36],dword 1 |
ret |
align 4 |
readmousepos: |
; eax=0 screen relative |
; eax=1 window relative |
; eax=2 buttons pressed |
test eax,eax |
jnz nosr |
mov eax,[0xfb0a] |
shl eax,16 |
mov ax,[0xfb0c] |
mov [esp+36],eax |
ret |
nosr: |
cmp eax,1 |
jnz nowr |
mov eax,[0xfb0a] |
shl eax,16 |
mov ax,[0xfb0c] |
mov esi,[0x3010] |
mov bx, word [esi-twdw+WDATA.box.left] |
shl ebx,16 |
mov bx, word [esi-twdw+WDATA.box.top] |
sub eax,ebx |
mov [esp+36],eax |
ret |
nowr: |
cmp eax,2 |
jnz nomb |
movzx eax,byte [0xfb40] |
nomb: |
mov [esp+36],eax |
ret |
is_input: |
push edx |
mov dx,word [midisp] |
in al,dx |
and al,0x80 |
pop edx |
ret |
is_output: |
push edx |
mov dx,word [midisp] |
in al,dx |
and al,0x40 |
pop edx |
ret |
get_mpu_in: |
push edx |
mov dx,word [mididp] |
in al,dx |
pop edx |
ret |
put_mpu_out: |
push edx |
mov dx,word [mididp] |
out dx,al |
pop edx |
ret |
setuart: |
su1: |
call is_output |
cmp al,0 |
jnz su1 |
mov dx,word [midisp] |
mov al,0xff |
out dx,al |
su2: |
mov dx,word [midisp] |
mov al,0xff |
out dx,al |
call is_input |
cmp al,0 |
jnz su2 |
call get_mpu_in |
cmp al,0xfe |
jnz su2 |
su3: |
call is_output |
cmp al,0 |
jnz su3 |
mov dx,word [midisp] |
mov al,0x3f |
out dx,al |
ret |
align 4 |
sys_midi: |
cmp [mididp],0 |
jnz sm0 |
mov [esp+36],dword 1 |
ret |
sm0: |
cmp eax,1 |
mov [esp+36],dword 0 |
jnz smn1 |
call setuart |
ret |
smn1: |
cmp eax,2 |
jnz smn2 |
sm10: |
call get_mpu_in |
call is_output |
test al,al |
jnz sm10 |
mov al,bl |
call put_mpu_out |
ret |
smn2: |
ret |
detect_devices: |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'detect/commouse.inc' |
include 'detect/ps2mouse.inc' |
;include 'detect/dev_fd.inc' |
;include 'detect/dev_hdcd.inc' |
;include 'detect/sear_par.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
ret |
sys_end: |
mov eax,[0x3010] |
mov [eax+TASKDATA.state], 3 ; terminate this program |
waitterm: ; wait here for termination |
mov eax,5 |
call delay_hs |
jmp waitterm |
iglobal |
sys_system_table: |
dd sysfn_shutdown ; 1 = system shutdown |
dd sysfn_terminate ; 2 = terminate thread |
dd sysfn_activate ; 3 = activate window |
dd sysfn_getidletime ; 4 = get idle time |
dd sysfn_getcpuclock ; 5 = get cpu clock |
dd sysfn_saveramdisk ; 6 = save ramdisk |
dd sysfn_getactive ; 7 = get active window |
dd sysfn_sound_flag ; 8 = get/set sound_flag |
dd sysfn_shutdown_param ; 9 = shutdown with parameter |
dd sysfn_minimize ; 10 = minimize window |
dd sysfn_getdiskinfo ; 11 = get disk subsystem info |
dd sysfn_lastkey ; 12 = get last pressed key |
dd sysfn_getversion ; 13 = get kernel version |
dd sysfn_waitretrace ; 14 = wait retrace |
dd sysfn_centermouse ; 15 = center mouse cursor |
dd sysfn_getfreemem ; 16 = get free memory size |
dd sysfn_getallmem ; 17 = get total memory size |
dd sysfn_terminate2 ; 18 = terminate thread using PID |
; instead of slot |
dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration |
sysfn_num = ($ - sys_system_table)/4 |
endg |
sys_system: |
dec eax |
cmp eax, sysfn_num |
jae @f |
jmp dword [sys_system_table + eax*4] |
@@: |
ret |
sysfn_shutdown: ; 18.1 = BOOT |
mov [0x2f0000+0x9030],byte 0 |
for_shutdown_parameter: |
mov eax,[0x3004] |
add eax,2 |
mov [shutdown_processes],eax |
mov [0xFF00],al |
and dword [esp+36], 0 |
ret |
uglobal |
shutdown_processes: dd 0x0 |
endg |
sysfn_terminate: ; 18.2 = TERMINATE |
cmp ebx,2 |
jb noprocessterminate |
mov edx,[0x3004] |
cmp ebx,edx |
ja noprocessterminate |
mov eax,[0x3004] |
shl ebx,5 |
mov edx,[ebx+0x3000+TASKDATA.pid] |
add ebx,0x3000+TASKDATA.state |
cmp byte [ebx], 9 |
jz noprocessterminate |
;call MEM_Heap_Lock ;guarantee that process isn't working with heap |
mov [ebx],byte 3 ; clear possible i40's |
;call MEM_Heap_UnLock |
cmp edx,[application_table_status] ; clear app table stat |
jne noatsc |
mov [application_table_status],0 |
noatsc: |
noprocessterminate: |
ret |
sysfn_terminate2: |
;lock application_table_status mutex |
.table_status: |
cli |
cmp [application_table_status],0 |
je .stf |
sti |
call change_task |
jmp .table_status |
.stf: |
call set_application_table_status |
mov eax,ebx |
call pid_to_slot |
test eax,eax |
jz .not_found |
mov ebx,eax |
cli |
call sysfn_terminate |
mov [application_table_status],0 |
sti |
and dword [esp+36],0 |
ret |
.not_found: |
mov [application_table_status],0 |
or dword [esp+36],-1 |
ret |
sysfn_activate: ; 18.3 = ACTIVATE WINDOW |
cmp ebx,2 |
jb .nowindowactivate |
cmp ebx,[0x3004] |
ja .nowindowactivate |
mov [window_minimize], 2 ; restore window if minimized |
movzx esi, word [0xC000 + ebx*2] |
cmp esi, [0x3004] |
je .nowindowactivate ; already active |
mov edi, ebx |
shl edi, 5 |
add edi, window_data |
movzx esi, word [0xC000 + ebx * 2] |
lea esi, [0xC400 + esi * 2] |
call waredraw |
.nowindowactivate: |
ret |
sysfn_getidletime: ; 18.4 = GET IDLETIME |
mov eax,[idleusesec] |
mov [esp+36], eax |
ret |
sysfn_getcpuclock: ; 18.5 = GET TSC/SEC |
mov eax,[0xf600] |
mov [esp+36], eax |
ret |
; SAVE ramdisk to /hd/1/menuet.img |
;!!!!!!!!!!!!!!!!!!!!!!!! |
include 'blkdev/rdsave.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!! |
sysfn_getactive: ; 18.7 = get active window |
mov eax, [0x3004] |
movzx eax, word [0xC400 + eax*2] |
mov [esp+36],eax |
ret |
sysfn_sound_flag: ; 18.8 = get/set sound_flag |
cmp ebx,1 |
jne nogetsoundflag |
movzx eax,byte [sound_flag] ; get sound_flag |
mov [esp+36],eax |
ret |
nogetsoundflag: |
cmp ebx,2 |
jnz nosoundflag |
xor byte [sound_flag], 1 |
nosoundflag: |
ret |
sysfn_shutdown_param: ; 18.9 = system shutdown with param |
cmp ebx,1 |
jl exit_for_anyone |
cmp ebx,4 |
jg exit_for_anyone |
mov [0x2f0000+0x9030],bl |
jmp for_shutdown_parameter |
sysfn_minimize: ; 18.10 = minimize window |
mov [window_minimize],1 |
exit_for_anyone: |
ret |
sysfn_getdiskinfo: ; 18.11 = get disk info table |
cmp ebx,1 |
jnz full_table |
small_table: |
call for_all_tables |
mov ecx,10 |
cld |
rep movsb |
ret |
for_all_tables: |
mov edi,[0x3010] |
mov edi,[edi+TASKDATA.mem_start] |
add edi,ecx |
mov esi,0x40000 |
ret |
full_table: |
cmp ebx,2 |
jnz exit_for_anyone |
call for_all_tables |
mov ecx,16384 |
cld |
rep movsd |
ret |
sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) |
and dword [esp+36], 0 |
ret |
sysfn_getversion: ; 18.13 = get kernel ID and version |
mov edi,[0x3010] |
mov edi,[edi+TASKDATA.mem_start] |
add edi,ebx |
mov esi,version_inf |
mov ecx,version_end-version_inf |
cld |
rep movsb |
ret |
sysfn_waitretrace: ; 18.14 = sys wait retrace |
;wait retrace functions |
sys_wait_retrace: |
mov edx,0x3da |
WaitRetrace_loop: |
in al,dx |
test al,1000b |
jz WaitRetrace_loop |
mov [esp+36],dword 0 |
ret |
sysfn_centermouse: ; 18.15 = mouse centered |
call mouse_centered |
mov [esp+36],dword 0 |
ret |
sysfn_mouse_acceleration: ; 18.19 = set/get mouse features |
cmp ebx,0 ; get mouse speed factor |
jnz .set_mouse_acceleration |
xor eax,eax |
mov ax,[mouse_speed_factor] |
mov [esp+36],eax |
ret |
.set_mouse_acceleration: |
cmp ebx,1 ; set mouse speed factor |
jnz .get_mouse_delay |
mov [mouse_speed_factor],cx |
ret |
.get_mouse_delay: |
cmp ebx,2 ; get mouse delay |
jnz .set_mouse_delay |
mov eax,[mouse_delay] |
mov [esp+36],eax |
ret |
.set_mouse_delay: |
cmp ebx,3 ; set mouse delay |
jnz .set_pointer_position |
mov [mouse_delay],ecx |
ret |
.set_pointer_position: |
cmp ebx,4 ; set mouse pointer position |
jnz .end |
mov [0xFB0C],cx ;y |
ror ecx,16 |
mov [0xFB0A],cx ;x |
rol ecx,16 |
.end: |
ret |
sysfn_getfreemem: |
mov eax,[MEM_FreeSpace] |
shl eax,2 |
mov [esp+36],eax |
ret |
sysfn_getallmem: |
mov eax,[0xFE8C] |
shr eax,10 |
; mov eax,[MEM_AllSpace] |
; shl eax,2 |
mov [esp+36],eax |
ret |
uglobal |
;// mike.dld, 2006-29-01 [ |
screen_workarea RECT |
;// mike.dld, 2006-29-01 ] |
window_minimize db 0 |
sound_flag db 0 |
endg |
iglobal |
version_inf: |
db 0,5,8,1 ; version 0.5.8.1 |
db UID_KOLIBRI |
db 'Kolibri',0 |
version_end: |
endg |
UID_NONE=0 |
UID_MENUETOS=1 ;official |
UID_KOLIBRI=2 ;russian |
sys_cachetodiskette: |
; pushad |
; cmp eax,1 |
; jne no_write_all_of_ramdisk |
; call fdc_writeramdisk |
; popad |
; ret |
; no_write_all_of_ramdisk: |
; cmp eax,2 |
; jne no_write_part_of_ramdisk |
; call fdc_commitflush |
; popad |
; ret |
; no_write_part_of_ramdisk: |
; cmp eax,3 |
; jne no_set_fdc |
; call fdc_set |
; popad |
; ret |
; no_set_fdc: |
; cmp eax,4 |
; jne no_get_fdc |
; popad |
; call fdc_get |
; mov [esp+36],ecx |
; ret |
; no_get_fdc: |
; popad |
; ret |
cmp eax,1 |
jne no_floppy_a_save |
mov [flp_number],1 |
jmp save_image_on_floppy |
no_floppy_a_save: |
cmp eax,2 |
jne no_floppy_b_save |
mov [flp_number],2 |
save_image_on_floppy: |
call save_image |
mov [esp+36],dword 0 |
cmp [FDC_Status],0 |
je yes_floppy_save |
no_floppy_b_save: |
mov [esp+36],dword 1 |
yes_floppy_save: |
ret |
uglobal |
; bgrchanged dd 0x0 |
endg |
sys_background: |
cmp eax,1 ; BACKGROUND SIZE |
jnz nosb1 |
cmp ebx,0 |
je sbgrr |
cmp ecx,0 |
je sbgrr |
mov [display_data-8],ebx |
mov [display_data-4],ecx |
; mov [bgrchanged],1 |
sbgrr: |
ret |
nosb1: |
cmp eax,2 ; SET PIXEL |
jnz nosb2 |
mov edx,0x160000-16 |
cmp edx,ebx |
jbe nosb2 |
mov edx,[ebx] |
and edx,0xFF000000 ;255*256*256*256 |
and ecx,0x00FFFFFF ;255*256*256+255*256+255 |
add edx,ecx |
mov [ebx+0x300000],edx |
; mov [bgrchanged],1 |
ret |
nosb2: |
cmp eax,3 ; DRAW BACKGROUND |
jnz nosb3 |
draw_background_temp: |
; cmp [bgrchanged],1 ;0 |
; je nosb31 |
;draw_background_temp: |
; mov [bgrchanged],1 ;0 |
mov [0xfff0],byte 1 |
mov [background_defined], 1 |
nosb31: |
ret |
nosb3: |
cmp eax,4 ; TILED / STRETCHED |
jnz nosb4 |
cmp ebx,[display_data-12] |
je nosb41 |
mov [display_data-12],ebx |
; mov [bgrchanged],1 |
nosb41: |
ret |
nosb4: |
cmp eax,5 ; BLOCK MOVE TO BGR |
jnz nosb5 |
; bughere |
mov edi, [0x3010] |
add ebx, [edi+TASKDATA.mem_start] |
; mov esi, ebx |
; mov edi, ecx |
mov eax, ebx |
mov ebx, ecx |
add ecx, edx |
cmp ecx, 0x160000-16 |
ja .fin |
; add edi, 0x300000 |
add ebx, 0x300000 |
mov ecx, edx |
cmp ecx, 0x160000-16 |
ja .fin |
; mov [bgrchanged],1 |
; cld |
; rep movsb |
call memmove |
.fin: |
ret |
nosb5: |
ret |
align 4 |
sys_getbackground: |
cmp eax,1 ; SIZE |
jnz nogb1 |
mov eax,[display_data-8] |
shl eax,16 |
mov ax,[display_data-4] |
mov [esp+36],eax |
ret |
nogb1: |
cmp eax,2 ; PIXEL |
jnz nogb2 |
mov edx,0x160000-16 |
cmp edx,ebx |
jbe nogb2 |
mov eax, [ebx+0x300000] |
and eax, 0xFFFFFF |
mov [esp+36],eax |
ret |
nogb2: |
cmp eax,4 ; TILED / STRETCHED |
jnz nogb4 |
mov eax,[display_data-12] |
nogb4: |
mov [esp+36],eax |
ret |
align 4 |
sys_getkey: |
mov [esp+36],dword 1 |
; test main buffer |
mov ebx, [0x3000] ; TOP OF WINDOW STACK |
movzx ecx,word [0xC000 + ebx * 2] |
mov edx,[0x3004] |
cmp ecx,edx |
jne .finish |
cmp [0xf400],byte 0 |
je .finish |
movzx eax,byte [0xf401] |
shl eax,8 |
push eax |
dec byte [0xf400] |
and byte [0xf400],127 |
movzx ecx,byte [0xf400] |
add ecx,2 |
; mov esi,0xf402 |
; mov edi,0xf401 |
; cld |
; rep movsb |
mov eax, 0xF402 |
mov ebx, 0xF401 |
call memmove |
pop eax |
.ret_eax: |
mov [esp+36],eax |
ret |
.finish: |
; test hotkeys buffer |
mov ecx, hotkey_buffer |
@@: |
cmp [ecx], ebx |
jz .found |
add ecx, 8 |
cmp ecx, hotkey_buffer+120*8 |
jb @b |
ret |
.found: |
mov ax, [ecx+6] |
shl eax, 16 |
mov ah, [ecx+4] |
mov al, 2 |
and dword [ecx+4], 0 |
and dword [ecx], 0 |
jmp .ret_eax |
align 4 |
sys_getbutton: |
mov ebx, [0x3000] ; TOP OF WINDOW STACK |
mov [esp+36],dword 1 |
movzx ecx, word [0xC000 + ebx * 2] |
mov edx, [0x3004] ; less than 256 processes |
cmp ecx,edx |
jne .exit |
movzx eax,byte [0xf500] |
test eax,eax |
jz .exit |
mov eax,[0xf501] |
shl eax,8 |
mov [0xf500],byte 0 |
mov [esp+36],eax |
.exit: |
ret |
align 4 |
sys_cpuusage: |
; RETURN: |
; |
; +00 dword process cpu usage |
; +04 word position in windowing stack |
; +06 word windowing stack value at current position (cpu nro) |
; +10 12 bytes name |
; +22 dword start in mem |
; +26 dword used mem |
; +30 dword PID , process idenfification number |
; |
mov edi,[0x3010] ; eax = return area |
add eax,[edi + TASKDATA.mem_start] |
cmp ebx,-1 ; who am I ? |
jne no_who_am_i |
mov ebx,[0x3000] |
no_who_am_i: |
push eax ; return area |
push ebx ; process number |
push ebx |
push ebx |
push eax |
; return memory usage |
xor edx,edx |
mov eax,0x20 |
mul ebx |
add eax,0x3000+TASKDATA.cpu_usage |
mov ebx,eax |
pop eax |
mov ecx,[ebx] |
mov [eax],ecx |
pop ebx |
mov cx, [0xC000 + ebx * 2] |
mov [eax+4],cx |
mov cx, [0xC400 + ebx * 2] |
mov [eax+6],cx |
push eax |
mov eax,ebx |
shl eax,8 |
add eax,0x80000+APPDATA.app_name |
pop ebx |
add ebx,10 |
mov ecx,11 |
call memmove |
; memory usage |
xor eax,eax |
mov edx,0x100000*16 |
pop ecx ; get gdt of tss |
cmp ecx,1 |
je os_mem |
shl ecx,8 |
mov edx,[0x80000+ecx+APPDATA.mem_size] ;0x8c |
mov eax,std_application_base_address |
; eax run base -> edx used memory |
os_mem: |
dec edx |
mov [ebx+12],eax |
mov [ebx+16],edx |
; PID (+30) |
mov eax,[esp] |
shl eax,5 |
add eax,0x3000+TASKDATA.pid |
mov eax,[eax] |
mov [ebx+20],eax |
; window position and size |
mov esi,[esp] |
shl esi,5 |
add esi,window_data + WDATA.box |
mov edi,[esp+4] |
add edi,34 |
mov ecx,4 |
cld |
rep movsd |
; Process state (+50) |
mov eax,[esp] |
shl eax,5 |
add eax,0x3000+TASKDATA.state |
mov eax,[eax] |
mov [ebx+40],ax |
pop ebx |
pop eax |
; return number of processes |
mov eax,[0x3004] |
mov [esp+36],eax |
ret |
align 4 |
sys_clock: |
cli |
; Mikhail Lisovin xx Jan 2005 |
@@: mov al, 10 |
out 0x70, al |
in al, 0x71 |
test al, al |
jns @f |
mov esi, 1 |
call delay_ms |
jmp @b |
@@: |
; end Lisovin's fix |
xor al,al ; seconds |
out 0x70,al |
in al,0x71 |
movzx ecx,al |
mov al,02 ; minutes |
shl ecx,16 |
out 0x70,al |
in al,0x71 |
movzx edx,al |
mov al,04 ; hours |
shl edx,8 |
out 0x70,al |
in al,0x71 |
add ecx,edx |
movzx edx,al |
add ecx,edx |
sti |
mov [esp+36],ecx |
ret |
align 4 |
sys_date: |
cli |
@@: mov al, 10 |
out 0x70, al |
in al, 0x71 |
test al, al |
jns @f |
mov esi, 1 |
call delay_ms |
jmp @b |
@@: |
mov ch,0 |
mov al,7 ; date |
out 0x70,al |
in al,0x71 |
mov cl,al |
mov al,8 ; month |
shl ecx,16 |
out 0x70,al |
in al,0x71 |
mov ch,al |
mov al,9 ; year |
out 0x70,al |
in al,0x71 |
mov cl,al |
sti |
mov [esp+36],ecx |
ret |
; redraw status |
sys_redrawstat: |
cmp eax,1 |
jne no_widgets_away |
; buttons away |
mov ecx,[0x3000] |
sys_newba2: |
mov edi,[0xfe88] |
cmp [edi],dword 0 ; empty button list ? |
je end_of_buttons_away |
movzx ebx,word [edi] |
inc ebx |
mov eax,edi |
sys_newba: |
dec ebx |
jz end_of_buttons_away |
add eax,0x10 |
cmp cx,[eax] |
jnz sys_newba |
push eax ebx ecx |
mov ecx,ebx |
inc ecx |
shl ecx,4 |
mov ebx,eax |
add eax,0x10 |
call memmove |
dec dword [edi] |
pop ecx ebx eax |
jmp sys_newba2 |
end_of_buttons_away: |
ret |
no_widgets_away: |
cmp eax,2 |
jnz srl1 |
mov edx,[0x3010] ; return whole screen draw area for this app |
add edx,draw_data-0x3000 |
mov [edx+RECT.left], 0 |
mov [edx+RECT.top], 0 |
mov eax,[0xfe00] |
mov [edx+RECT.right],eax |
mov eax,[0xfe04] |
mov [edx+RECT.bottom],eax |
mov edi,[0x3010] |
mov [edi-twdw+WDATA.fl_wdrawn], 1 ; no new position & buttons from app |
call sys_window_mouse |
ret |
srl1: |
ret |
sys_drawwindow: |
mov edi,ecx |
shr edi,16+8 |
and edi,15 |
cmp edi,0 ; type I - original style |
jne nosyswI |
inc [mouse_pause] |
call [disable_mouse] |
call sys_set_window |
call [disable_mouse] |
call drawwindow_I |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswI: |
cmp edi,1 ; type II - only reserve area, no draw |
jne nosyswII |
inc [mouse_pause] |
call [disable_mouse] |
call sys_set_window |
call [disable_mouse] |
call sys_window_mouse |
dec [mouse_pause] |
call [draw_pointer] |
ret |
nosyswII: |
cmp edi,2 ; type III - new style |
jne nosyswIII |
inc [mouse_pause] |
call [disable_mouse] |
call sys_set_window |
call [disable_mouse] |
call drawwindow_III |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswIII: |
cmp edi,3 ; type IV - skinned window |
jne nosyswIV |
; parameter for drawwindow_IV |
push 0 |
mov edi, [0x3004] |
movzx edi, word [0xC400 + edi*2] |
cmp edi, [0x3000] |
jne @f |
inc dword [esp] |
@@: |
inc [mouse_pause] |
call [disable_mouse] |
call sys_set_window |
call [disable_mouse] |
call drawwindow_IV |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswIV: |
ret |
draw_window_caption: |
inc [mouse_pause] |
call [disable_mouse] |
xor eax,eax |
mov edx,[0x3004] |
movzx edx,word[0xC400+edx*2] |
cmp edx,[0x3000] |
jne @f |
inc eax |
@@: mov edx,[0x3000] |
shl edx,5 |
add edx,window_data |
movzx ebx,[edx+WDATA.fl_wstyle] |
and bl,0x0F |
cmp bl,3 |
jne .not_style_3 |
push edx |
call drawwindow_IV_caption |
add esp,4 |
jmp .2 |
.not_style_3: |
cmp bl,2 |
jne .not_style_2 |
call drawwindow_III_caption |
jmp .2 |
.not_style_2: |
cmp bl,0 |
jne .2 |
call drawwindow_I_caption |
;-------------------------------------------------------------- |
.2: ;jmp @f |
mov edi,[0x3000] |
shl edi,5 |
test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION |
jz @f |
mov ecx,[edi*8+0x80000+APPDATA.wnd_caption] |
or ecx,ecx |
jz @f |
add ecx,[edi+twdw+TASKDATA.mem_start] |
movzx eax,[edi+window_data+WDATA.fl_wstyle] |
and al,0x0F |
cmp al,3 |
jne .not_skinned |
mov ebp,[edi+window_data+WDATA.box.left-2] |
mov bp,word[edi+window_data+WDATA.box.top] |
movzx eax,word[edi+window_data+WDATA.box.width] |
sub ax,[_skinmargins.left] |
sub ax,[_skinmargins.right] |
cwde |
cdq |
mov ebx,6 |
idiv ebx |
or eax,eax |
js @f |
mov edx,eax |
mov eax,dword[_skinmargins.left-2] |
mov ax,word[_skinh] |
sub ax,[_skinmargins.bottom] |
sub ax,[_skinmargins.top] |
sar ax,1 |
adc ax,0 |
add ax,[_skinmargins.top] |
add ax,-3 |
add eax,ebp |
mov ebx,[common_colours+16];0x00FFFFFF |
xor edi,edi |
call dtext |
jmp @f |
.not_skinned: |
cmp al,1 |
je @f |
mov ebp,[edi+window_data+WDATA.box.left-2] |
mov bp,word[edi+window_data+WDATA.box.top] |
movzx eax,word[edi+window_data+WDATA.box.width] |
sub eax,16 |
cwde |
cdq |
mov ebx,6 |
idiv ebx |
or eax,eax |
js @f |
mov edx,eax |
mov eax,0x00080007 |
add eax,ebp |
mov ebx,[common_colours+16];0x00FFFFFF |
xor edi,edi |
call dtext |
jmp @f |
@@: |
;-------------------------------------------------------------- |
dec [mouse_pause] |
call [draw_pointer] |
ret |
iglobal |
align 4 |
window_topleft dd \ |
1, 21,\ |
0, 0,\ |
5, 20,\ |
5, ? |
endg |
set_window_clientbox: |
push eax ecx edi |
mov eax,[_skinh] |
mov [window_topleft+4*7],eax |
mov ecx,edi |
sub edi,window_data |
shl edi,3 |
test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE |
jz @f |
movzx eax,[ecx+WDATA.fl_wstyle] |
and eax,0x0F |
mov eax,[eax*8+window_topleft+0] |
mov [edi+0x80000+APPDATA.wnd_clientbox.left],eax |
shl eax,1 |
neg eax |
add eax,[ecx+WDATA.box.width] |
mov [edi+0x80000+APPDATA.wnd_clientbox.width],eax |
movzx eax,[ecx+WDATA.fl_wstyle] |
and eax,0x0F |
push [eax*8+window_topleft+0] |
mov eax,[eax*8+window_topleft+4] |
mov [edi+0x80000+APPDATA.wnd_clientbox.top],eax |
neg eax |
sub eax,[esp] |
add eax,[ecx+WDATA.box.height] |
mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax |
add esp,4 |
pop edi ecx eax |
ret |
@@: |
xor eax,eax |
mov [edi+0x80000+APPDATA.wnd_clientbox.left],eax |
mov [edi+0x80000+APPDATA.wnd_clientbox.top],eax |
mov eax,[ecx+WDATA.box.width] |
mov [edi+0x80000+APPDATA.wnd_clientbox.width],eax |
mov eax,[ecx+WDATA.box.height] |
mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax |
pop edi ecx eax |
ret |
sys_set_window: |
mov edi,[0x3000] |
shl edi,5 |
add edi,window_data |
; colors |
mov [edi+WDATA.cl_workarea],ecx |
mov [edi+WDATA.cl_titlebar],edx |
mov [edi+WDATA.cl_frames],esi |
call set_window_clientbox |
; check flag (?) |
cmp [edi+WDATA.fl_wdrawn],1 |
jz newd |
push eax |
mov eax,[timer_ticks] ;[0xfdf0] |
add eax,100 |
mov [new_window_starting],eax |
pop eax |
mov word[edi+WDATA.box.width],ax |
mov word[edi+WDATA.box.height],bx |
sar eax,16 |
sar ebx,16 |
mov word[edi+WDATA.box.left],ax |
mov word[edi+WDATA.box.top],bx |
call check_window_position |
push ecx esi edi ; save for window fullscreen/resize |
;mov esi,edi |
mov cl,[edi+WDATA.fl_wstyle] |
sub edi,window_data |
shl edi,3 |
add edi,0x80000 |
and cl,0x0F |
mov [edi+APPDATA.wnd_caption],0 |
cmp cl,3 |
jne @f |
mov [edi+APPDATA.wnd_caption],esi |
@@: mov esi,[esp+0] |
add edi, APPDATA.saved_box |
mov ecx,4 |
cld |
rep movsd |
pop edi esi ecx |
push eax ebx ecx edx |
;;; mov eax, 1 |
;;; call delay_hs |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, [edi+WDATA.box.width] |
mov edx, [edi+WDATA.box.height] |
add ecx, eax |
add edx, ebx |
call [calc_clipping_rects] |
pop edx ecx ebx eax |
mov [0xf400],byte 0 ; empty keyboard buffer |
mov [0xf500],byte 0 ; empty button buffer |
newd: |
mov [edi+WDATA.fl_redraw],byte 0 ; no redraw |
mov edx,edi |
ret |
syscall_windowsettings: |
.set_window_caption: |
dec eax ; subfunction #1 - set window caption |
jnz .get_window_caption |
; NOTE: only window owner thread can set its caption, |
; so there's no parameter for PID/TID |
mov edi,[0x3000] |
shl edi,5 |
; have to check if caption is within application memory limit |
; check is trivial, and if application resizes its memory, |
; caption still can become over bounds |
mov ecx,[edi*8+0x80000+APPDATA.mem_size] |
add ecx,255 ; max caption length |
cmp ebx,ecx |
ja .exit_fail |
mov [edi*8+0x80000+APPDATA.wnd_caption],ebx |
or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION |
call draw_window_caption |
xor eax,eax ; eax = 0 (success) |
ret |
.get_window_caption: |
dec eax ; subfunction #2 - get window caption |
jnz .exit_fail |
; not implemented yet |
.exit_fail: |
xor eax,eax |
inc eax ; eax = 1 (fail) |
ret |
sys_window_move: |
mov edi,[0x3000] |
shl edi,5 |
add edi,window_data |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz .window_move_return |
push dword [edi + WDATA.box.left] ; save old coordinates |
push dword [edi + WDATA.box.top] |
push dword [edi + WDATA.box.width] |
push dword [edi + WDATA.box.height] |
cmp eax,-1 ; set new position and size |
je .no_x_reposition |
mov [edi + WDATA.box.left], eax |
.no_x_reposition: |
cmp ebx,-1 |
je .no_y_reposition |
mov [edi + WDATA.box.top], ebx |
.no_y_reposition: |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz .no_y_resizing |
cmp ecx,-1 |
je .no_x_resizing |
mov [edi + WDATA.box.width], ecx |
.no_x_resizing: |
cmp edx,-1 |
je .no_y_resizing |
mov [edi + WDATA.box.height], edx |
.no_y_resizing: |
call check_window_position |
pushad ; save for window fullscreen/resize |
mov esi,edi |
sub edi,window_data |
shr edi,5 |
shl edi,8 |
add edi, 0x80000 + APPDATA.saved_box |
mov ecx,4 |
cld |
rep movsd |
popad |
pushad ; calculcate screen at new position |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
add ecx, eax |
add edx, ebx |
call [calculatescreen] |
popad |
pop edx ; calculcate screen at old position |
pop ecx |
pop ebx |
pop eax |
add ecx,eax |
add edx,ebx |
mov [dlx],eax ; save for drawlimits |
mov [dly],ebx |
mov [dlxe],ecx |
mov [dlye],edx |
call [calculatescreen] |
mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw |
mov eax,edi ; redraw screen at old position |
xor esi,esi |
call redrawscreen |
mov [0xfff5],byte 0 ; mouse pointer |
mov [0xfff4],byte 0 ; no mouse under |
mov [0xfb44],byte 0 ; react to mouse up/down |
mov ecx,10 ; wait 1/10 second |
.wmrl3: |
call [draw_pointer] |
mov eax,1 |
call delay_hs |
loop .wmrl3 |
mov [window_move_pr],0 |
.window_move_return: |
ret |
;type_background_1: |
; cmp [0xfff0],byte 0 ; background update ? |
; jz temp_nobackgr |
; mov [0xfff0],byte 2 |
; call change_task |
; mov [draw_data+32+0],dword 0 |
; mov [draw_data+32+4],dword 0 |
; mov eax,[0xfe00] |
; mov ebx,[0xfe04] |
; mov [draw_data+32+8],eax |
; mov [draw_data+32+12],ebx |
; call drawbackground |
; mov [0xfff0],byte 0 |
; mov [0xfff4],byte 0 |
;temp_nobackgr: |
; ret |
uglobal |
window_move_pr dd 0x0 |
window_move_eax dd 0x0 |
window_move_ebx dd 0x0 |
window_move_ecx dd 0x0 |
window_move_edx dd 0x0 |
endg |
;ok - 100% work |
;nt - not tested |
;--------------------------------------------------------------------------------------------- |
;eax |
;0 - task switch counter. Ret switch counter in eax. Block. ok. |
;1 - change task. Ret nothing. Block. ok. |
;2 - performance control |
; ebx |
; 0 - enable or disable (inversion) PCE flag on CR4 for rdmpc in user mode. |
; returned new cr4 in eax. Ret cr4 in eax. Block. ok. |
; 1 - is cache enabled. Ret cr0 in eax if enabled else zero in eax. Block. ok. |
; 2 - enable cache. Ret 1 in eax. Ret nothing. Block. ok. |
; 3 - disable cache. Ret 0 in eax. Ret nothing. Block. ok. |
;eax |
;3 - rdmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. |
;4 - wrmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. |
;--------------------------------------------------------------------------------------------- |
sys_sheduler: ;noname & halyavin |
cmp eax,0 |
je shed_counter |
cmp eax,2 |
je perf_control |
cmp eax,3 |
je rdmsr_instr |
cmp eax,4 |
je wrmsr_instr |
cmp eax,1 |
jne not_supported |
call change_task ;delay,0 |
ret |
shed_counter: |
mov eax,[context_counter] |
mov [esp+36],eax |
not_supported: |
ret |
perf_control: |
inc eax ;now eax=3 |
cmp ebx,eax |
je cache_disable |
dec eax |
cmp ebx,eax |
je cache_enable |
dec eax |
cmp ebx,eax |
je is_cache_enabled |
dec eax |
cmp ebx,eax |
je modify_pce |
ret |
rdmsr_instr: |
;now counter in ecx |
;(edx:eax) esi:edi => edx:esi |
mov eax,esi |
rdmsr |
mov [esp+36],eax |
mov [esp+24],edx ;ret in ebx? |
ret |
wrmsr_instr: |
;now counter in ecx |
;(edx:eax) esi:edi => edx:esi |
mov eax,esi |
wrmsr |
mov [esp+36],eax |
mov [esp+24],edx ;ret in ebx? |
ret |
cache_disable: |
mov eax,cr0 |
or eax,01100000000000000000000000000000b |
mov cr0,eax |
wbinvd ;set MESI |
ret |
cache_enable: |
mov eax,cr0 |
and eax,10011111111111111111111111111111b |
mov cr0,eax |
ret |
is_cache_enabled: |
mov eax,cr0 |
mov ebx,eax |
and eax,01100000000000000000000000000000b |
jz cache_disabled |
mov [esp+36],ebx |
cache_disabled: |
mov dword [esp+36],eax ;0 |
ret |
modify_pce: |
mov eax,cr4 |
; mov ebx,0 |
; or bx,100000000b ;pce |
; xor eax,ebx ;invert pce |
bts eax,8 ;pce=cr4[8] |
mov cr4,eax |
mov [esp+36],eax |
ret |
;--------------------------------------------------------------------------------------------- |
; check if pixel is allowed to be drawn |
checkpixel: |
push eax edx |
mov edx,[0xfe00] ; screen x size |
inc edx |
imul edx, ebx |
mov dl, [eax+edx+display_data] ; lea eax, [...] |
xor ecx, ecx |
mov eax, [0x3000] |
cmp al, dl |
setne cl |
pop edx eax |
ret |
uglobal |
mouse_active db 0 |
endg |
iglobal |
cpustring db 'CPU ' |
endg |
uglobal |
background_defined db 0 ; diamond, 11.04.2006 |
endg |
align 4 |
; check misc |
checkmisc: |
cmp [ctrl_alt_del], 1 |
jne nocpustart |
mov eax, cpustring |
xor ebx,ebx ; no parameters |
xor edx,edx ; no flags |
call start_application_fl |
mov [ctrl_alt_del], 0 |
nocpustart: |
cmp [mouse_active], 1 |
jne mouse_not_active |
mov [mouse_active], 0 |
xor edi, edi |
mov ecx, [0x3004] |
set_mouse_event: |
add edi, 256 |
or [edi+0x80000+APPDATA.event_mask], dword 00100000b |
loop set_mouse_event |
mouse_not_active: |
cmp [0xfff0],byte 0 ; background update ? |
jz nobackgr |
cmp [background_defined], 0 |
jz nobackgr |
mov [0xfff0],byte 2 |
call change_task |
mov [draw_data+32 + RECT.left],dword 0 |
mov [draw_data+32 + RECT.top],dword 0 |
mov eax,[0xfe00] |
mov ebx,[0xfe04] |
mov [draw_data+32 + RECT.right],eax |
mov [draw_data+32 + RECT.bottom],ebx |
call [drawbackground] |
mov [0xfff0],byte 0 |
mov [0xfff4],byte 0 |
nobackgr: |
; system shutdown request |
cmp [0xFF00],byte 0 |
je noshutdown |
mov edx,[shutdown_processes] |
sub dl,2 |
cmp [0xff00],dl |
jne no_mark_system_shutdown |
mov edx,0x3040 |
movzx ecx,byte [0xff00] |
add ecx,5 |
markz: |
mov [edx+TASKDATA.state],byte 3 |
add edx,0x20 |
loop markz |
no_mark_system_shutdown: |
call [disable_mouse] |
dec byte [0xff00] |
cmp [0xff00],byte 0 |
je system_shutdown |
noshutdown: |
mov eax,[0x3004] ; termination |
mov ebx,0x3020+TASKDATA.state |
mov esi,1 |
newct: |
mov cl,[ebx] |
cmp cl,byte 3 |
jz terminate |
cmp cl,byte 4 |
jz terminate |
add ebx,0x20 |
inc esi |
dec eax |
jnz newct |
ret |
; redraw screen |
redrawscreen: |
; eax , if process window_data base is eax, do not set flag/limits |
pushad |
push eax |
;;; mov eax,2 |
;;; call delay_hs |
;mov ecx,0 ; redraw flags for apps |
xor ecx,ecx |
newdw2: |
inc ecx |
push ecx |
mov eax,ecx |
shl eax,5 |
add eax,window_data |
cmp eax,[esp+4] |
je not_this_task |
; check if window in redraw area |
mov edi,eax |
cmp ecx,1 ; limit for background |
jz bgli |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
add ecx, eax |
add edx, ebx |
mov ecx,[dlye] ; ecx = area y end ebx = window y start |
cmp ecx,ebx |
jl ricino |
mov ecx,[dlxe] ; ecx = area x end eax = window x start |
cmp ecx,eax |
jl ricino |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
add ecx, eax |
add edx, ebx |
mov eax,[dly] ; eax = area y start edx = window y end |
cmp edx,eax |
jl ricino |
mov eax,[dlx] ; eax = area x start ecx = window x end |
cmp ecx,eax |
jl ricino |
bgli: |
cmp edi,esi |
jz ricino |
mov eax,edi |
add eax,draw_data-window_data |
mov ebx,[dlx] ; set limits |
mov [eax + RECT.left], ebx |
mov ebx,[dly] |
mov [eax + RECT.top], ebx |
mov ebx,[dlxe] |
mov [eax + RECT.right], ebx |
mov ebx,[dlye] |
mov [eax + RECT.bottom], ebx |
sub eax,draw_data-window_data |
cmp ecx,1 |
jne nobgrd |
cmp esi,1 |
je newdw8 |
call [drawbackground] |
newdw8: |
nobgrd: |
mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw |
ricino: |
not_this_task: |
pop ecx |
cmp ecx,[0x3004] |
jle newdw2 |
pop eax |
popad |
ret |
calculatebackground: ; background |
; all black |
mov [display_data-8],dword 4 ; size x |
mov [display_data-4],dword 2 ; size y |
mov edi, 0x300000 ; set background to black |
xor eax, eax |
mov ecx, 0x0fff00 / 4 |
cld |
rep stosd |
mov edi,display_data ; set os to use all pixels |
mov eax,0x01010101 |
mov ecx,0x1fff00 / 4 |
rep stosd |
mov byte [0xFFF0], 0 ; do not draw background! |
ret |
uglobal |
imax dd 0x0 |
endg |
delay_ms: ; delay in 1/1000 sec |
push eax |
push ecx |
mov ecx,esi |
; <CPU clock fix by Sergey Kuzmin aka Wildwest> |
imul ecx, 33941 |
shr ecx, 9 |
; </CPU clock fix> |
in al,0x61 |
and al,0x10 |
mov ah,al |
cld |
cnt1: in al,0x61 |
and al,0x10 |
cmp al,ah |
jz cnt1 |
mov ah,al |
loop cnt1 |
pop ecx |
pop eax |
ret |
set_app_param: |
push edi |
mov edi,[0x3010] |
mov [edi+TASKDATA.event_mask],eax |
pop edi |
ret |
delay_hs: ; delay in 1/100 secs |
push eax |
push ecx |
push edx |
mov edx,[timer_ticks] |
add edx,eax |
newtic: |
mov ecx,[timer_ticks] |
cmp edx,ecx |
jbe zerodelay |
call change_task |
jmp newtic |
zerodelay: |
pop edx |
pop ecx |
pop eax |
ret |
memmove: ; memory move in bytes |
; eax = from |
; ebx = to |
; ecx = no of bytes |
test ecx, ecx |
jle .ret |
push esi edi ecx |
mov edi, ebx |
mov esi, eax |
test ecx, not 11b |
jz @f |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
and ecx, 11b |
jz .finish |
@@: |
rep movsb |
.finish: |
pop ecx edi esi |
.ret: |
ret |
; <diamond> Sysfunction 34, read_floppy_file, is obsolete. Use 58 or 70 function instead. |
;align 4 |
; |
;read_floppy_file: |
; |
;; as input |
;; |
;; eax pointer to file |
;; ebx file lenght |
;; ecx start 512 byte block number |
;; edx number of blocks to read |
;; esi pointer to return/work area (atleast 20 000 bytes) |
;; |
;; |
;; on return |
;; |
;; eax = 0 command succesful |
;; 1 no fd base and/or partition defined |
;; 2 yet unsupported FS |
;; 3 unknown FS |
;; 4 partition not defined at hd |
;; 5 file not found |
;; ebx = size of file |
; |
; mov edi,[0x3010] |
; add edi,0x10 |
; add esi,[edi] |
; add eax,[edi] |
; |
; pushad |
; mov edi,esi |
; add edi,1024 |
; mov esi,0x100000+19*512 |
; sub ecx,1 |
; shl ecx,9 |
; add esi,ecx |
; shl edx,9 |
; mov ecx,edx |
; cld |
; rep movsb |
; popad |
; |
; mov [esp+36],eax |
; mov [esp+24],ebx |
; ret |
align 4 |
sys_programirq: |
mov edi,[0x3010] |
add eax,[edi+TASKDATA.mem_start] |
cmp ebx,16 |
jae .not_owner |
mov edi,[0x3010] |
mov edi,[edi+TASKDATA.pid] |
cmp edi,[irq_owner+ebx*4] |
je spril1 |
.not_owner: |
mov [esp+36],dword 1 |
ret |
spril1: |
mov esi,eax |
shl ebx,6 |
add ebx,irq00read |
mov edi,ebx |
mov ecx,16 |
cld |
rep movsd |
mov [esp+36],dword 0 |
ret |
align 4 |
get_irq_data: |
cmp eax,16 |
jae .not_owner |
mov edx,eax ; check for correct owner |
shl edx,2 |
add edx,irq_owner |
mov edx,[edx] |
mov edi,[0x3010] |
mov edi,[edi+TASKDATA.pid] |
cmp edx,edi |
je gidril1 |
.not_owner: |
mov [esp+32],dword 2 ; ecx=2 |
ret |
gidril1: |
mov ebx,eax |
shl ebx,12 |
add ebx,0x2e0000 |
mov eax,[ebx] |
mov ecx,1 |
test eax,eax |
jz gid1 |
dec eax |
mov esi,ebx |
mov [ebx],eax |
movzx ebx,byte [ebx+0x10] |
add esi,0x10 |
mov edi,esi |
inc esi |
mov ecx,4000 / 4 |
cld |
rep movsd |
; xor ecx,ecx ; as result of 'rep' ecx=0 |
gid1: |
mov [esp+36],eax |
mov [esp+32],ecx |
mov [esp+24],ebx |
ret |
set_io_access_rights: |
pushad |
mov edi,[0x3000] |
imul edi,tss_step |
add edi,tss_data+128 |
; add edi,128 |
mov ecx,eax |
and ecx,7 ; offset in byte |
shr eax,3 ; number of byte |
add edi,eax |
mov ebx,1 |
shl ebx,cl |
cmp ebp,0 ; enable access - ebp = 0 |
jne siar1 |
not ebx |
and [edi],byte bl |
popad |
ret |
siar1: |
or [edi],byte bl ; disable access - ebp = 1 |
popad |
ret |
r_f_port_area: |
test eax, eax |
jnz free_port_area |
; je r_port_area |
; jmp free_port_area |
; r_port_area: |
pushad |
cmp ebx,ecx ; beginning > end ? |
ja rpal1 |
cmp ecx,65536 |
jae rpal1 |
mov esi,[0x2d0000] |
test esi,esi ; no reserved areas ? |
je rpal2 |
cmp esi,255 ; max reserved |
jae rpal1 |
rpal3: |
mov edi,esi |
shl edi,4 |
add edi,0x2d0000 |
cmp ebx,[edi+8] |
ja rpal4 |
cmp ecx,[edi+4] |
jae rpal1 |
; jb rpal4 |
; jmp rpal1 |
rpal4: |
dec esi |
jnz rpal3 |
jmp rpal2 |
rpal1: |
popad |
mov eax,1 |
ret |
rpal2: |
popad |
; enable port access at port IO map |
cli |
pushad ; start enable io map |
cmp ecx,65536 ;16384 |
jae no_unmask_io ; jge |
mov eax,ebx |
new_port_access: |
pushad |
xor ebp,ebp ; enable - eax = port |
call set_io_access_rights |
popad |
inc eax |
cmp eax,ecx |
jbe new_port_access |
no_unmask_io: |
popad ; end enable io map |
sti |
mov edi,[0x2d0000] |
add edi,1 |
mov [0x2d0000],edi |
shl edi,4 |
add edi,0x2d0000 |
mov esi,[0x3010] |
mov esi,[esi+TASKDATA.pid] |
mov [edi],esi |
mov [edi+4],ebx |
mov [edi+8],ecx |
xor eax, eax |
ret |
free_port_area: |
pushad |
mov esi,[0x2d0000] ; no reserved areas ? |
test esi,esi |
je frpal2 |
mov edx,[0x3010] |
mov edx,[edx+TASKDATA.pid] |
frpal3: |
mov edi,esi |
shl edi,4 |
add edi,0x2d0000 |
cmp edx,[edi] |
jne frpal4 |
cmp ebx,[edi+4] |
jne frpal4 |
cmp ecx,[edi+8] |
jne frpal4 |
jmp frpal1 |
frpal4: |
dec esi |
jnz frpal3 |
frpal2: |
popad |
mov eax,1 |
ret |
frpal1: |
mov ecx,256 |
sub ecx,esi |
shl ecx,4 |
mov esi,edi |
add esi,16 |
cld |
rep movsb |
dec dword [0x2d0000] |
popad |
; disable port access at port IO map |
pushad ; start disable io map |
cmp ecx,65536 ;16384 |
jge no_mask_io |
mov eax,ebx |
new_port_access_disable: |
pushad |
mov ebp,1 ; disable - eax = port |
call set_io_access_rights |
popad |
inc eax |
cmp eax,ecx |
jbe new_port_access_disable |
no_mask_io: |
popad ; end disable io map |
xor eax, eax |
ret |
reserve_free_irq: |
mov ecx, 1 |
cmp ebx, 16 |
jae fril1 |
test eax,eax |
jz reserve_irq |
lea edi,[irq_owner+ebx*4] |
mov edx,[edi] |
mov eax,[0x3010] |
cmp edx,[eax+TASKDATA.pid] |
jne fril1 |
dec ecx |
mov [edi],ecx |
fril1: |
mov [esp+36],ecx ; return in eax |
ret |
reserve_irq: |
lea edi,[irq_owner+ebx*4] |
cmp dword [edi], 0 |
jnz ril1 |
mov edx,[0x3010] |
mov edx,[edx+TASKDATA.pid] |
mov [edi],edx |
dec ecx |
ril1: |
mov [esp+36],ecx ; return in eax |
ret |
__sys_drawbackground: |
inc [mouse_pause] |
cmp [0xfe0c],word 0x12 |
je dbrv20 |
dbrv12: |
cmp [0xfe0c],word 0100000000000000b |
jge dbrv20 |
cmp [0xfe0c],word 0x13 |
je dbrv20 |
call vesa12_drawbackground |
dec [mouse_pause] |
call [draw_pointer] |
ret |
dbrv20: |
cmp [display_data-12],dword 1 |
jne bgrstr |
call vesa20_drawbackground_tiled |
dec [mouse_pause] |
call [draw_pointer] |
ret |
bgrstr: |
call vesa20_drawbackground_stretch |
dec [mouse_pause] |
call [draw_pointer] |
ret |
align 4 |
syscall_putimage: ; PutImage |
mov edx,ecx |
mov ecx,ebx |
lea ebx, [eax+std_application_base_address] |
call [putimage] |
ret |
__sys_putimage: |
test ecx,0x80008000 |
jnz .exit |
test ecx,0x0000FFFF |
jz .exit |
test ecx,0xFFFF0000 |
jnz @f |
.exit: |
ret |
@@: |
mov edi,[0x3000] |
shl edi,8 |
add dx,word[edi+0x80000+APPDATA.wnd_clientbox.top] |
rol edx,16 |
add dx,word[edi+0x80000+APPDATA.wnd_clientbox.left] |
rol edx,16 |
.forced: |
; mov eax, vga_putimage |
cmp [0xfe0c], word 0x12 |
jz @f ;.doit |
mov eax, vesa12_putimage |
cmp [0xfe0c], word 0100000000000000b |
jae @f |
cmp [0xfe0c], word 0x13 |
jnz .doit |
@@: |
mov eax, vesa20_putimage |
.doit: |
inc [mouse_pause] |
call eax |
dec [mouse_pause] |
jmp [draw_pointer] |
; eax x beginning |
; ebx y beginning |
; ecx x end |
; edx y end |
; edi color |
__sys_drawbar: |
mov esi,[0x3000] |
shl esi,8 |
add eax,[esi+0x80000+APPDATA.wnd_clientbox.left] |
add ecx,[esi+0x80000+APPDATA.wnd_clientbox.left] |
add ebx,[esi+0x80000+APPDATA.wnd_clientbox.top] |
add edx,[esi+0x80000+APPDATA.wnd_clientbox.top] |
.forced: |
inc [mouse_pause] |
cmp [0xfe0c],word 0x12 |
je dbv20 |
sdbv20: |
cmp [0xfe0c],word 0100000000000000b |
jge dbv20 |
cmp [0xfe0c],word 0x13 |
je dbv20 |
call vesa12_drawbar |
dec [mouse_pause] |
call [draw_pointer] |
ret |
dbv20: |
call vesa20_drawbar |
dec [mouse_pause] |
call [draw_pointer] |
ret |
kb_read: |
push ecx edx |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kr_loop: |
in al,0x64 |
test al,1 |
jnz kr_ready |
loop kr_loop |
mov ah,1 |
jmp kr_exit |
kr_ready: |
push ecx |
mov ecx,32 |
kr_delay: |
loop kr_delay |
pop ecx |
in al,0x60 |
xor ah,ah |
kr_exit: |
pop edx ecx |
ret |
kb_write: |
push ecx edx |
mov dl,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop1: |
in al,0x64 |
test al,0x20 |
jz kw_ok1 |
loop kw_loop1 |
mov ah,1 |
jmp kw_exit |
kw_ok1: |
in al,0x60 |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop: |
in al,0x64 |
test al,2 |
jz kw_ok |
loop kw_loop |
mov ah,1 |
jmp kw_exit |
kw_ok: |
mov al,dl |
out 0x60,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop3: |
in al,0x64 |
test al,2 |
jz kw_ok3 |
loop kw_loop3 |
mov ah,1 |
jmp kw_exit |
kw_ok3: |
mov ah,8 |
kw_loop4: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop5: |
in al,0x64 |
test al,1 |
jnz kw_ok4 |
loop kw_loop5 |
dec ah |
jnz kw_loop4 |
kw_ok4: |
xor ah,ah |
kw_exit: |
pop edx ecx |
ret |
kb_cmd: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_wait: |
in al,0x64 |
test al,2 |
jz c_send |
loop c_wait |
jmp c_error |
c_send: |
mov al,bl |
out 0x64,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_accept: |
in al,0x64 |
test al,2 |
jz c_ok |
loop c_accept |
c_error: |
mov ah,1 |
jmp c_exit |
c_ok: |
xor ah,ah |
c_exit: |
ret |
setmouse: ; set mousepicture -pointer |
; ps2 mouse enable |
mov [0xf200],dword mousepointer+62+32*31*4 |
cli |
; mov bl,0xa8 ; enable mouse cmd |
; call kb_cmd |
; call kb_read ; read status |
; mov bl,0x20 ; get command byte |
; call kb_cmd |
; call kb_read |
; or al,3 ; enable interrupt |
; mov bl,0x60 ; write command |
; push eax |
; call kb_cmd |
; pop eax |
; call kb_write |
; mov bl,0xd4 ; for mouse |
; call kb_cmd |
; mov al,0xf4 ; enable mouse device |
; call kb_write |
; call kb_read ; read status return |
; com1 mouse enable |
mov bx,0x3f8 ; combase |
mov dx,bx |
add dx,3 |
mov al,0x80 |
out dx,al |
mov dx,bx |
add dx,1 |
mov al,0 |
out dx,al |
mov dx,bx |
add dx,0 |
mov al,0x30*2 ; 0x30 / 4 |
out dx,al |
mov dx,bx |
add dx,3 |
mov al,2 ; 3 |
out dx,al |
mov dx,bx |
add dx,4 |
mov al,0xb |
out dx,al |
mov dx,bx |
add dx,1 |
mov al,1 |
out dx,al |
; com2 mouse enable |
mov bx,0x2f8 ; combase |
mov dx,bx |
add dx,3 |
mov al,0x80 |
out dx,al |
mov dx,bx |
add dx,1 |
mov al,0 |
out dx,al |
mov dx,bx |
add dx,0 |
mov al,0x30*2 |
out dx,al |
mov dx,bx |
add dx,3 |
mov al,2 |
out dx,al |
mov dx,bx |
add dx,4 |
mov al,0xb |
out dx,al |
mov dx,bx |
add dx,1 |
mov al,1 |
out dx,al |
ret |
_rdtsc: |
mov edx,[cpuid_1+3*4] |
test edx,00010000b |
jz ret_rdtsc |
rdtsc |
ret |
ret_rdtsc: |
mov edx,0xffffffff |
mov eax,0xffffffff |
ret |
rerouteirqs: |
cli |
mov al,0x11 ; icw4, edge triggered |
out 0x20,al |
call pic_delay |
out 0xA0,al |
call pic_delay |
mov al,0x20 ; generate 0x20 + |
out 0x21,al |
call pic_delay |
mov al,0x28 ; generate 0x28 + |
out 0xA1,al |
call pic_delay |
mov al,0x04 ; slave at irq2 |
out 0x21,al |
call pic_delay |
mov al,0x02 ; at irq9 |
out 0xA1,al |
call pic_delay |
mov al,0x01 ; 8086 mode |
out 0x21,al |
call pic_delay |
out 0xA1,al |
call pic_delay |
mov al,255 ; mask all irq's |
out 0xA1,al |
call pic_delay |
out 0x21,al |
call pic_delay |
mov ecx,0x1000 |
cld |
picl1: call pic_delay |
loop picl1 |
mov al,255 ; mask all irq's |
out 0xA1,al |
call pic_delay |
out 0x21,al |
call pic_delay |
cli |
ret |
pic_delay: |
jmp pdl1 |
pdl1: ret |
sys_msg_board_str: |
pushad |
@@: |
cmp [esi],byte 0 |
je @f |
mov eax,1 |
movzx ebx,byte [esi] |
call sys_msg_board |
inc esi |
jmp @b |
@@: |
popad |
ret |
uglobal |
msg_board_data: times 512 db 0 |
msg_board_count dd 0x0 |
endg |
sys_msg_board: |
; eax=1 : write : bl byte to write |
; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al |
mov ecx,[msg_board_count] |
cmp eax, 1 |
jne smbl1 |
mov [msg_board_data+ecx],bl |
inc ecx |
and ecx, 511 |
mov [msg_board_count], ecx |
mov [check_idle_semaphore], 5 |
ret |
smbl1: |
cmp eax, 2 |
jne smbl2 |
test ecx, ecx |
jz smbl21 |
; mov edi, msg_board_data |
; mov esi, msg_board_data+1 |
; movzx eax, byte [edi] |
mov eax, msg_board_data+1 |
mov ebx, msg_board_data |
movzx edx, byte [ebx] |
call memmove |
; push ecx |
; shr ecx, 2 |
; cld |
; rep movsd |
; pop ecx |
; and ecx, 3 |
; rep movsb |
dec [msg_board_count] |
mov [esp+36], edx ;eax |
mov [esp+24], dword 1 |
ret |
smbl21: |
mov [esp+36], ecx |
mov [esp+24], ecx |
smbl2: |
ret |
sys_trace: |
test eax, eax ; get event data |
jnz no_get_sys_events |
mov esi,save_syscall_data ; data |
mov edi,[0x3010] |
mov edi,[edi+TASKDATA.mem_start] |
add edi,ebx |
cld |
rep movsb |
mov [esp+24],dword 0 |
mov eax,[save_syscall_count] ; count |
mov [esp+36],eax |
ret |
no_get_sys_events: |
ret |
sys_process_def: |
mov edi, [0x3000] |
dec eax ; 1 = set keyboard mode |
jne no_set_keyboard_setup |
shl edi,8 |
mov [edi+0x80000 + APPDATA.keyboard_mode],bl |
ret |
no_set_keyboard_setup: |
dec eax ; 2 = get keyboard mode |
jne no_get_keyboard_setup |
shl edi,8 |
movzx eax, byte [0x80000+edi + APPDATA.keyboard_mode] |
mov [esp+36],eax |
ret |
no_get_keyboard_setup: |
dec eax ; 3 = get keyboard ctrl, alt, shift |
jne no_get_keyboard_cas |
; xor eax,eax |
; movzx eax,byte [shift] |
; movzx ebx,byte [ctrl] |
; shl ebx,2 |
; add eax,ebx |
; movzx ebx,byte [alt] |
; shl ebx,3 |
; add eax,ebx |
;// mike.dld [ |
mov eax, [kb_state] |
;// mike.dld ] |
mov [esp+36],eax |
ret |
no_get_keyboard_cas: |
dec eax |
jnz no_add_keyboard_hotkey |
mov eax, hotkey_list |
@@: |
cmp dword [eax+8], 0 |
jz .found_free |
add eax, 16 |
cmp eax, hotkey_list+16*256 |
jb @b |
mov dword [esp+36], 1 |
ret |
.found_free: |
mov [eax+8], edi |
mov [eax+4], ecx |
movzx ebx, bl |
lea ebx, [hotkey_scancodes+ebx*4] |
mov ecx, [ebx] |
mov [eax], ecx |
mov [ebx], eax |
mov [eax+12], ebx |
jecxz @f |
mov [ecx+12], eax |
@@: |
and dword [esp+36], 0 |
ret |
no_add_keyboard_hotkey: |
dec eax |
jnz no_del_keyboard_hotkey |
movzx ebx, bl |
lea ebx, [hotkey_scancodes+ebx*4] |
mov eax, [ebx] |
.scan: |
test eax, eax |
jz .notfound |
cmp [eax+8], edi |
jnz .next |
cmp [eax+4], ecx |
jz .found |
.next: |
mov eax, [eax] |
jmp .scan |
.notfound: |
mov dword [esp+36], 1 |
ret |
.found: |
mov ecx, [eax] |
jecxz @f |
mov edx, [eax+12] |
mov [ecx+12], edx |
@@: |
mov ecx, [eax+12] |
mov edx, [eax] |
mov [ecx], edx |
xor edx, edx |
mov [eax+4], edx |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax], edx |
mov [esp+36], edx |
ret |
no_del_keyboard_hotkey: |
ret |
sys_ipc: |
cmp eax,1 ; DEFINE IPC MEMORY |
jne no_ipc_def |
mov edi,[0x3000] |
shl edi,8 |
add edi,0x80000 |
mov [edi + APPDATA.ipc_start], ebx |
mov [edi + APPDATA.ipc_size], ecx |
mov [esp+36],dword 0 |
ret |
no_ipc_def: |
cmp eax,2 ; SEND IPC MESSAGE |
jne no_ipc_send |
mov esi,1 |
mov edi,0x3020 |
ipcs1: |
cmp [edi+TASKDATA.pid], ebx |
je ipcs2 |
add edi,0x20 |
inc esi |
cmp esi,[0x3004] |
jbe ipcs1 |
mov [esp+36],dword 4 |
ret |
ipcs2: |
cli |
push esi |
mov eax,esi |
shl eax,8 |
mov ebx,[eax+0x80000 + APPDATA.ipc_start] |
test ebx,ebx ; ipc area not defined ? |
je ipc_err1 |
add ebx,[eax+0x80000 + APPDATA.ipc_size] |
mov eax,esi |
shl eax,5 |
add ebx,[eax+0x3000 + TASKDATA.mem_start] ; ebx <- max data position |
mov eax,esi ; to |
shl esi,8 |
add esi,0x80000 |
mov edi,[esi+APPDATA.ipc_start] |
shl eax,5 |
add eax,0x3000 |
add edi,[eax+TASKDATA.mem_start] |
cmp [edi],byte 0 ; overrun ? |
jne ipc_err2 |
mov ebp,edi |
add edi,[edi+4] |
add edi,8 |
mov esi,ecx ; from |
mov eax,[0x3010] |
mov eax,[eax+TASKDATA.mem_start] |
add esi,eax |
mov ecx,edx ; size |
mov eax,edi |
add eax,ecx |
cmp eax,ebx |
jg ipc_err3 ; not enough room ? |
push ecx |
mov eax,[0x3010] |
mov eax,[eax+TASKDATA.pid] |
mov [edi-8],eax |
mov [edi-4],ecx |
cld |
rep movsb |
pop ecx |
add ecx,8 |
mov edi,ebp ; increase memory position |
add dword [edi+4],ecx |
mov edi,[esp] |
shl edi,8 |
or dword [edi+0x80000+APPDATA.event_mask],dword 01000000b ; ipc message |
cmp [check_idle_semaphore],dword 20 |
jge ipc_no_cis |
mov [check_idle_semaphore],5 |
ipc_no_cis: |
xor eax, eax |
ipc_err: |
add esp,4 |
mov [esp+36],eax |
sti |
ret |
ipc_err1: |
add esp,4 |
mov [esp+36],dword 1 |
sti |
ret |
ipc_err2: |
add esp,4 |
mov [esp+36],dword 2 |
sti |
ret |
ipc_err3: |
add esp,4 |
mov [esp+36],dword 3 |
sti |
ret |
no_ipc_send: |
mov [esp+36],dword -1 |
ret |
align 4 |
sys_gs: ; direct screen access |
cmp eax,1 ; resolution |
jne no_gs1 |
mov eax,[0xfe00] |
shl eax,16 |
mov ax,[0xfe04] |
add eax,0x00010001 |
mov [esp+36],eax |
ret |
no_gs1: |
cmp eax,2 ; bits per pixel |
jne no_gs2 |
movzx eax,byte [0xfbf1] |
mov [esp+36],eax |
ret |
no_gs2: |
cmp eax,3 ; bytes per scanline |
jne no_gs3 |
mov eax,[0xfe08] |
mov [esp+36],eax |
ret |
no_gs3: |
mov [esp+36],dword -1 |
ret |
align 4 ; PCI functions |
sys_pci: |
call pci_api |
mov [esp+36],eax |
ret |
align 4 ; system functions |
syscall_setpixel: ; SetPixel |
mov edx,[0x3010] |
add eax,[edx-twdw+WDATA.box.left] |
add ebx,[edx-twdw+WDATA.box.top] |
mov edi,[0x3000] |
shl edi,8 |
add eax,[edi+0x80000+APPDATA.wnd_clientbox.left] |
add ebx,[edi+0x80000+APPDATA.wnd_clientbox.top] |
xor edi,edi ; no force |
; mov edi,1 |
call [disable_mouse] |
jmp [putpixel] |
align 4 |
syscall_writetext: ; WriteText |
mov edi,[0x3010] |
mov ebp,[edi-twdw+WDATA.box.left] |
mov esi,[0x3000] |
shl esi,8 |
add ebp,[esi+0x80000+APPDATA.wnd_clientbox.left] |
shl ebp,16 |
add ebp,[edi-twdw+WDATA.box.top] |
add bp,word[esi+0x80000+APPDATA.wnd_clientbox.top] |
add ecx,[edi+TASKDATA.mem_start] |
add eax,ebp |
xor edi,edi |
jmp dtext |
align 4 |
syscall_openramdiskfile: ; OpenRamdiskFile |
mov edi,[0x3010] |
add edi, TASKDATA.mem_start |
add eax,[edi] |
add edx,[edi] |
mov esi,12 |
call fileread |
mov [esp+36],ebx |
ret |
align 4 |
syscall_drawrect: ; DrawRect |
mov edi,ecx |
and edi,0x80FFFFFF |
test ax,ax |
je drectr |
test bx,bx |
je drectr |
movzx ecx,ax |
sar eax,16 |
movzx edx,bx |
sar ebx,16 |
mov esi,[0x3000] |
shl esi,8 |
add eax,[esi+0x80000+APPDATA.wnd_clientbox.left] |
add ebx,[esi+0x80000+APPDATA.wnd_clientbox.top] |
add ecx,eax |
add edx,ebx |
jmp [drawbar] |
drectr: |
ret |
align 4 |
syscall_getscreensize: ; GetScreenSize |
movzx eax,word[0xfe00] |
shl eax,16 |
mov ax,[0xfe04] |
mov [esp+36],eax |
ret |
align 4 |
syscall_startapp: ; StartApp |
mov edi,[0x3010] |
add edi, TASKDATA.mem_start |
add eax,[edi] |
test ebx,ebx |
jz noapppar |
add ebx,[edi] |
noapppar: |
; call start_application_fl |
xor edx,edx ; compatibility - flags=0 |
call new_start_application_fl |
mov [esp+36],eax |
ret |
align 4 |
syscall_cdaudio: ; CD |
call sys_cd_audio |
mov [esp+36],eax |
ret |
; <diamond> ReadHd and StartHdApp functions are obsolete. Use 58 or 70 functions instead. |
;align 4 |
; |
;syscall_readhd: ; ReadHd |
; |
; mov edi,[0x3010] |
; add edi,0x10 |
; add esi,[edi] |
; add eax,[edi] |
; call read_hd_file |
; mov [esp+36],eax |
; mov [esp+24],ebx |
; ret |
;align 4 |
; |
;syscall_starthdapp: ; StartHdApp |
; |
; mov edi,[0x3010] |
; add edi,0x10 |
; add eax,[edi] |
; add ecx,[edi] |
; xor ebp,ebp |
; xor edx,edx ; compatibility - flags=0 |
; call start_application_hd |
; mov [esp+36],eax |
; ret |
align 4 |
syscall_delramdiskfile: ; DelRamdiskFile |
mov edi,[0x3010] |
add edi, TASKDATA.mem_start |
add eax,[edi] |
call filedelete |
mov [esp+36],eax |
ret |
align 4 |
syscall_writeramdiskfile: ; WriteRamdiskFile |
mov edi,[0x3010] |
add edi, TASKDATA.mem_start |
add eax,[edi] |
add ebx,[edi] |
call filesave |
mov [esp+36],eax |
ret |
align 4 |
syscall_getpixel: ; GetPixel |
mov ecx,[0xfe00] |
inc ecx |
xor edx,edx |
div ecx |
mov ebx,edx |
xchg eax,ebx |
call dword [0xe024] |
mov [esp+36],ecx |
ret |
align 4 |
syscall_readstring: ; ReadString |
mov edi,[0x3010] |
add edi, TASKDATA.mem_start |
add eax,[edi] |
call read_string |
mov [esp+36],eax |
ret |
align 4 |
syscall_drawline: ; DrawLine |
mov edi,[0x3010] |
mov edx, [edi-twdw+WDATA.box.left] |
mov esi,[0x3000] |
shl esi,8 |
add edx, [esi+0x80000+APPDATA.wnd_clientbox.left] |
add ax,dx |
rol eax,16 |
add ax,dx |
rol eax,16 |
mov edx, [edi-twdw+WDATA.box.top] |
add edx, [esi+0x80000+APPDATA.wnd_clientbox.top] |
add bx,dx |
rol ebx,16 |
add bx,dx |
rol ebx,16 |
xor edi,edi |
jmp [draw_line] |
align 4 |
syscall_getirqowner: ; GetIrqOwner |
cmp eax,16 |
jae .err |
shl eax,2 |
add eax,irq_owner |
mov eax,[eax] |
mov [esp+36],eax |
ret |
.err: |
or dword [esp+36], -1 |
ret |
align 4 |
syscall_reserveportarea: ; ReservePortArea and FreePortArea |
call r_f_port_area |
mov [esp+36],eax |
ret |
align 4 |
syscall_threads: ; CreateThreads |
call sys_threads |
mov [esp+36],eax |
ret |
align 4 |
stack_driver_stat: |
call app_stack_handler ; Stack status |
; mov [check_idle_semaphore],5 ; enable these for zero delay |
; call change_task ; between sent packet |
mov [esp+36],eax |
ret |
align 4 |
socket: ; Socket interface |
call app_socket_handler |
; mov [check_idle_semaphore],5 ; enable these for zero delay |
; call change_task ; between sent packet |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
align 4 |
user_events: ; User event times |
mov eax,0x12345678 |
mov [esp+36],eax |
ret |
align 4 |
read_from_hd: ; Read from hd - fn not in use |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
add ecx,[edi] |
add edx,[edi] |
call file_read |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
align 4 |
write_to_hd: ; Write a file to hd |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
add ecx,[edi] |
add edx,[edi] |
call file_write |
ret |
; <diamond> Sysfunction 57, delete_from_hd, is obsolete. Use 58 or 70 functions instead. |
;align 4 |
; |
;delete_from_hd: ; Delete a file from hd |
; |
; mov edi,[0x3010] |
; add edi,0x10 |
; add eax,[edi] |
; add ecx,[edi] |
; call file_delete |
; ret |
; |
; --------------- APM --------------------- |
apm_entry dp 0 |
apm_vf dd 0 |
align 4 |
sys_apm: |
cmp word [apm_vf], 0 ; Check APM BIOS enable |
jne @f |
or [esp + 56], byte 1 ; error |
mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported |
ret |
@@: xchg eax, ecx |
xchg ebx, ecx |
cmp al, 3 |
ja @f |
and [esp + 56], byte 0xfe ; emulate func 0..3 as func 0 |
mov eax, [apm_vf] |
mov [esp + 36], eax |
shr eax, 16 |
mov [esp + 32], eax |
ret |
@@: call pword [apm_entry] ; call APM BIOS |
mov [esp + 8 ], edi |
mov [esp + 12], esi |
mov [esp + 24], ebx |
mov [esp + 28], edx |
mov [esp + 32], ecx |
mov [esp + 36], eax |
setc al |
and [esp + 56], byte 0xfe |
or [esp + 56], al |
ret |
; ----------------------------------------- |
align 4 |
undefined_syscall: ; Undefined system call |
mov [esp+36],dword -1 |
ret |
;clear_busy_flag_at_caller: |
; push edi |
; mov edi,[0x3000] ; restore processes tss pointer in gdt, busyfl? |
; imul edi,8 |
; mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b |
; pop edi |
; ret |
keymap: |
db '6',27 |
db '1234567890-=',8,9 |
db 'qwertyuiop[]',13 |
db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 ' |
db '@234567890123',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'AB<D',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
keymap_shift: |
db '6',27 |
db '!@#$%^&*()_+',8,9 |
db 'QWERTYUIOP{}',13 |
db '~ASDFGHJKL:"~',0,'|ZXCVBNM<>?',0,'45 ' |
db '@234567890123',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
keymap_alt: |
db ' ',27 |
db ' @ $ {[]}\ ',8,9 |
db ' ',13 |
db ' ',0,' ',0,'4',0,' ' |
db ' ',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
; device irq owners |
uglobal |
irq_owner: ; process id |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
dd 0x0 |
endg |
; on irq read ports |
uglobal |
irq00read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq01read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq02read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq03read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq04read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq05read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq06read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq07read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq08read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq09read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq10read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq11read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq12read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq13read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq14read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
irq15read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
endg |
; status |
uglobal |
hd1_status dd 0x0 ; 0 - free : other - pid |
application_table_status dd 0x0 ; 0 - free : other - pid |
endg |
; device addresses |
uglobal |
mididp dd 0x0 |
midisp dd 0x0 |
cdbase dd 0x0 |
cdid dd 0x0 |
hdbase dd 0x0 ; for boot 0x1f0 |
hdid dd 0x0 |
hdpos dd 0x0 ; for boot 0x1 |
fat32part dd 0x0 ; for boot 0x1 |
;part2_ld dd 0x0 |
;* start code - Mario79 |
mouse_pause dd 0 |
MouseTickCounter dd 0 |
ps2_mouse_detected db 0 |
com1_mouse_detected db 0 |
com2_mouse_detected db 0 |
;* end code - Mario79 |
wraw_bacground_select db 0 |
lba_read_enabled dd 0x0 ; 0 = disabled , 1 = enabled |
pci_access_enabled dd 0x0 ; 0 = disabled , 1 = enabled |
sb16 dd 0x0 |
wss dd 0x0 |
buttontype dd 0x0 |
windowtypechanged dd 0x0 |
endg |
iglobal |
keyboard dd 0x1 |
sound_dma dd 0x1 |
syslang dd 0x1 |
endg |
IncludeIGlobals |
endofcode: |
IncludeUGlobals |
uglobals_size = $ - endofcode |
diff16 "end of kernel code",0,$ |
/kernel/branches/gfx_kernel/kernel16.inc |
---|
0,0 → 1,32 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; KERNEL16.INC ;; |
;; ;; |
;; Included 16 bit kernel files for MenuetOS ;; |
;; ;; |
;; This file is kept separate as it will be easier to ;; |
;; maintain and compile with an automated SETUP program ;; |
;; in the future. ;; |
;; ;; |
;; Copyright Ville Turjanmaa, see file COPYING for details. ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;% +include |
;!!! |
if lang eq en |
include "boot/booteng.inc" ; english system boot messages |
else |
include "boot/bootru.inc" ; russian system boot messages |
;!!! |
end if |
include "boot/ru.inc" ; Russian font |
org $-0x10000 |
include "boot/bootcode.inc" ; 16 bit system boot code |
include "bus/pci/pci16.inc" |
;% -include |
/kernel/branches/gfx_kernel/kernel32.inc |
---|
0,0 → 1,256 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; KERNEL32.INC ;; |
;; ;; |
;; Included 32 bit kernel files for MenuetOS ;; |
;; ;; |
;; This file is kept separate as it will be easier to ;; |
;; maintain and compile with an automated SETUP program ;; |
;; in the future. ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; structure definition helper |
macro struct name, [arg] |
{ |
common |
name@struct equ name |
struc name arg { |
} |
macro struct_helper name |
{ |
match xname,name |
\{ |
virtual at 0 |
xname xname |
sizeof.#xname = $ - xname |
name equ sizeof.#xname |
end virtual |
\} |
} |
ends fix } struct_helper name@struct |
;// mike.dld, 2006-29-01 [ |
; macros definition |
macro diff16 title,l1,l2 |
{ |
local s,d |
s = l2-l1 |
display title,': 0x' |
repeat 8 |
d = 48 + s shr ((8-%) shl 2) and $0F |
if d > 57 |
d = d + 65-57-1 |
end if |
display d |
end repeat |
display 13,10 |
} |
;struc db [a] { common . db a |
; if ~used . |
; display 'not used db: ',`.,13,10 |
; end if } |
;struc dw [a] { common . dw a |
; if ~used . |
; display 'not used dw: ',`.,13,10 |
; end if } |
;struc dd [a] { common . dd a |
; if ~used . |
; display 'not used dd: ',`.,13,10 |
; end if } |
;struc dp [a] { common . dp a |
; if ~used . |
; display 'not used dp: ',`.,13,10 |
; end if } |
;struc dq [a] { common . dq a |
; if ~used . |
; display 'not used dq: ',`.,13,10 |
; end if } |
;struc dt [a] { common . dt a |
; if ~used . |
; display 'not used dt: ',`.,13,10 |
; end if } |
struc RECT { |
.left dd ? |
.top dd ? |
.right dd ? |
.bottom dd ? |
} |
virtual at 0 |
RECT RECT |
end virtual |
struc BOX { |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
} |
virtual at 0 |
BOX BOX |
end virtual |
; constants definition |
WSTATE_NORMAL = 00000000b |
WSTATE_MAXIMIZED = 00000001b |
WSTATE_MINIMIZED = 00000010b |
WSTATE_ROLLEDUP = 00000100b |
WSTATE_REDRAW = 00000001b |
WSTATE_WNDDRAWN = 00000010b |
WSTYLE_HASCAPTION = 00010000b |
WSTYLE_CLIENTRELATIVE = 00100000b |
struc TASKDATA |
{ |
.event_mask dd ? |
.pid dd ? |
dw ? |
.state db ? |
db ? |
dw ? |
.wnd_number db ? |
db ? |
.mem_start dd ? |
.counter_sum dd ? |
.counter_add dd ? |
.cpu_usage dd ? |
} |
virtual at 0 |
TASKDATA TASKDATA |
end virtual |
; structures definition |
struc WDATA { |
.box BOX |
.cl_workarea dd ? |
.cl_titlebar dd ? |
.cl_frames dd ? |
.reserved db ? |
.fl_wstate db ? |
.fl_wdrawn db ? |
.fl_redraw db ? |
} |
virtual at 0 |
WDATA WDATA |
end virtual |
label WDATA.fl_wstyle byte at 0x13 |
struc APPDATA |
{ |
.app_name db 11 dup(?) |
db 5 dup(?) |
.fpu_save_area: db 108 dup(?) |
db 3 dup(?) |
.is_fpu_saved db ? |
.wnd_shape dd ? |
.wnd_shape_scale dd ? |
dd ? |
.mem_size dd ? |
.saved_box BOX |
.ipc_start dd ? |
.ipc_size dd ? |
.event_mask dd ? |
.debugger_slot dd ? |
dd ? |
.keyboard_mode db ? |
db 3 dup(?) |
.dir_table dd ? |
.dbg_event_mem dd ? |
.dbg_regs: |
.dbg_regs.dr0 dd ? |
.dbg_regs.dr1 dd ? |
.dbg_regs.dr2 dd ? |
.dbg_regs.dr3 dd ? |
.dbg_regs.dr7 dd ? |
.wnd_caption dd ? |
.wnd_clientbox BOX |
} |
virtual at 0 |
APPDATA APPDATA |
end virtual |
;// mike.dld, 2006-29-01 ] |
; Core functions |
include "core/sync.inc" ; macros for synhronization objects |
include "core/sys32.inc" ; process management |
include "core/sched.inc" ; process scheduling |
include "core/syscall.inc" ; system call |
include "core/mem.inc" ; high-level memory management |
include "core/newproce.inc" ;new process management |
include "core/physmem.inc" ; access to physical memory for applications |
; GUI stuff |
include "gui/window.inc" |
include "gui/event.inc" |
include "gui/font.inc" |
include "gui/button.inc" |
; shutdown |
include "boot/shutdown.inc" ; shutdown or restart |
; file system |
include "fs/fs.inc" ; syscall |
include "fs/fat32.inc" ; read / write for fat32 filesystem |
include "fs/fat12.inc" ; read / write for fat12 filesystem |
include "blkdev/rd.inc" ; ramdisk read /write |
include "fs/fs_lfn.inc" ; syscall, version 2 |
include "fs/iso9660.inc" ; read for iso9660 filesystem CD |
; sound |
include "sound/sb16.inc" ; playback for Sound Blaster 16 |
include "sound/playnote.inc" ; player Note for Speaker PC |
; display |
include "video/vesa12.inc" ; Vesa 1.2 functions |
include "video/vesa20.inc" ; Vesa 2.0 functions |
include "video/vga.inc" ; VGA 16 color functions |
; Network Interface & TCPIP Stack |
include "network/stack.inc" |
; Mouse pointer |
include "gui/mouse.inc" |
; Window skinning |
include "gui/skincode.inc" |
; Pci functions |
include "bus/pci/pci32.inc" |
; Floppy drive controller |
include "blkdev/fdc.inc" |
include "blkdev/flp_drv.inc" |
; CD drive controller |
include "blkdev/cdrom.inc" |
include "blkdev/cd_drv.inc" |
; Character devices |
include "hid/keyboard.inc" |
include "hid/mousedrv.inc" |
; setting date,time,clock and alarm-clock |
include "hid/set_dtc.inc" |
;% -include |
/kernel/branches/gfx_kernel/kglobals.inc |
---|
0,0 → 1,50 |
;------------------------------------------------------------------ |
; use "iglobal" for inserting initialized global data definitions. |
;------------------------------------------------------------------ |
macro iglobal { |
IGlobals equ IGlobals, |
macro __IGlobalBlock { } |
;------------------------------------------------------------- |
; use 'uglobal' for inserting uninitialized global definitions. |
; even when you define some data values, these variables |
; will be stored as uninitialized data. |
;------------------------------------------------------------- |
macro uglobal { |
UGlobals equ UGlobals, |
macro __UGlobalBlock { } |
endg fix } ; Use endg for ending iglobal and uglobal blocks. |
macro IncludeIGlobals{ |
macro IGlobals dummy,[n] \{ __IGlobalBlock |
purge __IGlobalBlock \} |
match I, IGlobals \{ I \} } |
macro IncludeUGlobals{ |
macro UGlobals dummy,[n] \{ |
\common |
\local begin, size |
begin = $ |
virtual at $ |
\forward |
__UGlobalBlock |
purge __UGlobalBlock |
\common |
size = $ - begin |
end virtual |
rb size |
\} |
match U, UGlobals \{ U \} } |
macro IncludeAllGlobals { |
IncludeIGlobals |
IncludeUGlobals |
} |
iglobal |
endg |
uglobal |
endg |
/kernel/branches/gfx_kernel/lang.inc |
---|
0,0 → 1,0 |
lang fix en |
/kernel/branches/gfx_kernel/makefile |
---|
0,0 → 1,16 |
FASM=fasm |
KSRC=kernel.asm |
KOUT=kernel.mnt |
en: kernel.asm |
rm -f lang.inc |
echo lang fix en > lang.inc |
$(FASM) $(KSRC) $(KOUT) |
ru: kernel.asm |
rm -f lang.inc |
echo lang fix ru > lang.inc |
$(FASM) $(KSRC) $(KOUT) |
clean: |
rm -f $(KOUT) |
rm -f lang.inc |
/kernel/branches/gfx_kernel/memmap.inc |
---|
0,0 → 1,237 |
; |
; MEMORY MAP |
; |
; Boot: |
; |
; 0:9000 byte bits per pixel |
; 0:9001 word scanline length |
; 0:9008 word vesa video mode |
; 0:900A word X res |
; 0:900C word Y res |
; 0:9010 byte mouse port - not used |
; 0:9014 dword Vesa 1.2 pm bank switch |
; 0:9018 dword Vesa 2.0 LFB address |
; 0:901C byte 0 or 1 : enable MTRR graphics acceleration |
; 0:901D byte not used anymore (0 or 1 : enable system log display) |
; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled |
; 0:9020 8bytes pci data |
; 0:9030 byte VRR start enabled 1, 2-no |
; 0:9031 word IDEContrRegsBaseAddr |
; 0:9034 byte vesa major version number (ascii) |
; 0:9035 byte card vendor (intel=1, s3=2, other=3) |
; 0x9040 - dword - entry point of APM BIOS |
; 0x9044 - word - version (BCD) |
; 0x9046 - word - flags |
; |
; Runtime: |
; |
; 0000 -> 1FFF window_data - 256 entries |
; |
; 0000 dword x start |
; 0004 dword y start |
; 0008 dword x size |
; 000C dword y size |
; 0010 dword color of work area |
; 0014 dword color of grab bar |
; 0018 dword color of frames |
; 001C dword window flags, +30 = window drawn, +31 redraw flag |
; |
; 2000 -> 2FFF free |
; |
; 3000 -> 4FFF task list - 256 entries |
; |
; 00 dword process count |
; 04 dword no of processes |
; 10 dword base of running process at 0x3000+ |
; |
; 20 dword application event mask |
; 24 dword PID - process identification number |
; 2a byte slot state: 0=running, 1,2=suspended |
; 3=zombie, 4=terminate, |
; 5=waiting for event, 9 = not used |
; 2e byte window number on screen |
; 30 dword exact position in memory |
; 34 dword counter sum |
; 38 dword time stamp counter add |
; 3c dword cpu usage in cpu timer tics |
; |
; |
; 5000 -> 5FFF save_syscall_data - syscall trace |
; 6000 -> 68FF free |
; 6900 -> 6EFF saved picture under mouse pointer |
; |
; 6F00 -> 6FFF free |
; |
; 7000 -> 7FFF used CD driver |
; |
; 8000 -> A3FF used FLOPPY driver |
; |
; A400 -> B0FF free |
; B100 -> B2FF IDT |
; B300 -> BFFF free |
; C000 -> C3FF window stack C000 no of windows - all in words |
; C402 -> C7FF window position in stack |
; D000 -> D1FF FDC controller |
; D200 -> D3FF FDC controller for Fat12 |
; D400 -> DFFF free |
; E000 byte multitasking started |
; E020 dword putpixel address |
; E024 dword getpixel address |
; E030 dword Vesa 1.2 pm bank switch address |
; E034 byte vesa major version number (ascii) |
; E035 byte card vendor (intel=1, s3=2, other=3) |
; F200 dword mousepicture -pointer |
; F204 dword mouse appearance counter |
; F300 dword x & y temp for windowmove |
; F400 byte no of keys in buffer |
; F401 byte 'buffer' |
; F402 -> F4FF reserved for keys |
; F500 byte no of buttons in buffer |
; F501 dword 'buffer' |
; F502 -> F5FF reserved for buttons |
; F600 dword tsc / second |
; F604 byte mouse port: 1 ps2, 2 com1, 3 com2 |
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y |
; FB10 -> FB17 mouse color mem |
; FB21 x move |
; FB22 y move |
; FB28 high bits temp |
; FB30 color temp |
; FB40 byte buttons down |
; FB44 byte 0 mouse down -> do not draw |
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under |
; FBF1 byte bits per pixel |
; FC00 -> FCFE com1/ps2 buffer |
; FCFF com1/ps2 buffer count starting from FC00 |
; FE00 dword screen x size |
; FE04 dword screen y size |
; FE08 dword screen y multiplier |
; FE0C dword screen mode |
; FE10 dword entries in hd cache |
; FE80 dword address of LFB in physical |
; FE84 dword address of applications memory start in physical |
; FE88 dword address of button list |
; FE8C dword memory to use |
; FF00 byte 1 = system shutdown request |
; FF01 dword free |
; FFF0 byte 1 = redraw background request from app |
; FFF1 byte 1 = diskette int occur |
; FFF2 write and read bank in screen |
; FFF4 byte 0 if first mouse draw & do not return picture under |
; FFF5 byte 1 do not draw pointer |
; FFFF byte do not change task for 1/100 sec. |
; |
; 10000 -> 3DBFF kernel, 32-bit run-time code (up to 183 Kb) |
; 3DC00 -> 3EBFF stack at boot time (4Kb) |
; 3EC00 -> 3F5FF basic text font II |
; 3F600 -> 3FFFF basic text font I |
; 40000 -> 4FFFF data of retrieved disks and partitions (Mario79) |
; 50000 -> 5FFFF free (64 Kb) |
; 60000 -> 7FFFF reserved to physical memory manager |
; 80000 -> 8FFFF additional app info, in 256 byte steps - 256 entries |
; |
; 00 11db name of app running |
; 10 108db floating point unit save area |
; 7f byte 0= no fpu saved , 1= fpu saved to 0x10 -> restore |
; 80 dword address of random shaped window area |
; 84 byte shape area scale |
; 88 dword free |
; 8C dword application memory size |
; 90 dword window X position save |
; 94 dword window Y position save |
; 98 dword window X size save |
; 9C dword window Y size save |
; A0 dword IPC memory start |
; A4 dword IPC memory size |
; A8 dword event bits: mouse, stack,.. |
; AC dword 0 or debugger slot |
; B0 dword free |
; B4 byte keyboard mode: 0 = keymap, 1 = scancodes |
; B8 dword physical address of directory table |
; BC dword address of debug event memory |
; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7 |
; |
; 90000 -> 9FFFF tmp |
; A0000 -> AFFFF screen access area |
; B0000 -> FFFFF bios rest in peace -area |
; 100000 -> 27FFFF diskette image |
; 280000 -> 281FFF ramdisk fat |
; 282000 -> 283FFF floppy fat |
; |
; 284000 -> 29FFFF free (112 Kb) |
; |
; 2A0000 -> 2B00ff wav device data |
; 2C0000 -> 2C3fff button info |
; |
; 0000 word number of buttons |
; first button entry at 0x10 |
; +0000 word process number |
; +0002 word button id number : bits 00-15 |
; +0004 word x start |
; +0006 word x size |
; +0008 word y start |
; +000A word y size |
; +000C word button id number : bits 16-31 |
; |
; 2C4000 -> 2CFFFF free (48Kb) |
; |
; 2D0000 -> 2DFFFF reserved port area |
; |
; 0000 dword no of port areas reserved |
; 0010 dword process id |
; dword start port |
; dword end port |
; dword 0 |
; |
; 2E0000 -> 2EFFFF irq data area |
; 2F0000 -> 2FFFFF low memory save |
; |
; 300000 -> 45FFFF background image, max 1,375 M |
; |
; 460000 -> 5FFFFF display info |
; |
; 600000 -> 6FFFFF hd cache |
; |
; 700000 -> 71ffff tcp memory (128 kb) |
; 720000 -> 75ffff free (256 kb) |
; |
; 760000 -> 76ffff !vrr driver |
; 770000 -> 777fff tcp memory ( 32 kb) |
; |
; 778000 -> 77ffff window skinning ( 32 kb) |
; 780000 -> 7fffff reserved to physical memory manager |
; |
; 800000 -> BFFFFF mapped to LFB |
; |
; |
; C00000 -> C01FFF draw_data - 256 entries |
; |
; 00 dword draw limit - x start |
; 04 dword draw limit - y start |
; 08 dword draw limit - x end |
; 0C dword draw limit - y end |
; |
; C02000 -> C02fff free (4 Kb) |
; |
; C03000 -> D02fff sysint_stack_data |
; - ring0 stacks for ring3 processes |
; - used for interrupt handling |
; - 256 entries * 4096 step |
; |
; D03000 -> D1ffff free (116 Kb) |
; |
; D20000 -> F28000 TSS and IO map for (8192*8)=65536 ports |
; (128+8192)*256 = 557956 = 0x88000 |
; |
; 1000000 -> 3FFFFFF for applications |
; |
/kernel/branches/gfx_kernel/network/eth_drv/3c59x.inc |
---|
0,0 → 1,2380 |
;; Copyright (c) 2004, Endre Kozma <endre.kozma@axelero.hu> |
;; All rights reserved. |
;; |
;; Redistribution and use in source and binary forms, with or without |
;; modification, are permitted provided that the following conditions are |
;; met: |
;; |
;; 1. Redistributions of source code must retain the above copyright notice, |
;; this list of conditions and the following disclaimer. |
;; |
;; 2. Redistributions in binary form must reproduce the above copyright |
;; notice, this list of conditions and the following disclaimer in the |
;; documentation and/or other materials provided with the distribution. |
;; |
;; 3. The name of the author may not be used to endorse or promote products |
;; derived from this software without specific prior written permission. |
;; |
;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 3C59X.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Driver for 3Com fast etherlink 3c59x and ;; |
;; etherlink XL 3c900 and 3c905 cards ;; |
;; References: ;; |
;; www.3Com.com - data sheets ;; |
;; DP83840A.pdf - ethernet physical layer ;; |
;; 3c59x.c - linux driver ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; Credits ;; |
;; Mike Hibbett, ;; |
;; who kindly supplied me with a 3Com905C-TX-M card ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; History |
;; ======= |
;; $Log: 3C59X.INC,v $ |
;; Revision 1.3 2004/07/11 12:21:12 kozma |
;; Support of vortex chips (3c59x) added. |
;; Support of 3c920 and 3c982 added. |
;; Corrections. |
;; |
;; Revision 1.2 2004/06/12 19:40:20 kozma |
;; Function e3c59x_set_available_media added in order to set |
;; the default media in case auto detection finds no valid link. |
;; Incorrect mii check removed (3c900 Cyclone works now). |
;; Cleanups. |
;; |
;; Revision 1.1 2004/06/12 18:27:15 kozma |
;; Initial revision |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; comment the next line out if you don't want debug info printed |
; on the debug board. This option adds a lot of bytes to the driver |
; so it's worth to comment it out. |
; E3C59X_DEBUG equ 1 |
; forcing full duplex mode makes sense at some cards and link types |
E3C59X_FORCE_FD equ 1 |
macro virt_to_dma reg |
{ |
if defined E3C59X_LINUX |
sub reg, [virt_addr] |
add reg, [dma_addr] |
end if |
} |
macro dma_to_virt reg |
{ |
if defined E3C59X_LINUX |
sub reg, [dma_addr] |
add reg, [virt_addr] |
end if |
} |
macro zero_to_virt reg |
{ |
if defined E3C59X_LINUX |
add reg, [virt_addr] |
end if |
} |
macro virt_to_zero reg |
{ |
if defined E3C59X_LINUX |
sub reg, [virt_addr] |
end if |
} |
macro zero_to_dma reg |
{ |
if defined E3C59X_LINUX |
add reg, [dma_addr] |
end if |
} |
macro dma_to_zero reg |
{ |
if defined E3C59X_LINUX |
sub reg, [dma_addr] |
end if |
} |
macro strtbl name, [string] |
{ |
common |
label name dword |
forward |
local label |
dd label |
forward |
label db string, 0 |
} |
; Ethernet frame symbols |
ETH_ALEN equ 6 |
ETH_HLEN equ (2*ETH_ALEN+2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
; PCI programming |
PCI_REG_COMMAND equ 0x4 ; command register |
PCI_REG_STATUS equ 0x6 ; status register |
PCI_REG_LATENCY equ 0xd ; latency timer register |
PCI_REG_CAP_PTR equ 0x34 ; capabilities pointer |
PCI_REG_CAPABILITY_ID equ 0x0 ; capapility ID in pm register block |
PCI_REG_PM_STATUS equ 0x4 ; power management status register |
PCI_REG_PM_CTRL equ 0x4 ; power management control register |
PCI_BIT_PIO equ 0 ; bit0: io space control |
PCI_BIT_MMIO equ 1 ; bit1: memory space control |
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master |
; Registers |
E3C59X_REG_POWER_MGMT_CTRL equ 0x7c |
E3C59X_REG_UP_LIST_PTR equ 0x38 |
E3C59X_REG_UP_PKT_STATUS equ 0x30 |
E3C59X_REG_TX_FREE_THRESH equ 0x2f |
E3C59X_REG_DN_LIST_PTR equ 0x24 |
E3C59X_REG_DMA_CTRL equ 0x20 |
E3C59X_REG_TX_STATUS equ 0x1b |
E3C59X_REG_RX_STATUS equ 0x18 |
E3C59X_REG_TX_DATA equ 0x10 |
; Common window registers |
E3C59X_REG_INT_STATUS equ 0xe |
E3C59X_REG_COMMAND equ 0xe |
; Register window 7 |
E3C59X_REG_MASTER_STATUS equ 0xc |
E3C59X_REG_POWER_MGMT_EVENT equ 0xc |
E3C59X_REG_MASTER_LEN equ 0x6 |
E3C59X_REG_VLAN_ETHER_TYPE equ 0x4 |
E3C59X_REG_VLAN_MASK equ 0x0 |
E3C59X_REG_MASTER_ADDRESS equ 0x0 |
; Register window 6 |
E3C59X_REG_BYTES_XMITTED_OK equ 0xc |
E3C59X_REG_BYTES_RCVD_OK equ 0xa |
E3C59X_REG_UPPER_FRAMES_OK equ 0x9 |
E3C59X_REG_FRAMES_DEFERRED equ 0x8 |
E3C59X_REG_FRAMES_RCVD_OK equ 0x7 |
E3C59X_REG_FRAMES_XMITTED_OK equ 0x6 |
E3C59X_REG_RX_OVERRUNS equ 0x5 |
E3C59X_REG_LATE_COLLISIONS equ 0x4 |
E3C59X_REG_SINGLE_COLLISIONS equ 0x3 |
E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2 |
E3C59X_REG_SQE_ERRORS equ 0x1 |
E3C59X_REG_CARRIER_LOST equ 0x0 |
; Register window 5 |
E3C59X_REG_INDICATION_ENABLE equ 0xc |
E3C59X_REG_INTERRUPT_ENABLE equ 0xa |
E3C59X_REG_TX_RECLAIM_THRESH equ 0x9 |
E3C59X_REG_RX_FILTER equ 0x8 |
E3C59X_REG_RX_EARLY_THRESH equ 0x6 |
E3C59X_REG_TX_START_THRESH equ 0x0 |
; Register window 4 |
E3C59X_REG_UPPER_BYTES_OK equ 0xe |
E3C59X_REG_BAD_SSD equ 0xc |
E3C59X_REG_MEDIA_STATUS equ 0xa |
E3C59X_REG_PHYSICAL_MGMT equ 0x8 |
E3C59X_REG_NETWORK_DIAGNOSTIC equ 0x6 |
E3C59X_REG_FIFO_DIAGNOSTIC equ 0x4 |
E3C59X_REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported |
; Bits in register window 4 |
E3C59X_BIT_AUTOSELECT equ 24 |
; Register window 3 |
E3C59X_REG_TX_FREE equ 0xc |
E3C59X_REG_RX_FREE equ 0xa |
E3C59X_REG_MEDIA_OPTIONS equ 0x8 |
E3C59X_REG_MAC_CONTROL equ 0x6 |
E3C59X_REG_MAX_PKT_SIZE equ 0x4 |
E3C59X_REG_INTERNAL_CONFIG equ 0x0 |
; Register window 2 |
E3C59X_REG_RESET_OPTIONS equ 0xc |
E3C59X_REG_STATION_MASK_HI equ 0xa |
E3C59X_REG_STATION_MASK_MID equ 0x8 |
E3C59X_REG_STATION_MASK_LO equ 0x6 |
E3C59X_REG_STATION_ADDRESS_HI equ 0x4 |
E3C59X_REG_STATION_ADDRESS_MID equ 0x2 |
E3C59X_REG_STATION_ADDRESS_LO equ 0x0 |
; Register window 1 |
E3C59X_REG_TRIGGER_BITS equ 0xc |
E3C59X_REG_SOS_BITS equ 0xa |
E3C59X_REG_WAKE_ON_TIMER equ 0x8 |
E3C59X_REG_SMB_RXBYTES equ 0x7 |
E3C59X_REG_SMB_DIAG equ 0x5 |
E3C59X_REG_SMB_ARB equ 0x4 |
E3C59X_REG_SMB_STATUS equ 0x2 |
E3C59X_REG_SMB_ADDRESS equ 0x1 |
E3C59X_REG_SMB_FIFO_DATA equ 0x0 |
; Register window 0 |
E3C59X_REG_EEPROM_DATA equ 0xc |
E3C59X_REG_EEPROM_COMMAND equ 0xa |
E3C59X_REG_BIOS_ROM_DATA equ 0x8 |
E3C59X_REG_BIOS_ROM_ADDR equ 0x4 |
; Physical management bits |
E3C59X_BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData |
E3C59X_BIT_MGMT_DATA equ 1 ; MII management data bit |
E3C59X_BIT_MGMT_CLK equ 0 ; MII management clock |
; MII commands |
E3C59X_MII_CMD_MASK equ (1111b shl 10) |
E3C59X_MII_CMD_READ equ (0110b shl 10) |
E3C59X_MII_CMD_WRITE equ (0101b shl 10) |
; MII registers |
E3C59X_REG_MII_BMCR equ 0 ; basic mode control register |
E3C59X_REG_MII_BMSR equ 1 ; basic mode status register |
E3C59X_REG_MII_ANAR equ 4 ; auto negotiation advertisement register |
E3C59X_REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register |
E3C59X_REG_MII_ANER equ 6 ; auto negotiation expansion register |
; MII bits |
E3C59X_BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete |
E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6 |
; eeprom bits and commands |
E3C59X_EEPROM_CMD_READ equ 0x80 |
E3C59X_EEPROM_BIT_BUSY equ 15 |
; eeprom registers |
E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa |
E3C59X_EEPROM_REG_CAPABILITIES equ 0x10 |
; Commands for command register |
E3C59X_SELECT_REGISTER_WINDOW equ (1 shl 11) |
IS_VORTEX equ 0x1 |
IS_BOOMERANG equ 0x2 |
IS_CYCLONE equ 0x4 |
IS_TORNADO equ 0x8 |
EEPROM_8BIT equ 0x10 |
HAS_PWR_CTRL equ 0x20 |
HAS_MII equ 0x40 |
HAS_NWAY equ 0x80 |
HAS_CB_FNS equ 0x100 |
INVERT_MII_PWR equ 0x200 |
INVERT_LED_PWR equ 0x400 |
MAX_COLLISION_RESET equ 0x800 |
EEPROM_OFFSET equ 0x1000 |
HAS_HWCKSM equ 0x2000 |
EXTRA_PREAMBLE equ 0x4000 |
iglobal |
align 4 |
e3c59x_hw_versions: |
dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps |
dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex |
dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex |
dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx |
dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4 |
dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII |
dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT |
dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo |
dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO |
dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo |
dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC |
dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL |
dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx |
dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4 |
dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx |
dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC |
dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx |
dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado |
dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone |
dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone |
dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane |
dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane |
dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \ |
or INVERT_MII_PWR or HAS_HWCKSM ; 3c556 Laptop Tornado |
dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \ |
or INVERT_MII_PWR or HAS_HWCKSM ; 3c556B Laptop Hurricane |
dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus |
dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus |
dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \ |
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE575BT Cyclone CardBus |
dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CCFE575CT Tornado CardBus |
dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE656 Cyclone CardBus |
dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFEM656B Cyclone+Winmodem CardBus |
dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ |
or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CXFEM656C Tornado+Winmodem CardBus |
dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado |
dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado |
dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A |
dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B |
dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4 |
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado |
E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions |
endg |
; RX/TX buffers sizes |
E3C59X_MAX_ETH_PKT_SIZE equ 1536 ; max packet size |
E3C59X_NUM_RX_DESC equ 4 ; a power of 2 number |
E3C59X_NUM_TX_DESC equ 4 ; a power of 2 number |
E3C59X_RX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC) |
E3C59X_TX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC) |
; Download Packet Descriptor |
E3C59X_DPD_DN_NEXT_PTR equ 0 |
E3C59X_DPD_FRAME_START_HDR equ 4 |
E3C59X_DPD_DN_FRAG_ADDR equ 8 ; for packet data |
E3C59X_DPD_DN_FRAG_LEN equ 12 ; for packet data |
E3C59X_DPD_SIZE equ 16 ; a power of 2 number |
; Upload Packet Descriptor |
E3C59X_UPD_UP_NEXT_PTR equ 0 |
E3C59X_UPD_PKT_STATUS equ 4 |
E3C59X_UPD_UP_FRAG_ADDR equ 8 ; for packet data |
E3C59X_UPD_UP_FRAG_LEN equ 12 ; for packet data |
E3C59X_UPD_SIZE equ 16 |
; RX/TX buffers |
if defined E3C59X_LINUX |
E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment |
e3c59x_rx_buff = 0 |
else |
E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment |
e3c59x_rx_buff = eth_data_start |
end if |
e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE |
e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE |
e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC) |
uglobal |
e3c59x_curr_upd: dd 0 |
e3c59x_prev_dpd: dd 0 |
e3c59x_prev_tx_frame: dd 0 |
e3c59x_transmit_function: dd 0 |
e3c59x_receive_function: dd 0 |
endg |
iglobal |
e3c59x_ver_id: db 17 |
endg |
uglobal |
e3c59x_full_bus_master: db 0 |
e3c59x_has_hwcksm: db 0 |
e3c59x_preamble: db 0 |
e3c59x_dn_list_ptr_cleared: db 0 |
e3c59x_self_directed_packet: rb 6 |
endg |
if defined E3C59X_DEBUG |
e3c59x_hw_type_str: db "Detected hardware type : ", 0 |
e3c59x_device_str: db "Device ID : 0x" |
e3c59x_device_id_str: db "ffff", 13, 10, 0 |
e3c59x_vendor_str: db "Vendor ID : 0x" |
e3c59x_vendor_id_str: db "ffff", 13, 10, 0 |
e3c59x_io_info_str: db "IO address : 0x" |
e3c59x_io_addr_str: db "ffff", 13, 10, 0 |
e3c59x_mac_info_str: db "MAC address : " |
e3c59x_mac_addr_str: db "ff:ff:ff:ff:ff:ff", 13, 10, 0 |
e3c59x_boomerang_str: db " (boomerang)", 13, 10, 0 |
e3c59x_vortex_str: db " (vortex)", 13, 10, 0 |
e3c59x_link_type_str: db "Established link type : ", 0 |
e3c59x_new_line_str: db 13, 10, 0 |
e3c59x_link_type: dd 0 |
e3c59x_charset: db '0123456789abcdef' |
strtbl e3c59x_link_str, \ |
"No valid link type detected", \ |
"10BASE-T half duplex", \ |
"10BASE-T full-duplex", \ |
"100BASE-TX half duplex", \ |
"100BASE-TX full duplex", \ |
"100BASE-T4", \ |
"100BASE-FX", \ |
"10Mbps AUI", \ |
"10Mbps COAX (BNC)", \ |
"miiDevice - not supported" |
strtbl e3c59x_hw_str, \ |
"3c590 Vortex 10Mbps", \ |
"3c592 EISA 10Mbps Demon/Vortex", \ |
"3c597 EISA Fast Demon/Vortex", \ |
"3c595 Vortex 100baseTx", \ |
"3c595 Vortex 100baseT4", \ |
"3c595 Vortex 100base-MII", \ |
"3c900 Boomerang 10baseT", \ |
"3c900 Boomerang 10Mbps Combo", \ |
"3c900 Cyclone 10Mbps TPO", \ |
"3c900 Cyclone 10Mbps Combo", \ |
"3c900 Cyclone 10Mbps TPC", \ |
"3c900B-FL Cyclone 10base-FL", \ |
"3c905 Boomerang 100baseTx", \ |
"3c905 Boomerang 100baseT4", \ |
"3c905B Cyclone 100baseTx", \ |
"3c905B Cyclone 10/100/BNC", \ |
"3c905B-FX Cyclone 100baseFx", \ |
"3c905C Tornado", \ |
"3c980 Cyclone", \ |
"3c982 Dual Port Server Cyclone", \ |
"3cSOHO100-TX Hurricane", \ |
"3c555 Laptop Hurricane", \ |
"3c556 Laptop Tornado", \ |
"3c556B Laptop Hurricane", \ |
"3c575 [Megahertz] 10/100 LAN CardBus", \ |
"3c575 Boomerang CardBus", \ |
"3CCFE575BT Cyclone CardBus", \ |
"3CCFE575CT Tornado CardBus", \ |
"3CCFE656 Cyclone CardBus", \ |
"3CCFEM656B Cyclone+Winmodem CardBus", \ |
"3CXFEM656C Tornado+Winmodem CardBus", \ |
"3c450 HomePNA Tornado", \ |
"3c920 Tornado", \ |
"3c982 Hydra Dual Port A", \ |
"3c982 Hydra Dual Port B", \ |
"3c905B-T4", \ |
"3c920B-EMB-WNM Tornado" |
end if ; defined E3C59X_DEBUG |
;*************************************************************************** |
; Function |
; e3c59x_debug |
; Description |
; prints debug info to the debug board |
; Parameters |
; ebp - io_addr |
; Return value |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
if defined E3C59X_DEBUG |
align 4 |
e3c59x_debug: |
pushad |
; print device type |
mov esi, e3c59x_hw_type_str |
call sys_msg_board_str |
movzx ecx, byte [e3c59x_ver_id] |
mov esi, [e3c59x_hw_str+ecx*4] |
call sys_msg_board_str |
mov esi, e3c59x_boomerang_str |
cmp dword [e3c59x_transmit_function], e3c59x_boomerang_transmit |
jz .boomerang |
mov esi, e3c59x_vortex_str |
.boomerang: |
call sys_msg_board_str |
; print device/vendor |
mov ax, [pci_data+2] |
mov cl, 2 |
mov ebx, e3c59x_device_id_str |
call e3c59x_print_hex |
mov esi, e3c59x_device_str |
call sys_msg_board_str |
mov ax, [pci_data] |
mov cl, 2 |
mov ebx, e3c59x_vendor_id_str |
call e3c59x_print_hex |
mov esi, e3c59x_vendor_str |
call sys_msg_board_str |
; print io address |
mov ax, [io_addr] |
mov ebx, e3c59x_io_addr_str |
mov cl, 2 |
call e3c59x_print_hex |
mov esi, e3c59x_io_info_str |
call sys_msg_board_str |
; print MAC address |
mov ebx, e3c59x_mac_addr_str |
xor ecx, ecx |
.mac_loop: |
push ecx |
mov al, [node_addr+ecx] |
mov cl, 1 |
call e3c59x_print_hex |
inc ebx |
pop ecx |
inc cl |
cmp cl, 6 |
jne .mac_loop |
mov esi, e3c59x_mac_info_str |
call sys_msg_board_str |
; print link type |
mov esi, e3c59x_link_type_str |
call sys_msg_board_str |
xor eax, eax |
bsr ax, word [e3c59x_link_type] |
jz @f |
sub ax, 4 |
@@: |
mov esi, [e3c59x_link_str+eax*4] |
call sys_msg_board_str |
mov esi, e3c59x_new_line_str |
call sys_msg_board_str |
popad |
ret |
;*************************************************************************** |
; Function |
; e3c59x_print_hex |
; Description |
; prints a hexadecimal value |
; Parameters |
; eax - value to be printed out |
; ebx - where to print |
; cl - value size (1, 2, 4) |
; Return value |
; ebx - end address after the print |
; Destroyed registers |
; eax, ebx |
; |
;*************************************************************************** |
align 4 |
e3c59x_print_hex: |
cmp cl, 1 |
je .print_byte |
cmp cl, 2 |
jz .print_word |
.print_dword: |
push eax |
bswap eax |
xchg ah, al |
call .print_word |
pop eax |
.print_word: |
push eax |
xchg ah, al |
call .print_byte |
pop eax |
.print_byte: |
movzx eax, al |
push eax |
and al, 0xf0 |
shr al, 4 |
mov al, byte [eax+e3c59x_charset] |
mov [ebx], al |
inc ebx |
pop eax |
and al, 0x0f |
mov al, byte [eax+e3c59x_charset] |
mov [ebx], al |
inc ebx |
ret |
end if ; defined E3C59X_DEBUG |
;*************************************************************************** |
; Function |
; e3c59x_try_link_detect |
; Description |
; e3c59x_try_link_detect checks if link exists |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 ; no link detected |
; al - 1 ; link detected |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_link_detect: |
; download self-directed packet |
mov edi, node_addr |
mov bx, 0x0608 ; packet type |
mov esi, e3c59x_self_directed_packet |
mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes |
call dword [e3c59x_transmit_function] |
; switch to register window 5 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 |
out dx, ax |
; program RxFilter for promiscuous operation |
mov ax, (10000b shl 11) |
lea edx, [ebp+E3C59X_REG_RX_FILTER] |
in al, dx |
or al, 1111b |
lea edx, [ebp+E3C59X_REG_COMMAND] |
out dx, ax |
; switch to register window 4 |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; check loop |
xor ebx, ebx |
mov ecx, 0xffff ; 65535 tries |
.loop: |
push ecx ebx |
call dword [e3c59x_receive_function] |
pop ebx ecx |
test al, al |
jnz .finish |
.no_packet_received: |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; read linkbeatdetect |
lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] |
in ax, dx |
test ah, 1000b ; test linkBeatDetect |
jnz .link_detected |
xor al, al |
jmp .finish |
.link_detected: |
; test carrierSense |
test al, 100000b |
jz .no_carrier_sense |
inc ebx |
.no_carrier_sense: |
dec ecx |
jns .loop |
; assume the link is good if 0 < ebx < 25 % |
test ebx, ebx |
setnz al |
jz .finish |
cmp ebx, 16384 ; 25% |
setb al |
.finish: |
if defined E3C59X_DEBUG |
test al, al |
jz @f |
or byte [e3c59x_link_type+1], 100b |
@@: |
end if ; defined E3C59X_DEBUG |
ret |
;*************************************************************************** |
; Function |
; e3c59x_try_phy |
; Description |
; e3c59x_try_phy checks the auto-negotiation function |
; in the PHY at PHY index. It can also be extended to |
; include link detection for non-IEEE 802.3u |
; auto-negotiation devices, for instance the BCM5000. |
; Parameters |
; ah - PHY index |
; ebp - io_addr |
; Return value |
; al - 0 link is auto-negotiated |
; al - 1 no link is auto-negotiated |
; Destroyed registers |
; eax, ebx, ecx, edx, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_phy: |
mov al, E3C59X_REG_MII_BMCR |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
or ah, 0x80 ; software reset |
mov ebx, eax |
pop eax |
push eax |
call e3c59x_mdio_write ; returns with window #4 |
; wait for reset to complete |
mov esi, 2000 ; 2000ms = 2s |
call delay_ms |
pop eax |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
test ah, 0x80 |
jnz .fail_finish |
pop eax |
push eax |
; wait for a while after reset |
mov esi, 20 ; 20ms |
call delay_ms |
pop eax |
push eax |
mov al, E3C59X_REG_MII_BMSR |
call e3c59x_mdio_read ; returns with window #4 |
test al, 1 ; extended capability supported? |
jz .no_ext_cap |
; auto-neg capable? |
test al, 1000b |
jz .fail_finish ; not auto-negotiation capable |
; auto-neg complete? |
test al, 100000b |
jnz .auto_neg_ok |
; restart auto-negotiation |
pop eax |
push eax |
mov al, E3C59X_REG_MII_ANAR |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
or ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX |
mov ebx, eax |
pop eax |
call e3c59x_mdio_write ; returns with window #4 |
pop eax |
push eax |
call e3c59x_mdio_read ; returns with window #4 |
mov ebx, eax |
or bh, 10010b ; restart auto-negotiation |
pop eax |
push eax |
call e3c59x_mdio_write ; returns with window #4 |
mov esi, 4000 ; 4000ms = 4 seconds |
call delay_ms |
pop eax |
push eax |
mov al, E3C59X_REG_MII_BMSR |
call e3c59x_mdio_read ; returns with window #4 |
test al, 100000b ; auto-neg complete? |
jnz .auto_neg_ok |
jmp .fail_finish |
.auto_neg_ok: |
; compare advertisement and link partner ability registers |
pop eax |
push eax |
mov al, E3C59X_REG_MII_ANAR |
call e3c59x_mdio_read ; returns with window #4 |
xchg eax, [esp] |
mov al, E3C59X_REG_MII_ANLPAR |
call e3c59x_mdio_read ; returns with window #4 |
pop ebx |
and eax, ebx |
and eax, 1111100000b |
push eax |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], ax |
end if ; defined E3C59X_DEBUG |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; set full-duplex mode |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
and ax, not 0x120 ; clear full duplex and flow control |
pop ebx |
test ebx, (1010b shl 5) ; check for full-duplex |
jz .half_duplex |
or ax, 0x120 ; set full duplex and flow control |
.half_duplex: |
out dx, ax |
mov al, 1 |
ret |
.no_ext_cap: |
; not yet implemented BCM5000 |
.fail_finish: |
pop eax |
xor al, al |
ret |
;*************************************************************************** |
; Function |
; e3c59x_try_mii |
; Description |
; e3c59x_try_MII checks the on-chip auto-negotiation logic |
; or an off-chip MII PHY, depending upon what is set in |
; xcvrSelect by the caller. |
; It exits when it finds the first device with a good link. |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, ebx, ecx, edx, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_mii: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, (1111b shl 20) |
cmp eax, (1000b shl 20) ; is auto-negotiation set? |
jne .mii_device |
; auto-negotiation is set |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; PHY==24 is the on-chip auto-negotiation logic |
; it supports only 10base-T and 100base-TX |
mov ah, 24 |
call e3c59x_try_phy |
test al, al |
jz .fail_finish |
mov cl, 24 |
jmp .check_preamble |
.mii_device: |
cmp eax, (0110b shl 20) |
jne .fail_finish |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
in ax, dx |
and al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA) |
cmp al, (1 shl E3C59X_BIT_MGMT_DATA) |
je .serch_for_phy |
xor al, al |
ret |
.serch_for_phy: |
; search for PHY |
mov cl, 31 |
.search_phy_loop: |
cmp cl, 24 |
je .next_phy |
mov ah, cl ; ah = phy |
mov al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register |
push ecx |
call e3c59x_mdio_read |
pop ecx |
test ax, ax |
jz .next_phy |
cmp ax, 0xffff |
je .next_phy |
mov ah, cl ; ah = phy |
push ecx |
call e3c59x_try_phy |
pop ecx |
test al, al |
jnz .check_preamble |
.next_phy: |
dec cl |
jns .search_phy_loop |
.fail_finish: |
xor al, al |
ret |
; epilog |
.check_preamble: |
push eax ; eax contains the return value of e3c59x_try_phy |
; check hard coded preamble forcing |
movzx eax, byte [e3c59x_ver_id] |
test word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE |
setnz [e3c59x_preamble] ; force preamble |
jnz .finish |
; check mii for preamble suppression |
mov ah, cl |
mov al, E3C59X_REG_MII_BMSR |
call e3c59x_mdio_read |
test al, 1000000b ; preamble suppression? |
setz [e3c59x_preamble] ; no |
.finish: |
pop eax |
ret |
;*************************************************************************** |
; Function |
; e3c59x_test_packet |
; Description |
; e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_test_packet: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; set fullDuplexEnable in MacControl register |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
or ax, 0x120 |
out dx, ax |
; switch to register window 5 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 |
out dx, ax |
; set RxFilter to enable individual address matches |
mov ax, (10000b shl 11) |
lea edx, [ebp+E3C59X_REG_RX_FILTER] |
in al, dx |
or al, 1 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
out dx, ax |
; issue RxEnable and TxEnable |
call e3c59x_rx_reset |
call e3c59x_tx_reset |
; download a self-directed test packet |
mov edi, node_addr |
mov bx, 0x0608 ; packet type |
mov esi, e3c59x_self_directed_packet |
mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes |
call dword [e3c59x_transmit_function] |
; wait for 2s |
mov esi, 2000 ; 2000ms = 2s |
call delay_ms |
; check if self-directed packet is received |
call dword [e3c59x_receive_function] |
test al, al |
jnz .finish |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; clear fullDuplexEnable in MacControl register |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
and ax, not 0x120 |
out dx, ax |
xor al, al |
.finish: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_try_loopback |
; Description |
; tries a loopback packet for 10BASE2 or AUI port |
; Parameters |
; al - 0: 10Mbps AUI connector |
; 1: 10BASE-2 |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_try_loopback: |
push eax |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
pop eax |
push eax |
if defined E3C59X_DEBUG |
mov bl, al |
inc bl |
shl bl, 3 |
or byte [e3c59x_link_type+1], bl |
end if ; defined E3C59X_DEBUG |
test al, al ; aui or coax? |
jz .complete_loopback |
; enable 100BASE-2 DC-DC converter |
mov ax, (10b shl 11) ; EnableDcConverter |
out dx, ax |
.complete_loopback: |
mov cl, 2 ; give a port 3 chances to complete a loopback |
.next_try: |
push ecx |
call e3c59x_test_packet |
pop ecx |
test al, al |
jnz .finish |
dec cl |
jns .next_try |
.finish: |
xchg eax, [esp] |
test al, al |
jz .aui_finish |
; issue DisableDcConverter command |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10111b shl 11) |
out dx, ax |
.aui_finish: |
pop eax ; al contains the result of operation |
if defined E3C59X_DEBUG |
test al, al |
jnz @f |
and byte [e3c59x_link_type+1], not 11000b |
@@: |
end if ; defined E3C59X_DEBUG |
ret |
;*************************************************************************** |
; Function |
; e3c59x_set_available_media |
; Description |
; sets the first available media |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 |
; al - 1 |
; Destroyed registers |
; eax, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_set_available_media: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
push eax |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx |
test al, 10b |
jz @f |
; baseTXAvailable |
pop eax |
and eax, not (1111b shl 20) |
or eax, (100b shl 20) |
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD |
mov word [e3c59x_link_type], (1 shl 8) |
else if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 7) |
end if |
jmp .set_media |
@@: |
test al, 100b |
jz @f |
; baseFXAvailable |
pop eax |
and eax, not (1111b shl 20) |
or eax, (101b shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 10) |
end if |
jmp .set_media |
@@: |
test al, 1000000b |
jz @f |
; miiDevice |
pop eax |
and eax, not (1111b shl 20) |
or eax, (0110b shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 13) |
end if |
jmp .set_media |
@@: |
test al, 1000b |
jz @f |
.set_default: |
; 10bTAvailable |
pop eax |
and eax, not (1111b shl 20) |
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD |
mov word [e3c59x_link_type], (1 shl 6) |
else if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 5) |
end if ; E3C59X_FORCE_FD |
jmp .set_media |
@@: |
test al, 10000b |
jz @f |
; coaxAvailable |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10b shl 11) ; EnableDcConverter |
out dx, ax |
pop eax |
and eax, not (1111b shl 20) |
or eax, (11b shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 12) |
end if ; defined E3C59X_DEBUG |
jmp .set_media |
@@: |
test al, 10000b |
jz .set_default |
; auiAvailable |
pop eax |
and eax, not (1111b shl 20) |
or eax, (1 shl 20) |
if defined E3C59X_DEBUG |
mov word [e3c59x_link_type], (1 shl 11) |
end if ; defined E3C59X_DEBUG |
.set_media: |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
out dx, eax |
if defined E3C59X_FORCE_FD |
; set fullDuplexEnable in MacControl register |
lea edx, [ebp+E3C59X_REG_MAC_CONTROL] |
in ax, dx |
or ax, 0x120 |
out dx, ax |
end if ; E3C59X_FORCE_FD |
mov al, 1 |
ret |
;*************************************************************************** |
; Function |
; e3c59x_set_active_port |
; Description |
; It selects the media port (transceiver) to be used |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_set_active_port: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
test eax, (1 shl 24) ; check if autoselect enable |
jz .set_first_available_media |
; check 100BASE-TX and 10BASE-T |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx |
test al, 1010b ; check whether 100BASE-TX or 10BASE-T available |
jz .mii_device ; they are not available |
; set auto-negotiation |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (1000b shl 20) |
out dx, eax |
call e3c59x_try_mii |
test al, al |
jz .mii_device |
ret |
.mii_device: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for off-chip mii device |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx |
test al, 1000000b ; check miiDevice |
jz .base_fx |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0110b shl 20) ; set MIIDevice |
out dx, eax |
call e3c59x_try_mii |
test al, al |
jz .base_fx |
ret |
.base_fx: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for 100BASE-FX |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx ; read media option register |
test al, 100b ; check 100BASE-FX |
jz .aui_enable |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0101b shl 20) ; set 100base-FX |
out dx, eax |
call e3c59x_try_link_detect |
test al, al |
jz .aui_enable |
ret |
.aui_enable: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for 10Mbps AUI connector |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx ; read media option register |
test al, 100000b ; check 10Mbps AUI connector |
jz .coax_available |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0001b shl 20) ; set 10Mbps AUI connector |
out dx, eax |
xor al, al ; try 10Mbps AUI connector |
call e3c59x_try_loopback |
test al, al |
jz .coax_available |
ret |
.coax_available: |
; switch to register window 3 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 |
out dx, ax |
; check for coaxial 10BASE-2 port |
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] |
in ax, dx ; read media option register |
test al, 10000b ; check 10BASE-2 |
jz .set_first_available_media |
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] |
in eax, dx |
and eax, not (1111b shl 20) |
or eax, (0011b shl 20) ; set 10BASE-2 |
out dx, eax |
mov al, 1 |
call e3c59x_try_loopback |
test al, al |
jz .set_first_available_media |
ret |
.set_first_available_media: |
jmp e3c59x_set_available_media |
;*************************************************************************** |
; Function |
; e3c59x_wake_up |
; Description |
; set the power state to D0 |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_wake_up: |
; wake up - we directly do it by programming PCI |
; check if the device is power management capable |
mov al, 2 |
mov ah, [pci_bus] |
mov bl, PCI_REG_STATUS |
mov bh, [pci_dev] |
push eax ebx |
call pci_read_reg |
test al, 10000b ; is there "new capabilities" linked list? |
pop ebx eax |
jz .device_awake |
; search for power management register |
mov al, 1 |
mov bl, PCI_REG_CAP_PTR |
push eax ebx |
call pci_read_reg |
mov cl, al |
cmp cl, 0x3f |
pop ebx eax |
jbe .device_awake |
; traverse the list |
mov al, 2 |
.pm_loop: |
mov bl, cl |
push eax ebx |
call pci_read_reg |
cmp al, 1 |
je .set_pm_state |
test ah, ah |
mov cl, ah |
pop ebx eax |
jnz .pm_loop |
jmp .device_awake |
; waku up the device if necessary |
.set_pm_state: |
pop ebx eax |
add bl, PCI_REG_PM_CTRL |
push eax ebx |
call pci_read_reg |
mov cx, ax |
test cl, 3 |
pop ebx eax |
jz .device_awake |
and cl, not 11b ; set state to D0 |
call pci_write_reg |
.device_awake: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_probe: |
movzx ebp, word [io_addr] |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
push ebp eax ebx |
call pci_read_reg |
mov cx, ax |
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) |
and cl, not (1 shl PCI_BIT_MMIO) |
pop ebx eax |
call pci_write_reg |
; wake up the card |
call e3c59x_wake_up |
pop ebp |
; get chip version |
mov ax, [pci_data+2] |
mov ecx, E3C59X_HW_VERSIONS_SIZE/4-1 |
.chip_ver_loop: |
cmp ax, [e3c59x_hw_versions+ecx*4] |
jz .chip_ver_found |
dec ecx |
jns .chip_ver_loop |
xor ecx, ecx |
.chip_ver_found: |
mov [e3c59x_ver_id], cl |
test word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM |
setnz [e3c59x_has_hwcksm] |
; set pci latency for vortex cards |
test word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX |
jz .not_vortex |
mov cx, 11111000b ; 248 = max latency |
mov al, 1 |
mov ah, [pci_bus] |
mov bl, PCI_REG_LATENCY |
mov bh, [pci_dev] |
call pci_write_reg |
.not_vortex: |
; set RX/TX functions |
mov ax, E3C59X_EEPROM_REG_CAPABILITIES |
call e3c59x_read_eeprom |
test al, 100000b ; full bus master? |
setnz [e3c59x_full_bus_master] |
jnz .boomerang_func |
mov dword [e3c59x_transmit_function], e3c59x_vortex_transmit |
mov dword [e3c59x_receive_function], e3c59x_vortex_poll |
jmp @f |
.boomerang_func: ; full bus master, so use boomerang functions |
mov dword [e3c59x_transmit_function], e3c59x_boomerang_transmit |
mov dword [e3c59x_receive_function], e3c59x_boomerang_poll |
@@: |
; read MAC from eeprom |
mov ecx, 2 |
.mac_loop: |
lea ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx] |
call e3c59x_read_eeprom |
xchg ah, al ; htons |
mov [node_addr+ecx*2], ax |
dec ecx |
jns .mac_loop |
test byte [e3c59x_full_bus_master], 0xff |
jz .set_preamble |
; switch to register window 2 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 |
out dx, ax |
; activate xcvr by setting some magic bits |
lea edx, [ebp+E3C59X_REG_RESET_OPTIONS] |
in ax, dx |
and ax, not 0x4010 |
movzx ebx, byte [e3c59x_ver_id] |
test word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR |
jz @f |
or al, 0x10 |
@@: |
test word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR |
jz @f |
or ah, 0x40 |
@@: |
out dx, ax |
.set_preamble: |
; use preamble as default |
mov byte [e3c59x_preamble], 1 ; enable preamble |
;*************************************************************************** |
; Function |
; e3c59x_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
e3c59x_reset: |
; issue global reset |
call e3c59x_global_reset |
; disable interrupts |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (1110b shl 11) |
out dx, ax |
; enable Statistics |
mov ax, (10101b shl 11) |
out dx, ax |
; set indication |
mov ax, (1111b shl 11) or 0x6c6 |
out dx, ax |
; acknowledge (clear) every interrupt indicator |
mov ax, (1101b shl 11) or 0x661 |
out dx, ax |
; switch to register window 2 |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 |
out dx, ax |
; write MAC addres back into the station address registers |
lea edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO] |
mov esi, node_addr |
cld |
outsw |
add edx, 2 |
outsw |
add edx, 2 |
outsw |
add edx, 2 |
; clear station mask |
xor eax, eax |
out dx, ax |
add edx, 2 |
out dx, ax |
add edx, 2 |
out dx, ax |
; switch to register window 6 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+6 |
out dx, ax |
; clear all statistics by reading |
lea edx, [ebp+E3C59X_REG_CARRIER_LOST] |
mov cl, 9 |
.stat_clearing_loop: |
in al, dx |
inc edx |
dec cl |
jns .stat_clearing_loop |
in ax, dx |
add dx, 2 |
in ax, dx |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; clear BadSSD |
lea edx, [ebp+E3C59X_REG_BAD_SSD] |
in al, dx |
; clear extra statistics bit in NetworkDiagnostic |
lea edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC] |
in ax, dx |
or ax, 0x0040 |
out dx, ax |
; SetRxEarlyThreshold |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2) |
out dx, ax |
test byte [e3c59x_full_bus_master], 0xff |
jz .skip_boomerang_setting |
; set upRxEarlyEnable |
lea edx, [ebp+E3C59X_REG_DMA_CTRL] |
in eax, dx |
or eax, 0x20 |
out dx, eax |
; TxFreeThreshold |
lea edx, [ebp+E3C59X_REG_TX_FREE_THRESH] |
mov al, (E3C59X_MAX_ETH_PKT_SIZE / 256) |
out dx, al |
; program DnListPtr |
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] |
xor eax, eax |
out dx, eax |
.skip_boomerang_setting: |
; initialization |
call e3c59x_rx_reset |
call e3c59x_tx_reset |
call e3c59x_set_active_port |
call e3c59x_rx_reset |
call e3c59x_tx_reset |
; switch to register window 5 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 |
out dx, ax |
; program RxFilter for promiscuous operation |
mov ax, (10000b shl 11) |
lea edx, [ebp+E3C59X_REG_RX_FILTER] |
in al, dx |
or al, 1111b |
lea edx, [ebp+E3C59X_REG_COMMAND] |
out dx, ax |
; switch to register window 4 |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
; wait for linkDetect |
lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] |
mov cl, 20 ; wait for max 2s |
mov esi, 100 ; 100ms |
.link_detect_loop: |
call delay_ms |
in ax, dx |
test ah, 1000b ; linkDetect |
jnz @f |
dec cl |
jnz .link_detect_loop |
@@: |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
if defined E3C59X_DEBUG |
call e3c59x_debug |
end if ; defined E3C59X_DEBUG |
ret |
;*************************************************************************** |
; Function |
; e3c59x_global_reset |
; Description |
; resets the device |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; ax, ecx, edx, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_global_reset: |
; GlobalReset |
lea edx, [ebp+E3C59X_REG_COMMAND] |
xor eax, eax |
; or al, 0x14 |
out dx, ax |
; wait for GlobalReset to complete |
mov ecx, 64000 |
.global_reset_loop: |
in ax, dx |
test ah, 10000b ; check CmdInProgress |
jz .finish |
dec ecx |
jnz .global_reset_loop |
.finish: |
; wait for 2 seconds for NIC to boot |
mov esi, 2000 ; 2000ms = 2s |
push ebp |
call delay_ms |
pop ebp |
ret |
;*************************************************************************** |
; Function |
; e3c59x_tx_reset |
; Description |
; resets and enables transmitter engine |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; ax, ecx, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_tx_reset: |
; TxReset |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (01011b shl 11) |
out dx, ax |
; wait for TxReset to complete |
mov ecx, 2000 |
.tx_reset_loop: |
in ax, dx |
test ah, 10000b ; check CmdInProgress |
jz .tx_enable |
dec ecx |
jns .tx_reset_loop |
test byte [e3c59x_full_bus_master], 0xff |
jz .tx_enable |
; init last_dpd |
mov dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE |
mov dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE |
.tx_enable: |
mov ax, (01001b shl 11) ; TxEnable |
out dx, ax |
ret |
;*************************************************************************** |
; Function |
; e3c59x_rx_reset |
; Description |
; resets and enables receiver engine |
; Parameters: |
; ebp - io_addr |
; Return value: |
; Destroyed registers |
; eax, ebx, ecx, edx, edi, esi |
; |
;*************************************************************************** |
align 4 |
e3c59x_rx_reset: |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (0101b shl 11) or 0x4 ; RxReset |
out dx, ax |
; wait for RxReset to complete |
mov ecx, 200000 |
.rx_reset_loop: |
in ax, dx |
test ah, 10000b ; check CmdInProgress |
jz .setup_upd |
dec ecx |
jns .rx_reset_loop |
.setup_upd: |
; check if full bus mastering |
test byte [e3c59x_full_bus_master], 0xff |
jz .rx_enable |
; create upd ring |
mov eax, e3c59x_upd_buff |
zero_to_virt eax |
mov [e3c59x_curr_upd], eax |
mov esi, eax |
virt_to_dma esi |
mov edi, e3c59x_rx_buff |
zero_to_dma edi |
mov ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE |
zero_to_virt ebx |
mov cl, E3C59X_NUM_RX_DESC-1 |
.upd_loop: |
mov [ebx+E3C59X_UPD_UP_NEXT_PTR], esi |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
mov [eax+E3C59X_UPD_UP_FRAG_ADDR], edi |
mov dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31) |
add edi, E3C59X_MAX_ETH_FRAME_SIZE |
add esi, E3C59X_UPD_SIZE |
mov ebx, eax |
add eax, E3C59X_UPD_SIZE |
dec cl |
jns .upd_loop |
mov eax, e3c59x_upd_buff |
zero_to_dma eax |
lea edx, [ebp+E3C59X_REG_UP_LIST_PTR] |
out dx, eax ; write E3C59X_REG_UP_LIST_PTR |
lea edx, [ebp+E3C59X_REG_COMMAND] |
.rx_enable: |
mov ax, (00100b shl 11) ; RxEnable |
out dx, ax |
ret |
;*************************************************************************** |
; Function |
; e3c59x_write_eeprom |
; Description |
; reads eeprom |
; Note : the caller must switch to the register window 0 |
; before calling this function |
; Parameters: |
; ax - register to be read (only the first 63 words can be read) |
; cx - value to be read into the register |
; Return value: |
; ax - word read |
; Destroyed registers |
; ax, ebx, edx |
; |
;*************************************************************************** |
; align 4 |
;e3c59x_write_eeprom: |
; mov edx, [io_addr] |
; add edx, E3C59X_REG_EEPROM_COMMAND |
; cmp ah, 11b |
; ja .finish ; address may have a value of maximal 1023 |
; shl ax, 2 |
; shr al, 2 |
; push eax |
;; wait for busy |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .write_enable |
; dec ebx |
; jns @r |
;; write enable |
;.write_enable: |
; xor eax, eax |
; mov eax, (11b shl 4) |
; out dx, ax |
;; wait for busy |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .erase_loop |
; dec ebx |
; jns @r |
;.erase_loop: |
; pop eax |
; push eax |
; or ax, (11b shl 6) ; erase register |
; out dx, ax |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .write_reg |
; dec ebx |
; jns @r |
;.write_reg: |
; add edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND |
; mov eax, ecx |
; out dx, ax |
;; write enable |
; add edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA |
; xor eax, eax |
; mov eax, (11b shl 4) |
; out dx, ax |
; wait for busy |
; mov ebx, 0xffff |
;@@: |
; in ax, dx |
; test ah, 0x80 |
; jz .issue_write_reg |
; dec ebx |
; jns @r |
;.issue_write_reg: |
; pop eax |
; or ax, 01b shl 6 |
; out dx, ax |
;.finish: |
; ret |
;*************************************************************************** |
; Function |
; e3c59x_read_eeprom |
; Description |
; reads eeprom |
; Parameters: |
; ax - register to be read (only the first 63 words can be read) |
; ebp - io_addr |
; Return value: |
; ax - word read |
; Destroyed registers |
; ax, ebx, edx, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_read_eeprom: |
push eax |
; switch to register window 0 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+0 |
out dx, ax |
pop eax |
and ax, 111111b ; take only the first 6 bits into account |
movzx ebx, byte [e3c59x_ver_id] |
test word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT |
jz @f |
add ax, 0x230 ; hardware constant |
jmp .read |
@@: |
add ax, E3C59X_EEPROM_CMD_READ |
test word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET |
jz .read |
add ax, 0x30 |
.read: |
lea edx, [ebp+E3C59X_REG_EEPROM_COMMAND] |
out dx, ax |
mov ebx, 0xffff ; duration of about 162 us ;-) |
.wait_for_reading: |
in ax, dx |
test ah, 0x80 ; check bit eepromBusy |
jz .read_data |
dec ebx |
jns .wait_for_reading |
.read_data: |
lea edx, [ebp+E3C59X_REG_EEPROM_DATA] |
in ax, dx |
ret |
;*************************************************************************** |
; Function |
; e3c59x_mdio_sync |
; Description |
; initial synchronization |
; Parameters |
; ebp - io_addr |
; Return value |
; Destroyed registers |
; ax, edx, cl |
; |
;*************************************************************************** |
align 4 |
e3c59x_mdio_sync: |
; switch to register window 4 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 |
out dx, ax |
cmp byte [e3c59x_preamble], 0 |
je .no_preamble |
; send 32 logic ones |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
mov cl, 31 |
.loop: |
mov ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR) |
out dx, ax |
in ax, dx ; delay |
mov ax, (1 shl E3C59X_BIT_MGMT_DATA) \ |
or (1 shl E3C59X_BIT_MGMT_DIR) \ |
or (1 shl E3C59X_BIT_MGMT_CLK) |
out dx, ax |
in ax, dx ; delay |
dec cl |
jns .loop |
.no_preamble: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_mdio_read |
; Description |
; read MII register |
; see page 16 in D83840A.pdf |
; Parameters |
; ah - PHY addr |
; al - register addr |
; ebp - io_addr |
; Return value |
; ax - register read |
; Destroyed registers |
; eax, ebx, cx, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_mdio_read: |
push eax |
call e3c59x_mdio_sync ; returns with window #4 |
pop eax |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
shl al, 3 |
shr ax, 3 |
and ax, not E3C59X_MII_CMD_MASK |
or ax, E3C59X_MII_CMD_READ |
mov ebx, eax |
xor ecx, ecx |
mov cl, 13 |
.cmd_loop: |
mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii |
bt ebx, ecx |
jnc .zero_bit |
or al, (1 shl E3C59X_BIT_MGMT_DATA) |
.zero_bit: |
out dx, ax |
push eax |
in ax, dx ; delay |
pop eax |
or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write |
out dx, ax |
in ax, dx ; delay |
dec cl |
jns .cmd_loop |
; read data (18 bits with the two transition bits) |
mov cl, 17 |
xor ebx, ebx |
.read_loop: |
shl ebx, 1 |
xor eax, eax ; read comand |
out dx, ax |
in ax, dx ; delay |
in ax, dx |
test al, (1 shl E3C59X_BIT_MGMT_DATA) |
jz .dont_set |
inc ebx |
.dont_set: |
mov ax, (1 shl E3C59X_BIT_MGMT_CLK) |
out dx, ax |
in ax, dx ; delay |
dec cl |
jns .read_loop |
mov eax, ebx |
ret |
;*************************************************************************** |
; Function |
; e3c59x_mdio_write |
; Description |
; write MII register |
; see page 16 in D83840A.pdf |
; Parameters |
; ah - PHY addr |
; al - register addr |
; bx - word to be written |
; ebp - io_addr |
; Return value |
; ax - register read |
; Destroyed registers |
; eax, ebx, cx, edx |
; |
;*************************************************************************** |
align 4 |
e3c59x_mdio_write: |
push eax |
call e3c59x_mdio_sync |
pop eax |
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] |
shl al, 3 |
shr ax, 3 |
and ax, not E3C59X_MII_CMD_MASK |
or ax, E3C59X_MII_CMD_WRITE |
shl eax, 2 |
or eax, 10b ; transition bits |
shl eax, 16 |
mov ax, bx |
mov ebx, eax |
mov ecx, 31 |
.cmd_loop: |
mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii |
bt ebx, ecx |
jnc .zero_bit |
or al, (1 shl E3C59X_BIT_MGMT_DATA) |
.zero_bit: |
out dx, ax |
push eax |
in ax, dx ; delay |
pop eax |
or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write |
out dx, ax |
in ax, dx ; delay |
dec ecx |
jns .cmd_loop |
ret |
;*************************************************************************** |
; Function |
; e3c59x_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; edi - Pointer to 48 bit destination address |
; bx - Type of packet |
; ecx - size of packet |
; esi - pointer to packet data |
; ebp - io_addr |
; Destroyed registers |
; eax, ecx, edx, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_transmit: |
jmp dword [e3c59x_transmit_function] |
;*************************************************************************** |
; Function |
; e3c59x_check_tx_status |
; Description |
; Checks TxStatus queue. |
; Return value |
; al - 0 no error was found |
; al - 1 error was found TxReset is needed |
; Destroyed registers |
; eax, ecx, edx, ebp |
; |
;*************************************************************************** |
e3c59x_check_tx_status: |
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC |
; clear TxStatus queue |
lea edx, [ebp+E3C59X_REG_TX_STATUS] |
mov cl, 31 ; max number of queue entries |
.tx_status_loop: |
in al, dx |
test al, al |
jz .finish ; no error |
test al, 0x3f |
jnz .finish ; error |
.no_error_found: |
; clear current TxStatus entry which advances the next one |
xor al, al |
out dx, al |
dec cl |
jns .tx_status_loop |
.finish: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_vortex_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; edi - Pointer to 48 bit destination address |
; bx - Type of packet |
; ecx - size of packet |
; esi - pointer to packet data |
; ebp - io_addr |
; Destroyed registers |
; eax, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_vortex_transmit: |
push ecx |
call e3c59x_check_tx_status |
pop ecx |
test al, al |
jz .no_error_found |
jmp e3c59x_tx_reset |
.no_error_found: |
; switch to register window 7 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 |
out dx, ax |
; check for master operation in progress |
lea edx, [ebp+E3C59X_REG_MASTER_STATUS] |
in ax, dx |
test ah, 0x80 |
jnz .finish ; no DMA for sending |
; dword boundary correction |
cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE |
ja .finish ; packet is too long |
; write Frame Start Header |
mov eax, ecx |
; add header length and extend the complete length to dword boundary |
add eax, ETH_HLEN+3 |
and eax, not 3 |
lea edx, [ebp+E3C59X_REG_TX_DATA] |
out dx, eax |
; prepare the complete frame |
push esi |
mov esi, edi |
mov edi, e3c59x_tx_buff |
zero_to_virt edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi, node_addr |
movsd |
movsw |
; copy packet type |
mov [edi], bx |
add edi, 2 |
; copy packet data |
pop esi |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
and ecx, 3 |
rep movsb |
mov ecx, eax |
; program frame address to be sent |
lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] |
mov eax, e3c59x_tx_buff |
zero_to_dma eax |
out dx, eax |
; program frame length |
lea edx, [ebp+E3C59X_REG_MASTER_LEN] |
mov eax, ecx |
out dx, ax |
; start DMA Down |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10100b shl 11) + 1 ; StartDMADown |
out dx, ax |
.finish: |
ret |
;*************************************************************************** |
; Function |
; e3c59x_boomerang_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; edi - Pointer to 48 bit destination address |
; bx - Type of packet |
; ecx - size of packet |
; esi - pointer to packet data |
; ebp - io_addr |
; Destroyed registers |
; eax, ebx, ecx, edx, esi, edi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_boomerang_transmit: |
push ecx |
call e3c59x_check_tx_status |
pop ecx |
test al, al |
jz .no_error_found |
jmp e3c59x_tx_reset |
.no_error_found: |
cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE |
ja .finish ; packet is too long |
; calculate descriptor address |
mov eax, [e3c59x_prev_dpd] |
cmp eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE |
jb @f |
; wrap around |
mov eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE |
@@: |
add eax, E3C59X_DPD_SIZE |
zero_to_virt eax |
push eax |
; check DnListPtr |
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] |
in eax, dx |
; mark if Dn_List_Ptr is cleared |
test eax, eax |
setz [e3c59x_dn_list_ptr_cleared] |
; finish if no more free descriptor is available - FIXME! |
cmp eax, [esp] |
pop eax |
jz .finish |
push eax esi |
mov esi, edi |
; calculate tx_buffer address |
mov edi, [e3c59x_prev_tx_frame] |
cmp edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE |
jb @f |
; wrap around |
mov edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE |
@@: |
add edi, E3C59X_MAX_ETH_FRAME_SIZE |
zero_to_virt edi |
mov eax, edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi, node_addr |
movsd |
movsw |
; copy packet type |
mov [edi], bx |
add edi, 2 |
; copy packet data |
pop esi |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
push ecx |
and ecx, 3 |
rep movsb |
; padding, do we really need it? |
pop ecx |
add ecx, ETH_HLEN |
cmp ecx, ETH_ZLEN |
jae @f |
mov ecx, ETH_ZLEN |
@@: |
; calculate |
mov ebx, ecx |
test byte [e3c59x_has_hwcksm], 0xff |
jz @f |
or ebx, (1 shl 26) ; set AddTcpChecksum |
@@: |
or ebx, 0x8000 ; transmission complete notification |
or ecx, 0x80000000 ; last fragment |
; program DPD |
mov edi, eax |
pop eax |
and dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0 |
mov dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx |
virt_to_dma edi |
mov dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi |
mov [eax+E3C59X_DPD_DN_FRAG_LEN], ecx |
; calculate physical address |
virt_to_dma eax |
push eax |
cmp byte [e3c59x_dn_list_ptr_cleared], 0 |
jz .add_to_list |
; write Dn_List_Ptr |
out dx, eax |
jmp .finish |
.add_to_list: |
; DnStall |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, ((110b shl 11)+2) |
out dx, ax |
; wait for DnStall to complete |
mov ecx, 6000 |
.wait_for_stall: |
in ax, dx ; read E3C59X_REG_INT_STATUS |
test ah, 10000b |
jz .dnstall_ok |
dec ecx |
jnz .wait_for_stall |
.dnstall_ok: |
pop eax |
push eax |
mov ebx, [e3c59x_prev_dpd] |
zero_to_virt ebx |
mov [ebx], eax |
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] |
in eax, dx |
test eax, eax |
jnz .dnunstall |
; if Dn_List_Ptr has been cleared fill it up |
pop eax |
push eax |
out dx, eax |
.dnunstall: |
; DnUnStall |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, ((110b shl 11)+3) |
out dx, ax |
.finish: |
pop eax |
dma_to_zero eax |
mov [e3c59x_prev_dpd], eax |
dma_to_zero edi |
mov [e3c59x_prev_tx_frame], edi |
ret |
;*************************************************************************** |
; Function |
; e3c59x_poll |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Destroyed registers |
; eax, ebx, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_poll: |
jmp dword [e3c59x_receive_function] |
;*************************************************************************** |
; Function |
; e3c59x_vortex_poll |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 ; no packet received |
; al - 1 ; packet received |
; Destroyed registers |
; eax, ebx, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_vortex_poll: |
and word [eth_rx_data_len], 0 ; assume no packet received |
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC |
.rx_status_loop: |
; examine RxStatus |
lea edx, [ebp+E3C59X_REG_RX_STATUS] |
in ax, dx |
test ax, ax |
jz .finish |
test ah, 0x80 ; rxIncomplete |
jz .check_error |
jmp .finish |
.check_error: |
test ah, 0x40 |
jz .check_length |
; discard the top frame received advancing the next one |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (01000b shl 11) |
out dx, ax |
jmp .rx_status_loop |
.check_length: |
and eax, 0x1fff |
cmp eax, E3C59X_MAX_ETH_PKT_SIZE |
ja .discard_frame ; frame is too long discard it |
.check_dma: |
push eax |
; switch to register window 7 |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 |
out dx, ax |
; check for master operation in progress |
lea edx, [ebp+E3C59X_REG_MASTER_STATUS] |
in ax, dx |
test ah, 0x80 |
jz .read_frame ; no DMA for receiving |
pop eax |
jmp .finish |
.read_frame: |
; program buffer address to read in |
lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] |
if defined E3C59X_LINUX |
mov eax, e3c59x_rx_buff |
zero_to_dma eax |
else |
mov eax, Ether_buffer |
end if |
out dx, eax |
; program frame length |
lea edx, [ebp+E3C59X_REG_MASTER_LEN] |
mov ax, 1560 |
out dx, ax |
; start DMA Up |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (10100b shl 11) ; StartDMAUp |
out dx, ax |
; check for master operation in progress |
.dma_loop: |
lea edx, [ebp+E3C59X_REG_MASTER_STATUS] |
in ax, dx |
test ah, 0x80 |
jnz .dma_loop |
; registrate the received packet length |
pop eax |
mov word [eth_rx_data_len], ax |
; discard the top frame received |
.discard_frame: |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, (01000b shl 11) |
out dx, ax |
.finish: |
; set return value |
cmp word [eth_rx_data_len], 0 |
setne al |
ret |
;*************************************************************************** |
; Function |
; e3c59x_boomerang_poll |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Parameters |
; ebp - io_addr |
; Return value |
; al - 0 ; no packet received |
; al - 1 ; packet received |
; Destroyed registers |
; eax, edx, ecx, edi, esi, ebp |
; |
;*************************************************************************** |
align 4 |
e3c59x_boomerang_poll: |
and word [eth_rx_data_len], 0 ; assume no packet received |
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC |
; check if packet is uploaded |
mov eax, [e3c59x_curr_upd] |
test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete |
jnz .check_error |
jmp .finish |
; packet is uploaded check for any error |
.check_error: |
test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError |
jz .copy_packet_length |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
jmp .finish |
.copy_packet_length: |
mov ecx, [eax+E3C59X_UPD_PKT_STATUS] |
and ecx, 0x1fff |
cmp ecx, E3C59X_MAX_ETH_PKT_SIZE |
jbe .copy_packet |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
jmp .finish |
.copy_packet: |
push ecx |
mov word [eth_rx_data_len], cx |
mov esi, [eax+E3C59X_UPD_UP_FRAG_ADDR] |
dma_to_virt esi |
mov edi, Ether_buffer |
shr ecx, 2 ; first copy dword-wise |
cld |
rep movsd ; copy the dwords |
pop ecx |
and ecx, 3 |
rep movsb ; copy the rest bytes |
mov eax, [e3c59x_curr_upd] |
and dword [eax+E3C59X_UPD_PKT_STATUS], 0 |
virt_to_zero eax |
cmp eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE |
jb .no_wrap |
; wrap around |
mov eax, e3c59x_upd_buff-E3C59X_UPD_SIZE |
.no_wrap: |
add eax, E3C59X_UPD_SIZE |
zero_to_virt eax |
mov [e3c59x_curr_upd], eax |
.finish: |
; check if the NIC is in the upStall state |
lea edx, [ebp+E3C59X_REG_UP_PKT_STATUS] |
in eax, dx |
test ah, 0x20 ; UpStalled |
jz .noUpUnStall |
; issue upUnStall command |
lea edx, [ebp+E3C59X_REG_COMMAND] |
mov ax, ((110b shl 11)+1) ; upUnStall |
out dx, ax |
.noUpUnStall: |
; set return value |
cmp word [eth_rx_data_len], 0 |
setnz al |
ret |
/kernel/branches/gfx_kernel/network/eth_drv/ethernet.inc |
---|
0,0 → 1,1701 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; ETHERNET.INC ;; |
;; ;; |
;; Ethernet network layer for Menuet OS ;; |
;; ;; |
;; Version 0.4 22 September 2003 ;; |
;; ;; |
;; This file contains the following: ;; |
;; PCI bus scanning for valid devices ;; |
;; Table of supported ethernet drivers ;; |
;; Code to identify and activate a supported driver ;; |
;; ARP handler ;; |
;; Driver interface to the IP layer ;; |
;; Gateway support ;; |
;; ;; |
;; Individual driver files are included here ;; |
;; ;; |
;; The PCI bus scanning code was ported from the etherboot ;; |
;; 5.0.6 project. The copyright statement for that code is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************** |
; Interface |
; ethernet_driver called by stack_handler in stack.inc |
; eth_probe called by app_stack_handler in stack.inc |
; |
;******************************************************************** |
; Some useful information on data structures |
; Ethernet Packet - ARP Request example |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Dest H/W Address | |
; | ( 14 byte header ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Source H/W Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Protocol - ARP 08 06 | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | H/W Type 00 01 | Protocol Type 08 00 | |
; | ( ARP Request packet ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | HLen 0x06 | PLen 0x04 | OpCode 00 01 | |
; | ( 0001 for request, 0002 for reply ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Source Hardware Address ( MAC Address ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Source IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Destination Hardware Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Destination IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; Include individual drivers source files at this point. |
; If you create a new driver, include it below. |
include "rtl8029.inc" |
include "i8255x.inc" |
include "rtl8139.inc" |
include "3c59x.inc" |
include "sis900.inc" |
include "pcnet32.inc" |
; DEBUGGING_STATE enables or disables output of received and transmitted |
; data over the serial port |
DEBUGGING_ENABLED equ 1 |
DEBUGGING_DISABLED equ 0 |
DEBUGGING_STATE equ DEBUGGING_ENABLED |
; PCICards |
; ======== |
; PCI vendor and hardware types for hardware supported by the above drivers |
; If you add a driver, ensure you update this datastructure, otherwise the |
; card will not be probed. |
; Each driver is defined by 4 double words. These are |
; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction |
; The last entry must be kept at all zeros, to indicate the end of the list |
; As a PCI driver may support more than one hardware implementation, there may |
; be several lines which refer to the same functions. |
; The first driver found on the PCI bus will be the one used. |
PCICARDS_ENTRY_SIZE equ 20 ; Size of each PCICARDS entry |
iglobal |
PCICards: |
dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit |
dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit |
dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit |
dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit |
dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit |
dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit |
dd 0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit |
dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
; /+/ Íîâûå âåíäîðû ñåòåâûõ êàðò íà áàçå rtl8139 |
dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit |
; /-/ |
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit |
dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit |
dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit |
dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit |
dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit |
; following card is untested |
dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit |
dd 0,0,0,0,0 ; end of list marker, do not remove |
endg |
; PCI Bus defines |
PCI_HEADER_TYPE equ 0x0e ;8 bit |
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit |
PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits |
PCI_BASE_ADDRESS_SPACE_IO equ 0x01 |
PCI_VENDOR_ID equ 0x00 ;16 bit |
PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC |
ETHER_IP equ 0x0008 ; Reversed from 0800 for intel |
ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel |
ETHER_RARP equ 0x3580 |
ARP_REQ_OPCODE equ 0x0100 |
ARP_REP_OPCODE equ 0x0200 |
uglobal |
arp_rx_count: dd 0 |
ip_rx_count: dd 0 |
dumped_rx_count: dd 0 |
ip_tx_count: dd 0 |
node_addr: db 0,0,0,0,0,0 |
eth_rx_data_len: dw 0 |
eth_status: dd 0 |
io_addr: dd 0 |
hdrtype: db 0 |
vendor_device: dd 0 |
pci_data: dd 0 |
pci_dev: dd 0 |
pci_bus: dd 0 |
; These will hold pointers to the selected driver functions |
drvr_probe: dd 0 |
drvr_reset: dd 0 |
drvr_poll: dd 0 |
drvr_transmit: dd 0 |
; These hold the destination Host identity for ARP responses |
remote_ip_add: dd 0 |
remote_hw_add: db 0, 0, 0, 0, 0, 0 |
endg |
iglobal |
broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff |
subnet_mask: dd 0x00ffffff |
endg |
uglobal |
; This is used by getMACfromIP |
MACAddress: db 0,0,0,0,0,0 |
gateway_ip: db 0, 0, 0, 0 |
dns_ip: dd 0 |
endg |
; The follow is the ARP Table. |
; This table must be manually updated and the kernel recompilied if |
; changes are made to it. |
; ARP_TABLE_SIZE defines the size of the table |
; ARP_TABLE_ENTRIES defines the number of entries in the table |
; Each entry is 10 bytes: 4 Byte IP address, 6 byte MAC Address, |
; 2 bytes status, 2 bytes TTL ( in seconds ) |
; Empty entries are filled with zeros |
; The TTL field is decremented every second, and is deleted when it |
; reaches 0. It is refreshed every time a packet is received |
; If the TTL field is 0xFFFF it is a permanent entry and is never deleted |
; The status field can be the following values |
; 0x0000 entry not used |
; 0x0001 entry holds a valid mapping |
; 0x0002 entry contains an IP address, awaiting ARP response |
; 0x0003 No response received to ARP request. |
; The last status value is provided to allow the network layer to delete |
; a packet that is queued awaiting an ARP response |
ARP_NO_ENTRY equ 0 |
ARP_VALID_MAPPING equ 1 |
ARP_AWAITING_RESPONSE equ 2 |
ARP_RESPONSE_TIMEOUT equ 3 |
ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry |
ARP_TABLE_SIZE equ 20 ; Size of table |
ARP_TABLE_ENTRIES equ 0 ; Inital, hardcoded entries |
uglobal |
ARPTable: |
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0 |
endg |
iglobal |
NumARP: db ARP_TABLE_ENTRIES |
endg |
;*************************************************************************** |
; Function |
; eth_probe |
; Description |
; Searches for an ethernet card. If found, the card is enabled and |
; the ethernet -> IP link established |
; |
; This function scans the PCI bus looking for a supported device. |
; ISA bus is currently not supported. |
; |
; eax is 0 if no hardware found |
;*************************************************************************** |
eth_probe: |
; Find a card on the PCI bus, and get it's address |
call scan_bus ; Find the ethernet cards PIC address |
xor eax, eax |
cmp [io_addr], eax |
je ep_00x ; Return 0 in eax if no cards found |
call dword [drvr_probe] ; Call the drivers probe function |
mov eax, [io_addr] ; return a non zero value |
ep_00x: |
ret |
;*************************************************************************** |
; Function |
; ethernet_driver |
; |
; Description |
; The ethernet RX and TX handler |
; This is a kernel function, called by stack_handler |
; |
;*************************************************************************** |
ethernet_driver: |
; Do nothing if the driver is inactive |
cmp [ethernet_active], byte 0 |
je eth_exit |
call eth_rx |
call eth_tx |
eth_exit: |
ret |
;*************************************************************************** |
; Function |
; eth_rx |
; |
; Description |
; Polls the ethernet card for received data. Extracts if present |
; Depending on the Protocol within the packet: |
; ARP : Pass to ARP_handler. This may result in an ARP reply |
; being tx'ed |
; IP : Store in an IP buffer |
; |
;*************************************************************************** |
eth_rx: |
xor ax, ax |
mov [eth_rx_data_len], ax |
call dword [drvr_poll] ; Call the drivers poll function |
mov ax, [eth_rx_data_len] |
cmp ax, 0 |
je erx_exit |
if DEBUGGING_STATE = DEBUGGING_ENABLED |
pusha |
mov eax, 0 ;Indicate that this is a received packet |
mov cx, [eth_rx_data_len] |
mov esi, Ether_buffer |
cmp word [esi + 12], ETHER_IP |
jnz erxd_done |
; cmp byte [esi + 14 + 9], 0x06 ; TCP |
; jnz erxd_done |
call eth_dump |
erxd_done: |
popa |
end if |
; Check the protocol. Call appropriate handler |
mov eax, Ether_buffer |
add eax, 12 ; The address of the protocol word |
mov ax, [eax] |
cmp ax, ETHER_ARP |
je erx_001 ; It is ARP |
cmp ax, ETHER_IP |
je erx_002 ; It's IP |
; inc dword [dumped_rx_count] |
jmp erx_exit ; If not IP or ARP, ignore |
erx_001: |
mov eax, [arp_rx_count] |
inc eax |
mov [arp_rx_count], eax |
; At this point, the packet is still in the Ether_buffer |
call arp_handler |
jmp erx_exit |
erx_002: |
mov eax, [ip_rx_count] |
inc eax |
mov [ip_rx_count], eax |
; Check to see if the MAC address is in our arp table |
; refresh the arp ttl if so |
mov esi, Ether_buffer |
add esi, 6 |
call refreshARP |
call ether_IP_handler |
jmp erx_exit |
erx_exit: |
ret |
;*************************************************************************** |
; Function |
; eth_tx |
; |
; Description |
; Looks at the NET1OUT_QUEUE for data to send. |
; Stores that destination IP in a location used by the tx routine |
; Looks up the MAC address in the ARP table; stores that where |
; the tx routine can get it |
; Get the length of the data. Store that where the tx routine wants it |
; Call tx |
; Places buffer on empty queue when the tx routine finished |
; |
;*************************************************************************** |
eth_tx: |
; Look for a buffer to tx |
mov eax, NET1OUT_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je eth_exit ; Exit if no buffer available |
push eax |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
; Extract the destination IP |
; find the destination IP in the ARP table, get MAC |
; store this MAC in 'MACAddress' |
mov ebx, eax ; Save buffer address |
mov edx, [ebx + 16] ; get destination address |
; If the destination address is 255.255.255.255, |
; set the MACAddress to all ones ( broadcast ) |
mov [MACAddress], dword 0xffffffff |
mov [MACAddress + 4], word 0xffff |
cmp edx, 0xffffffff |
je etx_send ; If it is broadcast, just send |
call getMACfromIP ; Get the MAC address. |
cmp eax, ARP_VALID_MAPPING |
jz etx_send |
; No valid entry. Are we waiting for a response? |
cmp eax, ARP_AWAITING_RESPONSE |
jne etx_001 |
; Re-queue the packet, and exit |
pop ebx |
mov eax, NET1OUT_QUEUE |
call queue |
jmp etx_exit |
etx_001: |
; HAs the request been sent, but timed out? |
cmp eax, ARP_RESPONSE_TIMEOUT |
jne etx_002 |
pop eax |
call freeBuff |
jmp etx_exit |
etx_002: |
; There is no entry. Re queue the request, and ask ARP to send a request |
; IP address is in edx |
push edx |
call arp_request |
pop ebx |
; Add an entry in the ARP table, awaiting response |
cmp byte [NumARP], ARP_TABLE_SIZE |
je etx_003 ; We cannot add a new entry in the table |
inc byte [NumARP] |
movzx eax, byte [NumARP] |
mov ecx, ARP_ENTRY_SIZE |
mul ecx |
sub eax, ARP_ENTRY_SIZE |
mov [eax + ARPTable], ebx |
xor ebx, ebx |
mov [eax + ARPTable + 4], ebx |
mov [eax + ARPTable + 8], bx |
; set the status field up - awaiting response |
mov cl, 0x00 |
mov [eax + ARPTable + 10], cl |
mov cl, 0x02 |
mov [eax + ARPTable + 11], cl |
; Initialise the time to live field - 10s |
mov cx, 0x000A |
mov [eax + ARPTable + 12], cx |
etx_003: |
pop ebx ; Get the buffer back |
mov eax, NET1OUT_QUEUE |
call queue |
jmp etx_exit |
etx_send: |
xor ecx, ecx |
mov ch, [ebx+2] |
mov cl, [ebx+3] ; ; Size of IP packet to send |
mov esi, ebx |
mov edi, MACAddress |
if DEBUGGING_STATE = DEBUGGING_ENABLED |
pusha |
mov cx, 42 |
mov eax, 1 ; Indicate that this is a tx packet |
call eth_dump |
popa |
end if |
mov bx, ETHER_IP |
call dword [drvr_transmit] ; Call the drivers transmit function |
; OK, we have sent a packet, so increment the count |
inc dword [ip_tx_count] |
; And finally, return the buffer to the free queue |
pop eax |
call freeBuff |
etx_exit: |
ret |
;*************************************************************************** |
; Function |
; ether_IP_handler |
; |
; Description |
; Called when an IP ethernet packet is received on the ethernet |
; Header + Data is in Ether_buffer[] |
; We just need to get a buffer from the 'free' queue, and |
; store the packet in it, then insert the packet number into the |
; IPRX queue. |
; If no queue entry is available, the packet is silently discarded |
; All registers may be destroyed |
; |
;*************************************************************************** |
ether_IP_handler: |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je eiph00x |
; convert buffer pointer eax to the absolute address |
push eax |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edi, eax |
; get a pointer to the start of the DATA |
mov esi, Ether_buffer + 14 |
; Now store it all away |
mov ecx, IPBUFFSIZE / 4 ; Copy all of the available |
; data across - worse case |
cld |
rep movsd |
; And finally, place the buffer in the IPRX queue |
pop ebx |
mov eax, IPIN_QUEUE |
call queue |
eiph00x: |
ret |
;*************************************************************************** |
; |
; ARP CODE FOLLOWS |
; |
; The ARP code is used by ethernet drivers to translate an destination |
; IP address into an ethernet hardware address. Functions to broadcast |
; requests and handle response are (or will be) here. |
; The IP layer has no knowledge of ARP, as this is a network interface |
; issue |
; |
;*************************************************************************** |
;*************************************************************************** |
; Function |
; arp_timer |
; |
; Description |
; Called every 1s |
; It is responsible for removing expired routes |
; All registers may be destroyed |
; |
;*************************************************************************** |
arp_timer: |
; loop through all the ARP entries, decrementing each one |
; that doesn't have a TTL of 0xFFFF |
movzx eax, byte [NumARP] |
arp_001: |
cmp eax, 0 |
je arp_003 |
push eax |
dec eax |
mov ecx, ARP_ENTRY_SIZE |
mul ecx |
cmp word [ eax + ARPTable + 12], 0xFFFF |
je arp_002 |
cmp word [ eax + ARPTable + 12], 0 |
je arp_002 |
dec word [eax + ARPTable + 12] |
arp_002: |
pop eax |
dec eax |
jmp arp_001 |
; Now, look for entries with a TTL of 0 |
; Valid entries and response timeout entries get removed |
; awaiting response gets converted into a response timeout, with a |
; short life time - this allows queued packets to be flushed |
arp_003: |
movzx edx, byte [NumARP] |
cmp edx, 0 |
je arp_exit |
; EDX holds the # of entries to search through |
mov eax, 0 |
arp_005: |
cmp word [ eax + ARPTable + 12], 0 |
jne arp_004 |
; If it's status code is 0001 or 0003, delete the entry |
cmp word [eax + ARPTable + 10], 0x0100 |
je arp_007 |
cmp word [eax + ARPTable + 10], 0x0300 |
je arp_007 |
; The only other valid code is 0002 - indicating a |
; timeout while waiting for a response. Change the |
; entry to response timed out |
mov [eax + ARPTable + 10], word 0x0300 |
mov [eax + ARPTable + 12], word 0x000A |
jmp arp_004 |
arp_007: |
; Delete this entry |
mov edi, ARPTable |
add edi, eax |
mov esi, edi |
add esi, ARP_ENTRY_SIZE |
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE |
sub ecx, eax |
rep movsb |
dec byte [NumARP] |
jmp arp_006 |
arp_004: |
add eax, ARP_ENTRY_SIZE |
arp_006: |
dec edx |
cmp edx, 0 |
jne arp_005 |
arp_exit: |
ret |
;*************************************************************************** |
; Function |
; arp_request |
; |
; Description |
; Sends an ARP request on the ethernet |
; The requested IP address is in edx |
; All registers may be destroyed |
; |
;*************************************************************************** |
arp_request: |
mov ebx, Ether_buffer |
mov ax, 0x0100 |
mov [ebx], ax |
add ebx, 2 |
mov ax, 0x0008 |
mov [ebx], ax |
add ebx, 2 |
mov ax, 0x0406 |
mov [ebx], ax |
add ebx, 2 |
mov ax, 0x0100 |
mov [ebx], ax |
add ebx, 2 |
mov ecx, node_addr |
mov eax, [ecx] |
mov [ebx], eax |
add ecx, 4 |
add ebx, 4 |
mov ax, [ecx] |
mov [ebx], ax |
add ebx, 2 |
mov eax, [stack_ip] |
mov [ebx], eax |
add ebx, 4 |
xor eax, eax |
mov [ebx], eax |
add ebx, 4 |
mov [ebx], ax |
add ebx, 2 |
mov [ebx], edx |
; Now, send it! |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
mov edi, broadcast_add |
;if DEBUGGING_STATE = DEBUGGING_ENABLED |
; pusha |
; mov eax, 1 ; Indicate that this is a tx packet |
; mov ecx, 28 |
; mov esi, Ether_buffer |
; call eth_dump |
; popa |
;end if |
mov bx, ETHER_ARP |
mov ecx, 28 |
mov esi, Ether_buffer |
call dword [drvr_transmit] ; Call the drivers transmit function |
ret |
;*************************************************************************** |
; Function |
; arp_handler |
; |
; Description |
; Called when an ARP packet is received on the ethernet |
; Header + Data is in Ether_buffer[] |
; It looks to see if the packet is a request to resolve this Hosts |
; IP address. If it is, send the ARP reply packet. |
; This Hosts IP address is in dword [stack_ip] ( in network format ) |
; This Hosts MAC address is in node_addr[6] |
; All registers may be destroyed |
; |
;*************************************************************************** |
arp_handler: |
; Is this a REQUEST? |
; Is this a request for My Host IP |
; Yes - So construct a response message. |
; Send this message to the ethernet card for transmission |
mov ebx, Ether_buffer |
mov edx, ebx |
add edx, 20 |
mov ax, [edx] |
cmp ax, ARP_REQ_OPCODE ; Is this a request packet? |
jne arph_resp ; No - so test for response |
mov edx, ebx |
add edx, 38 |
mov eax, [edx] |
cmp eax, [stack_ip] ; Is it looking for my IP address? |
jne arph_exit ; No - so quit now |
; OK, it is a request for my MAC address. Build the frame and send it |
; Save the important data from the original packet |
; remote MAC address first |
mov ecx, remote_hw_add |
mov edx, ebx |
add edx, 22 ; edx points to Source h/w address |
mov eax, [edx] |
mov [ecx], eax |
add edx, 4 |
add ecx, 4 |
mov ax, [edx] |
mov [ecx],ax |
; and also the remote IP address |
add edx, 2 |
mov eax,[edx] |
mov [remote_ip_add], eax |
; So now we can reuse the packet. ebx still holds the address of |
; the header + packet |
; We dont need the header ( first 14 bytes ) |
mov edx, ebx |
add edx, 20 |
mov ax, ARP_REP_OPCODE |
mov [edx], ax |
add edx, 2 |
mov ecx, node_addr |
mov eax, [ecx] |
mov [edx], eax |
add ecx, 4 |
add edx, 4 |
mov ax, [ecx] |
mov [edx], ax |
add edx, 2 |
mov eax, [stack_ip] |
mov [edx], eax |
add edx, 4 |
mov ecx, remote_hw_add |
mov eax, [ecx] |
mov [edx], eax |
add ecx, 4 |
add edx, 4 |
mov ax, [ecx] |
mov [edx], ax |
add edx, 2 |
mov eax, [remote_ip_add] |
mov [edx], eax |
; Now, send it! |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
mov edi, remote_hw_add |
;if DEBUGGING_STATE = DEBUGGING_ENABLED |
; pusha |
; mov eax, 1 ; Indicate that this is a tx packet |
; mov ecx, 28 |
; mov esi, Ether_buffer + 14 |
; call eth_dump |
; popa |
;end if |
mov bx, ETHER_ARP |
mov ecx, 28 |
mov esi, Ether_buffer + 14 |
call dword [drvr_transmit] ; Call the drivers transmit function |
jmp arph_exit |
arph_resp: |
cmp ax, ARP_REP_OPCODE ; Is this a replypacket? |
jne arph_resp ; No - so quit |
; This was a reply, probably directed at me. |
; save the remotes MAC & IP |
mov ecx, remote_hw_add |
mov edx, ebx |
add edx, 22 ; edx points to Source h/w address |
mov eax, [edx] |
mov [ecx], eax |
add edx, 4 |
add ecx, 4 |
mov ax, [edx] |
mov [ecx],ax |
; and also the remote IP address |
add edx, 2 |
mov eax,[edx] |
mov [remote_ip_add], eax |
; Now, add an entry in the table for this IP address if it doesn't exist |
push eax |
movzx eax, byte [NumARP] |
mov ecx, ARP_ENTRY_SIZE |
mul ecx |
pop edx |
movzx ecx, byte [NumARP] |
cmp ecx, 0 |
je arph_002 |
arph_001: |
sub eax, ARP_ENTRY_SIZE |
cmp [eax + ARPTable], edx |
loopnz arph_001 ; Return back if non match |
jnz arph_002 ; None found, add to end |
mov ecx, [remote_hw_add] |
mov [eax + ARPTable + 4], ecx |
mov cx, [remote_hw_add+4] |
mov [eax + ARPTable + 8], cx |
; specify the type - a valid entry |
mov cl, 0x00 |
mov [eax + ARPTable + 10], cl |
mov cl, 0x01 |
mov [eax + ARPTable + 11], cl |
; Initialise the time to live field - 1 hour |
mov cx, 0x0E10 |
mov [eax + ARPTable + 12], cx |
jmp arph_exit |
arph_002: |
cmp byte [NumARP], ARP_TABLE_SIZE |
je arph_exit |
inc byte [NumARP] |
movzx eax, byte [NumARP] |
mov ecx, ARP_ENTRY_SIZE |
mul ecx |
sub eax, ARP_ENTRY_SIZE |
mov ecx, [remote_ip_add] |
mov [eax + ARPTable], ecx |
mov ecx, [remote_hw_add] |
mov [eax + ARPTable + 4], ecx |
mov cx, [remote_hw_add+4] |
mov [eax + ARPTable + 8], cx |
mov cl, 0x00 |
mov [eax + ARPTable + 10], cl |
mov cl, 0x01 |
mov [eax + ARPTable + 11], cl |
; Initialise the time to live field - 1 hour |
mov cx, 0x0E10 |
mov [eax + ARPTable + 12], cx |
arph_exit: |
ret |
; pointer to MAC in esi |
refreshARP: |
mov ebx, [esi] |
mov dx, [esi+4] |
push edx |
movzx eax, byte [NumARP] |
mov ecx, ARP_ENTRY_SIZE |
mul ecx |
pop edx |
movzx ecx, byte [NumARP] |
cmp ecx, 0 |
je rf_exit |
rf_001: |
sub eax, ARP_ENTRY_SIZE |
cmp [eax + ARPTable+4], ebx |
je rf_002 |
loop rf_001 |
jmp rf_exit |
rf_002: |
cmp [eax + ARPTable+8], dx |
je rf_gotone |
loop rf_001 |
jmp rf_exit |
rf_gotone: |
; Initialise the time to live field - 1 hour |
mov cx, 0x0E10 |
mov [eax + ARPTable + 12], cx |
rf_exit: |
ret |
;*************************************************************************** |
; Function |
; getMACfromIP |
; |
; Description |
; Takes an IP address in edx and scans the ARP table for |
; a matching entry |
; If a match is found, it's MAC address is stored in MACAddress. |
; Otherwise the value 0 is writen to MACAddress |
; eax holds ARP table entry status code ( ARP_ ) |
; ebx unchanged |
; |
;*************************************************************************** |
getMACfromIP: |
; first, check destination IP to see if it is on 'this' network. |
; The test is: |
; if ( destIP & subnet_mask == stack_ip & subnet_mask ) |
; desitnation is local |
; else |
; destination is remote, so pass to gateway |
mov eax, edx |
and eax, [subnet_mask] |
mov ecx, [stack_ip] |
and ecx, [subnet_mask] |
cmp eax, ecx |
je gm0 |
mov edx, [gateway_ip] |
gm0: |
push edx |
xor eax, eax |
mov [MACAddress], eax |
mov [MACAddress + 4], ax |
movzx eax, byte [NumARP] |
mov ecx, ARP_ENTRY_SIZE |
mul ecx |
pop edx |
movzx ecx, byte [NumARP] |
cmp ecx, 0 |
je gm_none |
gm1: |
sub eax, ARP_ENTRY_SIZE |
cmp [eax + ARPTable], edx |
loopnz gm1 ; Return back if non match |
jnz gm_none ; Quit if none found |
; eax holds index |
mov ecx, [eax + ARPTable + 4] |
mov [MACAddress], ecx |
mov cx, [eax + ARPTable + 8] |
mov [MACAddress+4], cx |
; Return the entry status in eax |
mov ch, [eax + ARPTable + 10] |
mov cl, [eax + ARPTable + 11] |
movzx eax, cx |
jmp gm_exit |
gm_none: |
mov eax, ARP_NO_ENTRY |
gm_exit: |
ret |
;*************************************************************************** |
; |
; PCI CODE FOLLOWS |
; |
; the following functions provide access to the PCI interface. |
; These functions are used by scan_bus, and also some ethernet drivers |
; |
;*************************************************************************** |
;*************************************************************************** |
; Function |
; config_cmd |
; |
; Description |
; creates a command dword for use with the PCI bus |
; bus # in ebx |
; devfn in ecx |
; where in edx |
; |
; command dword returned in eax |
; Only eax destroyed |
;*************************************************************************** |
config_cmd: |
push ecx |
mov eax, ebx |
shl eax, 16 |
or eax, 0x80000000 |
shl ecx, 8 |
or eax, ecx |
pop ecx |
or eax, edx |
and eax, 0xFFFFFFFC |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_byte |
; |
; Description |
; reads a byte from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; byte returned in al ( rest of eax zero ) |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_byte: |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
and dx, 0x03 |
add dx, 0xCFC |
; and dx, 0xFFC |
in al, dx |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_word |
; |
; Description |
; reads a word from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; word returned in ax ( rest of eax zero ) |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_word: |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
and dx, 0x02 |
add dx, 0xCFC |
; and dx, 0xFFC |
in ax, dx |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_dword |
; |
; Description |
; reads a dword from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; dword returned in eax |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_dword: |
push edx |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
mov dx, 0xCFC |
in eax, dx |
pop edx |
ret |
;*************************************************************************** |
; Function |
; pcibios_write_config_byte |
; |
; Description |
; write a byte in al to the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_write_config_byte: |
push ax |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
pop ax |
and dx, 0x03 |
add dx, 0xCFC |
out dx, al |
ret |
;*************************************************************************** |
; Function |
; pcibios_write_config_word |
; |
; Description |
; write a word in ax to the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_write_config_word: |
push ax |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
pop ax |
and dx, 0x02 |
add dx, 0xCFC |
out dx, ax |
ret |
;*************************************************************************** |
; Function |
; delay_us |
; |
; Description |
; delays for 30 to 60 us |
; |
; I would prefer this routine to be able to delay for |
; a selectable number of microseconds, but this works for now. |
; |
; If you know a better way to do 2us delay, pleae tell me! |
;*************************************************************************** |
delay_us: |
push eax |
push ecx |
mov ecx,2 |
in al,0x61 |
and al,0x10 |
mov ah,al |
cld |
dcnt1: |
in al,0x61 |
and al,0x10 |
cmp al,ah |
jz dcnt1 |
mov ah,al |
loop dcnt1 |
pop ecx |
pop eax |
ret |
;*************************************************************************** |
; Function |
; scan_bus |
; |
; Description |
; Scans the PCI bus for a supported device |
; If a supported device is found, the drvr_ variables are initialised |
; to that drivers functions ( as defined in the PCICards table) |
; |
; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid |
; pci_data holds the PCI vendor + device code |
; pci_dev holds PCI bus dev # |
; pci_bus holds PCI bus # |
; |
; io_addr will be zero if no card found |
; |
;*************************************************************************** |
scan_bus: |
xor eax, eax |
mov [hdrtype], al |
mov [pci_data], eax |
xor ebx, ebx ; ebx = bus# 0 .. 255 |
sb_bus_loop: |
xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? ) |
sb_devf_loop: |
mov eax, ecx |
and eax, 0x07 |
cmp eax, 0 |
jne sb_001 |
mov edx, PCI_HEADER_TYPE |
call pcibios_read_config_byte |
mov [hdrtype], al |
jmp sb_002 |
sb_001: |
mov al, [hdrtype] |
and al, 0x80 |
cmp al, 0x80 |
jne sb_inc_devf |
sb_002: |
mov edx, PCI_VENDOR_ID |
call pcibios_read_config_dword |
mov [vendor_device], eax |
cmp eax, 0xffffffff |
je sb_empty |
cmp eax, 0 |
jne sb_check_vendor |
sb_empty: |
mov [hdrtype], byte 0 |
jmp sb_inc_devf |
sb_check_vendor: |
; iterate though PCICards until end or match found |
mov esi, PCICards |
sb_check: |
cmp [esi], dword 0 |
je sb_inc_devf ; Quit if at last entry |
cmp eax, [esi] |
je sb_got_card |
add esi, PCICARDS_ENTRY_SIZE |
jmp sb_check |
sb_got_card: |
; indicate that we have found the card |
mov [pci_data], eax |
mov [pci_dev], ecx |
mov [pci_bus], ebx |
; Define the driver functions |
push eax |
mov eax, [esi+4] |
mov [drvr_probe], eax |
mov eax, [esi+8] |
mov [drvr_reset], eax |
mov eax, [esi+12] |
mov [drvr_poll], eax |
mov eax, [esi+16] |
mov [drvr_transmit], eax |
pop eax |
mov edx, PCI_BASE_ADDRESS_0 |
sb_reg_check: |
call pcibios_read_config_dword |
mov [io_addr], eax |
and eax, PCI_BASE_ADDRESS_IO_MASK |
cmp eax, 0 |
je sb_inc_reg |
mov eax, [io_addr] |
and eax, PCI_BASE_ADDRESS_SPACE_IO |
cmp eax, 0 |
je sb_inc_reg |
mov eax, [io_addr] |
and eax, PCI_BASE_ADDRESS_IO_MASK |
mov [io_addr], eax |
sb_exit1: |
ret |
sb_inc_reg: |
add edx, 4 |
cmp edx, PCI_BASE_ADDRESS_5 |
jbe sb_reg_check |
sb_inc_devf: |
inc ecx |
cmp ecx, 255 |
jb sb_devf_loop |
inc ebx |
cmp ebx, 256 |
jb sb_bus_loop |
; We get here if we didn't find our card |
; set io_addr to 0 as an indication |
xor eax, eax |
mov [io_addr], eax |
sb_exit2: |
ret |
;*************************************************************************** |
; |
; DEBUGGING CODE FOLLOWS |
; |
; If debugging data output is not required, ALL code & data below may |
; be removed. |
; |
;*************************************************************************** |
if DEBUGGING_STATE = DEBUGGING_ENABLED |
;*************************************************************************** |
; Function |
; eth_dump |
; |
; Description |
; Dumps a tx or rx ethernet packet over the rs232 link |
; This is a debugging routine that seriously slows down the stack. |
; Use with caution. |
; |
; Baud rate is 57600, 8n1 com1 |
; eax : type (0 == rx, 1 == tx ) |
; cx : # of bytes in buffer |
; esi : address of buffer start |
; edi : pointer to MACAddress ( tx only ) |
; |
;*************************************************************************** |
eth_dump: |
pusha |
; Set the port to the desired speed |
mov ebx, 0x3f8 ; combase |
mov edx, ebx |
add edx, 3 ; data format register |
mov al, 0x80 ; enable access to divisor latch |
out dx, al |
mov edx, ebx |
add edx, 1 ; interrupt enable register |
mov al, 0x00 ; No interruts enabled |
out dx, al |
mov edx, ebx |
mov al, 0x20 / 16 ; set baud rate to 57600 0x10 =115200 |
out dx, al |
mov edx, ebx |
add edx, 3 ; data format register |
mov al, 0x03 ; 8 data bits |
out dx, al |
mov edx, ebx |
add edx, 4 ; Modem control register |
mov al, 0x08 ; out2 enabled. No handshaking. |
out dx, al |
mov edx, ebx |
add edx, 1 ; interrupt enable register |
mov al, 0x01 ; Receive data interrupt enabled, |
out dx, al |
popa |
; First, display the type of the buffer. |
; If it is a tx buffer, display the macaddress |
pusha |
cmp eax, 0 |
jne dd001 |
mov bl, 0x0a |
call tx_byted |
mov bl, 0x0d |
call tx_byted |
; Output "RX:" |
mov bl, 'R' |
call tx_byted |
mov bl, 'X' |
call tx_byted |
mov bl, ':' |
call tx_byted |
jmp dump_data |
dd001: |
mov bl, 0x0a |
call tx_byted |
mov bl, 0x0d |
call tx_byted |
; Output TX: xxxxxxxxxxxx |
mov bl, 'T' |
call tx_byted |
mov bl, 'X' |
call tx_byted |
mov bl, ':' |
call tx_byted |
mov bl, ' ' |
call tx_byted |
; Display MAC address |
xor eax, eax |
mov al, [edi] |
shr al, 4 |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
xor eax, eax |
mov al, [edi] |
and al, 0x0f |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
inc edi |
xor eax, eax |
mov al, [edi] |
shr al, 4 |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
xor eax, eax |
mov al, [edi] |
and al, 0x0f |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
inc edi |
xor eax, eax |
mov al, [edi] |
shr al, 4 |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
xor eax, eax |
mov al, [edi] |
and al, 0x0f |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
inc edi |
xor eax, eax |
mov al, [edi] |
shr al, 4 |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
xor eax, eax |
mov al, [edi] |
and al, 0x0f |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
inc edi |
xor eax, eax |
mov al, [edi] |
shr al, 4 |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
xor eax, eax |
mov al, [edi] |
and al, 0x0f |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
inc edi |
xor eax, eax |
mov al, [edi] |
shr al, 4 |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
xor eax, eax |
mov al, [edi] |
and al, 0x0f |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
dump_data: |
popa |
; OK, we come in here with |
; cx == number of byte to send |
; esi == buffer start |
; |
dd_000: |
mov bl, 0x0a |
call tx_byted |
mov bl, 0x0d |
call tx_byted |
mov eax, 16 ; Number of characters on the line |
mov edi, esi ; Save first byte position for later |
push ecx |
dd_001: |
push eax |
; Print a byte, and a space |
xor eax, eax |
mov al, [esi] |
shr al, 4 |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
xor eax, eax |
mov al, [esi] |
and al, 0x0f |
mov bl, [eax + hexchars] |
call tx_byted ; byte in bl eax ebx edx destroyed |
mov bl, ' ' |
call tx_byted |
pop eax |
inc esi |
dec ecx |
cmp ecx, 0 |
je dd_0011 ; Print the ASCII format |
dec eax |
cmp eax, 0 |
je dd_002 ; Print the ASCII format |
jmp dd_001 ; Print rest of line |
dd_0011: |
; First, complete the 16 bytes of data, by printing spaces |
dec eax |
cmp eax, 0 |
je dd_002 |
push eax |
mov bl, ' ' |
call tx_byted |
mov bl, ' ' |
call tx_byted |
mov bl, ' ' |
call tx_byted |
pop eax |
jmp dd_0011 |
dd_002: |
pop ecx |
mov esi, edi ; Go back to the start of the line data |
mov eax, 16 |
outLineAscii: |
push eax |
xor eax, eax |
mov al, [esi] |
mov bl, '.' |
cmp al, 0x1F |
jle outAscii |
cmp al, 0x7e |
jge outAscii |
mov bl, al |
outAscii: |
call tx_byted ; byte in bl eax ebx edx destroyed |
pop eax |
dec ecx |
inc esi |
cmp ecx, 0 |
je dd_003 |
dec eax |
cmp eax, 0 |
je dd_003 |
jmp outLineAscii |
dd_003: |
cmp ecx, 0 |
je dd_004 |
jmp dd_000 |
dd_004: |
ret |
;*************************************************************************** |
; Function |
; tx_byte |
; |
; Description |
; Send a byte in bl out of the com port 1 |
; destroys eax, edx |
; |
;*************************************************************************** |
tx_byted: |
push ebx ; Save the byte |
mov ebx, 0x3f8 ; get the com port address |
; Wait for transmit buffer to empty. This could take 1ms @ 9600baud |
mov edx, ebx |
add edx, 5 |
wait_txd: |
in al, dx ; read uart serialisation status |
and al, 0x40 |
cmp al, 0 |
jz wait_txd ; loop until free |
mov edx, ebx |
pop eax ; restore the byte to send |
out dx, al |
ret |
iglobal |
; This is used for translating hex to ASCII for display or output |
hexchars db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' |
endg |
end if |
/kernel/branches/gfx_kernel/network/eth_drv/i8255x.inc |
---|
0,0 → 1,739 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; I8255X.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.3 11 August 2003 ;; |
;; ;; |
;; This driver is based on the eepro100 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett, ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************** |
; Interface |
; I8255x_reset |
; I8255x_probe |
; I8255x_poll |
; I8255x_transmit |
; |
; These functions are referenced in ethernet.inc |
; |
;******************************************************************** |
rxfd_status equ eth_data_start |
rxfd_command equ eth_data_start + 2 |
rxfd_link equ eth_data_start + 4 |
rxfd_rx_buf_addr equ eth_data_start + 8 |
rxfd_count equ eth_data_start + 12 |
rxfd_size equ eth_data_start + 14 |
rxfd_packet equ eth_data_start + 16 |
uglobal |
eeprom_data: times 16 dd 0 |
align 4 |
lstats: |
tx_good_frames: dd 0 |
tx_coll16_errs: dd 0 |
tx_late_colls: dd 0 |
tx_underruns: dd 0 |
tx_lost_carrier: dd 0 |
tx_deferred: dd 0 |
tx_one_colls: dd 0 |
tx_multi_colls: dd 0 |
tx_total_colls: dd 0 |
rx_good_frames: dd 0 |
rx_crc_errs: dd 0 |
rx_align_errs: dd 0 |
rx_resource_errs: dd 0 |
rx_overrun_errs: dd 0 |
rx_colls_errs: dd 0 |
rx_runt_errs: dd 0 |
done_marker: dd 0 |
align 4 |
confcmd: |
confcmd_status: dw 0 |
confcmd_command: dw 0 |
confcmd_link: dd 0 |
endg |
iglobal |
confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 |
db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 |
db 0x80, 0x3f, 0x05 |
endg |
uglobal |
align 4 |
txfd: |
txfd_status: dw 0 |
txfd_command: dw 0 |
txfd_link: dd 0 |
txfd_tx_desc_addr: dd 0 |
txfd_count: dd 0 |
txfd_tx_buf_addr0: dd 0 |
txfd_tx_buf_size0: dd 0 |
txfd_tx_buf_addr1: dd 0 |
txfd_tx_buf_size1: dd 0 |
align 4 |
hdr: |
hdr_dst_addr: times 6 db 0 |
hdr_src_addr: times 6 db 0 |
hdr_type: dw 0 |
endg |
;*************************************************************************** |
; Function |
; wait_for_cmd_done |
; |
; Description |
; waits for the hardware to complete a command |
; port address in edx |
; |
; al destroyed |
;*************************************************************************** |
wait_for_cmd_done: |
in al, dx |
cmp al, 0 |
jne wait_for_cmd_done |
ret |
;*************************************************************************** |
; Function |
; mdio_read |
; |
; Description |
; This probably reads a register in the "physical media interface chip" |
; Phy_id in ebx |
; location in ecx |
; |
; Data returned in eax |
; |
;*************************************************************************** |
mdio_read: |
mov edx, [io_addr] |
add edx, 16 ; SCBCtrlMDI |
mov eax, 0x08000000 |
shl ecx, 16 |
or eax, ecx |
shl ebx, 21 |
or eax, ebx |
out dx, eax |
mrlp: |
call delay_us |
in eax, dx |
mov ecx, eax |
and ecx, 0x10000000 |
jz mrlp |
and eax, 0xffff |
ret |
;*************************************************************************** |
; Function |
; mdio_write |
; |
; Description |
; This probably writes a register in the "physical media interface chip" |
; Phy_id in ebx |
; location in ecx |
; data in edx |
; Data returned in eax |
; |
;*************************************************************************** |
mdio_write: |
mov eax, 0x04000000 |
shl ecx, 16 |
or eax, ecx |
shl ebx, 21 |
or eax, ebx |
or eax, edx |
mov edx, [io_addr] |
add edx, 16 ; SCBCtrlMDI |
out dx, eax |
mwlp: |
call delay_us |
in eax, dx |
mov ecx, eax |
and ecx, 0x10000000 |
jz mwlp |
and eax, 0xffff |
ret |
;/***********************************************************************/ |
;/* I82557 related defines */ |
;/***********************************************************************/ |
; Serial EEPROM section. |
; A "bit" grungy, but we work our way through bit-by-bit :->. |
; EEPROM_Ctrl bits. |
EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock. |
EE_CS equ 0x02 ; EEPROM chip select. |
EE_DATA_WRITE equ 0x04 ; EEPROM chip data in. |
EE_DATA_READ equ 0x08 ; EEPROM chip data out. |
EE_WRITE_0 equ 0x4802 |
EE_WRITE_1 equ 0x4806 |
EE_ENB equ 0x4802 |
; The EEPROM commands include the alway-set leading bit. |
EE_READ_CMD equ 6 |
; The SCB accepts the following controls for the Tx and Rx units: |
CU_START equ 0x0010 |
CU_RESUME equ 0x0020 |
CU_STATSADDR equ 0x0040 |
CU_SHOWSTATS equ 0x0050 ; Dump statistics counters. |
CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands. |
CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters. |
RX_START equ 0x0001 |
RX_RESUME equ 0x0002 |
RX_ABORT equ 0x0004 |
RX_ADDR_LOAD equ 0x0006 |
RX_RESUMENR equ 0x0007 |
INT_MASK equ 0x0100 |
DRVR_INT equ 0x0200 ; Driver generated interrupt. |
;*************************************************************************** |
; Function |
; do_eeprom_cmd |
; |
; Description |
; writes a cmd to the ethernet cards eeprom, by bit bashing |
; cmd in ebx |
; cmd length in ecx |
; return in eax |
;*************************************************************************** |
do_eeprom_cmd: |
mov edx, [io_addr] ; We only require the value in dx |
add dx, 14 ; the value SCBeeprom |
mov ax, EE_ENB |
out dx, ax |
call delay_us |
mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK |
out dx, ax |
call delay_us |
; dx holds ee_addr |
; ecx holds count |
; eax holds cmd |
xor edi, edi ; this will be the receive data |
dec_001: |
mov esi, 1 |
dec ecx |
shl esi, cl |
inc ecx |
and esi, ebx |
mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags.. |
cmp esi,0 |
jz dec_002 |
mov eax, EE_WRITE_1 |
dec_002: |
out dx, ax |
call delay_us |
or ax, EE_SHIFT_CLK |
out dx, ax |
call delay_us |
shl edi,1 |
in ax, dx |
and ax, EE_DATA_READ |
cmp ax,0 |
jz dec_003 |
inc edi |
dec_003: |
loop dec_001 |
mov ax, EE_ENB |
out dx, ax |
call delay_us |
mov ax, 0x4800 |
out dx, ax |
call delay_us |
mov eax, edi |
ret |
;*************************************************************************** |
; Function |
; I8255x_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; No inputs |
; All registers destroyed |
; |
;*************************************************************************** |
I8255x_reset: |
ret |
;*************************************************************************** |
; Function |
; I8255x_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; |
;*************************************************************************** |
I8255x_probe: |
mov eax, [io_addr] |
mov ebx, [pci_bus] |
mov ecx, [pci_dev] |
mov edx, 0x04 ; PCI_COMMAND |
call pcibios_read_config_word |
or ax, 0x05 |
mov ebx, [pci_bus] |
mov ecx, [pci_dev] |
mov edx, 0x04 ; PCI_COMMAND |
call pcibios_write_config_word |
mov ebx, 0x6000000 |
mov ecx, 27 |
call do_eeprom_cmd |
and eax, 0xffe0000 |
cmp eax, 0xffe0000 |
je bige |
mov ebx, 0x1800000 |
mov ecx, 0x40 |
jmp doread |
bige: |
mov ebx, 0x6000000 |
mov ecx, 0x100 |
doread: |
; do-eeprom-cmd will destroy all registers |
; we have eesize in ecx |
; read_cmd in ebx |
; Ignore full eeprom - just load the mac address |
mov ecx, 0 |
drlp: |
push ecx ; save count |
push ebx |
mov eax, ecx |
shl eax, 16 |
or ebx, eax |
mov ecx, 27 |
call do_eeprom_cmd |
pop ebx |
pop ecx |
mov edx, ecx |
shl edx, 2 |
mov esi, eeprom_data |
add esi, edx |
mov [esi], eax |
inc ecx |
cmp ecx, 16 |
jne drlp |
; OK, we have the MAC address. |
; Now reset the card |
mov edx, [io_addr] |
add dx, 8 ; SCBPort |
xor eax, eax ; The reset cmd == 0 |
out dx, eax |
mov esi, 10 |
call delay_ms ; Give the card time to warm up. |
mov eax, lstats |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov eax, 0x0140 ; INT_MASK | CU_STATSADDR |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
mov eax, 0 |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
; build rxrd structure |
mov ax, 0x0001 |
mov [rxfd_status], ax |
mov ax, 0x0000 |
mov [rxfd_command], ax |
mov eax, rxfd_status |
mov [rxfd_link], eax |
mov eax, Ether_buffer |
mov [rxfd_rx_buf_addr], eax |
mov ax, 0 |
mov [rxfd_count], ax |
mov ax, 1528 |
mov [rxfd_size], ax |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, rxfd_status |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0101 ; INT_MASK | RX_START |
out dx, ax |
call wait_for_cmd_done |
; start the reciver |
mov ax, 0 |
mov [rxfd_status], ax |
mov ax, 0xc000 |
mov [rxfd_command], ax |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, rxfd_status |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0101 ; INT_MASK | RX_START |
out dx, ax |
; Init TX Stuff |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, 0 |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE |
out dx, ax |
call wait_for_cmd_done |
; Set TX Base address |
; First, set up confcmd values |
mov ax, 2 |
mov [confcmd_command], ax |
mov eax, txfd |
mov [confcmd_link], eax |
mov ax, 1 |
mov [txfd_command], ax ; CmdIASetup |
mov ax, 0 |
mov [txfd_status], ax |
mov eax, confcmd |
mov [txfd_link], eax |
; ETH_ALEN is 6 bytes |
mov esi, eeprom_data |
mov edi, node_addr |
mov ecx, 3 |
drp000: |
mov eax, [esi] |
mov [edi], al |
shr eax, 8 |
inc edi |
mov [edi], al |
inc edi |
add esi, 4 |
loop drp000 |
; Hard code your MAC address into node_addr at this point, |
; If you cannot read the MAC address from the eeprom in the previous step. |
; You also have to write the mac address into txfd_tx_desc_addr, rather |
; than taking data from eeprom_data |
mov esi, eeprom_data |
mov edi, txfd_tx_desc_addr |
mov ecx, 3 |
drp001: |
mov eax, [esi] |
mov [edi], al |
shr eax, 8 |
inc edi |
mov [edi], al |
inc edi |
add esi, 4 |
loop drp001 |
mov esi, eeprom_data + (6 * 4) |
mov eax, [esi] |
shr eax, 8 |
and eax, 0x3f |
cmp eax, 4 ; DP83840 |
je drp002 |
cmp eax, 10 ; DP83840A |
je drp002 |
jmp drp003 |
drp002: |
mov ebx, [esi] |
and ebx, 0x1f |
push ebx |
mov ecx, 23 |
call mdio_read |
pop ebx |
or eax, 0x0422 |
mov ecx, 23 |
mov edx, eax |
call mdio_write |
drp003: |
mov ax, 0x4002 ; Cmdsuspend | CmdConfigure |
mov [confcmd_command], ax |
mov ax, 0 |
mov [confcmd_status], ax |
mov eax, txfd |
mov [confcmd_link], eax |
mov ebx, confcmd_data |
mov al, 0x88 ; fifo of 8 each |
mov [ebx + 1], al |
mov al, 0 |
mov [ebx + 4], al |
mov al, 0x80 |
mov [ebx + 5], al |
mov al, 0x48 |
mov [ebx + 15], al |
mov al, 0x80 |
mov [ebx + 19], al |
mov al, 0x05 |
mov [ebx + 21], al |
mov eax, txfd |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov eax, 0x0110 ; INT_MASK | CU_START |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
jmp skip |
; wait for thing to start |
drp004: |
mov ax, [txfd_status] |
cmp ax, 0 |
je drp004 |
skip: |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
I8255x_exit: |
ret |
;*************************************************************************** |
; Function |
; I8255x_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; |
;*************************************************************************** |
I8255x_poll: |
mov ax, 0 ; assume no data |
mov [eth_rx_data_len], ax |
mov ax, [rxfd_status] |
cmp ax, 0 |
je i8p_exit |
mov ax, 0 |
mov [rxfd_status], ax |
mov ax, 0xc000 |
mov [rxfd_command], ax |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
mov eax, rxfd_status |
out dx, eax |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
mov ax, 0x0101 ; INT_MASK | RX_START |
out dx, ax |
call wait_for_cmd_done |
mov esi, rxfd_packet |
mov edi, Ether_buffer |
mov ecx, 1518 |
cld |
rep movsb |
mov ax, [rxfd_count] |
and ax, 0x3fff |
mov [eth_rx_data_len], ax |
i8p_exit: |
ret |
;*************************************************************************** |
; Function |
; I8255x_transmit |
; |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
;*************************************************************************** |
I8255x_transmit: |
mov [hdr_type], bx |
mov eax, [edi] |
mov [hdr_dst_addr], eax |
mov ax, [edi+4] |
mov [hdr_dst_addr+4], ax |
mov eax, [node_addr] |
mov [hdr_src_addr], eax |
mov ax, [node_addr+4] |
mov [hdr_src_addr+4], ax |
mov edx, [io_addr] |
in ax, dx |
and ax, 0xfc00 |
out dx, ax |
xor ax, ax |
mov [txfd_status], ax |
mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex |
mov [txfd_command], ax |
mov eax, txfd |
mov [txfd_link], eax |
mov eax, 0x02208000 |
mov [txfd_count], eax |
mov eax, txfd_tx_buf_addr0 |
mov [txfd_tx_desc_addr], eax |
mov eax, hdr |
mov [txfd_tx_buf_addr0], eax |
mov eax, 14 ; sizeof hdr |
mov [txfd_tx_buf_size0], eax |
; Copy the buffer address and size in |
mov eax, esi |
mov [txfd_tx_buf_addr1], eax |
mov eax, ecx |
mov [txfd_tx_buf_size1], eax |
mov eax, txfd |
mov edx, [io_addr] |
add edx, 4 ; SCBPointer |
out dx, eax |
mov ax, 0x0110 ; INT_MASK | CU_START |
mov edx, [io_addr] |
add edx, 2 ; SCBCmd |
out dx, ax |
call wait_for_cmd_done |
mov edx, [io_addr] |
in ax, dx |
I8t_001: |
mov ax, [txfd_status] |
cmp ax, 0 |
je I8t_001 |
mov edx, [io_addr] |
in ax, dx |
ret |
/kernel/branches/gfx_kernel/network/eth_drv/pcnet32.inc |
---|
0,0 → 1,814 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; PCNET32.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 1.0 31 July 2004 ;; |
;; ;; |
;; This driver is based on the PCNet32 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2004 Jarek Pelczar, ;; |
;; jpelczar@interia.pl ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;macro PutStr X |
;{ |
; local .__xyz1 |
; local .__xyz2 |
; push esi |
; mov esi,.__xyz1 |
; call sys_msg_board_str |
; push eax |
; mov eax,1 |
; call delay_hs |
; pop eax |
; jmp .__xyz2 |
;.__xyz1: |
; db X |
; db 13,10,0 |
;.__xyz2: |
; pop esi |
;} |
PCNET32_PORT_AUI equ 0x00 |
PCNET32_PORT_10BT equ 0x01 |
PCNET32_PORT_GPSI equ 0x02 |
PCNET32_PORT_MII equ 0x03 |
PCNET32_PORT_PORTSEL equ 0x03 |
PCNET32_PORT_ASEL equ 0x04 |
PCNET32_PORT_100 equ 0x40 |
PCNET32_PORT_FD equ 0x80 |
PCNET32_DMA_MASK equ 0xffffffff |
PCNET32_LOG_TX_BUFFERS equ 1 |
PCNET32_LOG_RX_BUFFERS equ 2 |
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS) |
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1) |
PCNET32_TX_RING_LEN_BITS equ 0 |
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS) |
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1) |
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4) |
PCNET32_PKT_BUF_SZ equ 1544 |
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8 |
pcnet32_txb equ (eth_data_start) |
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) |
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) |
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) |
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) |
pcnet32_private: |
.mode dw ? |
.tlen_rlen dw ? |
.phys_addr db ?,?,?,?,?,? |
.reserved dw ? |
.filter dd ?,? |
.rx_ring dd ? |
.tx_ring dd ? |
.cur_rx dd ? |
.cur_tx dd ? |
.dirty_rx dd ? |
.dirty_tx dd ? |
.tx_full db ? |
.options dd ? |
.full_duplex db ? |
.chip_version dd ? |
.mii db ? |
.ltint db ? |
.dxsuflo db ? |
.fset db ? |
.fdx db ? |
end virtual |
virtual at 0 |
pcnet32_rx_head: |
.base dd ? |
.buf_length dw ? |
.status dw ? |
.msg_length dd ? |
.reserved dd ? |
end virtual |
virtual at 0 |
pcnet32_tx_head: |
.base dd ? |
.length dw ? |
.status dw ? |
.misc dd ? |
.reserved dd ? |
end virtual |
uglobal |
pcnet32_access: |
.read_csr dd ? |
.write_csr dd ? |
.read_bcr dd ? |
.write_bcr dd ? |
.read_rap dd ? |
.write_rap dd ? |
.reset dd ? |
endg |
iglobal |
pcnet32_options_mapping: |
dd PCNET32_PORT_ASEL ; 0 Auto-select |
dd PCNET32_PORT_AUI ; 1 BNC/AUI |
dd PCNET32_PORT_AUI ; 2 AUI/BNC |
dd PCNET32_PORT_ASEL ; 3 not supported |
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD |
dd PCNET32_PORT_ASEL ; 5 not supported |
dd PCNET32_PORT_ASEL ; 6 not supported |
dd PCNET32_PORT_ASEL ; 7 not supported |
dd PCNET32_PORT_ASEL ; 8 not supported |
dd PCNET32_PORT_MII ; 9 MII 10baseT |
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD |
dd PCNET32_PORT_MII ; 11 MII (autosel) |
dd PCNET32_PORT_10BT ; 12 10BaseT |
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx |
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD |
dd PCNET32_PORT_ASEL ; 15 not supported |
endg |
PCNET32_WIO_RDP equ 0x10 |
PCNET32_WIO_RAP equ 0x12 |
PCNET32_WIO_RESET equ 0x14 |
PCNET32_WIO_BDP equ 0x16 |
PCNET32_DWIO_RDP equ 0x10 |
PCNET32_DWIO_RAP equ 0x14 |
PCNET32_DWIO_RESET equ 0x18 |
PCNET32_DWIO_BDP equ 0x1C |
PCNET32_TOTAL_SIZE equ 0x20 |
; ebx - index |
; return: |
; eax - data |
pcnet32_wio_read_csr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
mov ax,bx |
out dx,ax |
lea edx,[ebp+PCNET32_WIO_RDP] |
in ax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - data |
; ebx - index |
pcnet32_wio_write_csr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
xchg eax,ebx |
out dx,ax |
xchg eax,ebx |
lea edx,[ebp+PCNET32_WIO_RDP] |
out dx,ax |
pop edx |
ret |
; ebx - index |
; return: |
; eax - data |
pcnet32_wio_read_bcr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
mov ax,bx |
out dx,ax |
lea edx,[ebp+PCNET32_WIO_BDP] |
in ax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - data |
; ebx - index |
pcnet32_wio_write_bcr: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
xchg eax,ebx |
out dx,ax |
xchg eax,ebx |
lea edx,[ebp+PCNET32_WIO_BDP] |
out dx,ax |
pop edx |
ret |
pcnet32_wio_read_rap: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
in ax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - val |
pcnet32_wio_write_rap: |
push edx |
lea edx,[ebp+PCNET32_WIO_RAP] |
out dx,ax |
pop edx |
ret |
pcnet32_wio_reset: |
push edx |
push eax |
lea edx,[ebp+PCNET32_WIO_RESET] |
in ax,dx |
pop eax |
pop edx |
ret |
pcnet32_wio_check: |
push edx |
mov ax,88 |
lea edx,[ebp+PCNET32_WIO_RAP] |
out dx,ax |
nop |
nop |
in ax,dx |
cmp ax,88 |
sete al |
pop edx |
ret |
iglobal |
pcnet32_wio: |
dd pcnet32_wio_read_csr |
dd pcnet32_wio_write_csr |
dd pcnet32_wio_read_bcr |
dd pcnet32_wio_write_bcr |
dd pcnet32_wio_read_rap |
dd pcnet32_wio_write_rap |
dd pcnet32_wio_reset |
endg |
; ebx - index |
; return: |
; eax - data |
pcnet32_dwio_read_csr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
mov ebx,eax |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_RDP] |
in eax,dx |
and eax,0xffff |
pop edx |
ret |
; ebx - index |
; eax - data |
pcnet32_dwio_write_csr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
xchg eax,ebx |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_RDP] |
xchg eax,ebx |
out dx,eax |
pop edx |
ret |
; ebx - index |
; return: |
; eax - data |
pcnet32_dwio_read_bcr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
mov ebx,eax |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_BDP] |
in eax,dx |
and eax,0xffff |
pop edx |
ret |
; ebx - index |
; eax - data |
pcnet32_dwio_write_bcr: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
xchg eax,ebx |
out dx,eax |
lea edx,[ebp+PCNET32_DWIO_BDP] |
xchg eax,ebx |
out dx,eax |
pop edx |
ret |
pcnet32_dwio_read_rap: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
in eax,dx |
and eax,0xffff |
pop edx |
ret |
; eax - val |
pcnet32_dwio_write_rap: |
push edx |
lea edx,[ebp+PCNET32_DWIO_RAP] |
out dx,eax |
pop edx |
ret |
pcnet32_dwio_reset: |
push edx |
push eax |
lea edx,[ebp+PCNET32_DWIO_RESET] |
in eax,dx |
pop eax |
pop edx |
ret |
pcnet32_dwio_check: |
push edx |
lea edx,[PCNET32_DWIO_RAP] |
mov eax,88 |
out dx,eax |
nop |
nop |
in eax,dx |
and eax,0xffff |
cmp eax,88 |
sete al |
pop edx |
ret |
iglobal |
pcnet32_dwio: |
dd pcnet32_dwio_read_csr |
dd pcnet32_dwio_write_csr |
dd pcnet32_dwio_read_bcr |
dd pcnet32_dwio_write_bcr |
dd pcnet32_dwio_read_rap |
dd pcnet32_dwio_write_rap |
dd pcnet32_dwio_reset |
endg |
pcnet32_init_ring: |
mov [pcnet32_private.tx_full],0 |
mov [pcnet32_private.cur_rx],0 |
mov [pcnet32_private.cur_tx],0 |
mov [pcnet32_private.dirty_rx],0 |
mov [pcnet32_private.dirty_tx],0 |
mov edi,pcnet32_rx_ring |
mov ecx,PCNET32_RX_RING_SIZE |
mov ebx,pcnet32_rxb |
.rx_init: |
mov [edi+pcnet32_rx_head.base],ebx |
mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG |
mov [edi+pcnet32_rx_head.status],word 0x8000 |
add ebx,PCNET32_PKT_BUF_SZ |
; inc ebx |
add edi,16 |
loop .rx_init |
mov edi,pcnet32_tx_ring |
mov ecx,PCNET32_TX_RING_SIZE |
.tx_init: |
mov [edi+pcnet32_tx_head.base],dword 0 |
mov [edi+pcnet32_tx_head.status],word 0 |
add edi,16 |
loop .tx_init |
mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) |
mov esi,node_addr |
mov edi,pcnet32_private.phys_addr |
cld |
movsd |
movsw |
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring |
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring |
ret |
pcnet32_reset: |
; Reset PCNET32 |
mov ebp,[io_addr] |
call dword [pcnet32_access.reset] |
; set 32bit mode |
mov ebx,20 |
mov eax,2 |
call dword [pcnet32_access.write_bcr] |
; set/reset autoselect bit |
mov ebx,2 |
call dword [pcnet32_access.read_bcr] |
and eax,not 2 |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jz .L1 |
or eax,2 |
.L1: |
call dword [pcnet32_access.write_bcr] |
; Handle full duplex setting |
cmp byte [pcnet32_private.full_duplex],0 |
je .L2 |
mov ebx,9 |
call dword [pcnet32_access.read_bcr] |
and eax,not 3 |
test [pcnet32_private.options],PCNET32_PORT_FD |
jz .L3 |
or eax,1 |
cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI |
jne .L4 |
or eax,2 |
jmp .L4 |
.L3: |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jz .L4 |
cmp [pcnet32_private.chip_version],0x2627 |
jne .L4 |
or eax,3 |
.L4: |
mov ebx,9 |
call dword [pcnet32_access.write_bcr] |
.L2: |
; set/reset GPSI bit |
mov ebx,124 |
call dword [pcnet32_access.read_csr] |
mov ecx,[pcnet32_private.options] |
and ecx,PCNET32_PORT_PORTSEL |
cmp ecx,PCNET32_PORT_GPSI |
jne .L5 |
or eax,0x10 |
.L5: |
call dword [pcnet32_access.write_csr] |
cmp [pcnet32_private.mii],0 |
je .L6 |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jnz .L6 |
mov ebx,32 |
call dword [pcnet32_access.read_bcr] |
and eax,not 0x38 |
test [pcnet32_private.options],PCNET32_PORT_FD |
jz .L7 |
or eax,0x10 |
.L7: |
test [pcnet32_private.options],PCNET32_PORT_100 |
jz .L8 |
or eax,0x08 |
.L8: |
call dword [pcnet32_access.write_bcr] |
jmp .L9 |
.L6: |
test [pcnet32_private.options],PCNET32_PORT_ASEL |
jz .L9 |
mov ebx,32 |
; PutStr "ASEL, enable auto-negotiation" |
call dword [pcnet32_access.read_bcr] |
and eax,not 0x98 |
or eax,0x20 |
call dword [pcnet32_access.write_bcr] |
.L9: |
cmp [pcnet32_private.ltint],0 |
je .L10 |
mov ebx,5 |
call dword [pcnet32_access.read_csr] |
or eax,(1 shl 14) |
call dword [pcnet32_access.write_csr] |
.L10: |
mov eax,[pcnet32_private.options] |
and eax,PCNET32_PORT_PORTSEL |
shl eax,7 |
mov [pcnet32_private.mode],ax |
mov [pcnet32_private.filter],dword 0xffffffff |
mov [pcnet32_private.filter+4],dword 0xffffffff |
call pcnet32_init_ring |
mov ebx,1 |
mov eax,pcnet32_private |
and eax,0xffff |
call dword [pcnet32_access.write_csr] |
mov eax,pcnet32_private |
mov ebx,2 |
shr eax,16 |
call dword [pcnet32_access.write_csr] |
mov ebx,4 |
mov eax,0x0915 |
call dword [pcnet32_access.write_csr] |
mov ebx,0 |
mov eax,1 |
call dword [pcnet32_access.write_csr] |
mov ecx,100 |
.L11: |
xor ebx,ebx |
call dword [pcnet32_access.read_csr] |
test ax,0x100 |
jnz .L12 |
loop .L11 |
.L12: |
; PutStr "hardware reset" |
xor ebx,ebx |
mov eax,0x0002 |
call dword [pcnet32_access.write_csr] |
xor ebx,ebx |
call dword [pcnet32_access.read_csr] |
; PutStr "PCNET reset complete" |
ret |
pcnet32_adjust_pci_device: |
;*******Get current setting************************ |
mov al, 2 ;read a word |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x04 ;from command Register |
call pci_read_reg |
;******see if its already set as bus master******** |
mov bx, ax |
and bx,5 |
cmp bx,5 |
je pcnet32_adjust_pci_device_Latency |
;******Make card a bus master******* |
mov cx, ax ;value to write |
mov bh, [pci_dev] |
mov al, 2 ;write a word |
or cx,5 |
mov ah, [pci_bus] |
mov bl, 0x04 ;to command register |
call pci_write_reg |
;******Check latency setting*********** |
pcnet32_adjust_pci_device_Latency: |
;*******Get current latency setting************************ |
; mov al, 1 ;read a byte |
; mov bh, [pci_dev] |
; mov ah, [pci_bus] |
; mov bl, 0x0D ;from Lantency Timer Register |
; call pci_read_reg |
;******see if its aat least 64 clocks******** |
; cmp ax,64 |
; jge pcnet32_adjust_pci_device_Done |
;******Set latency to 32 clocks******* |
; mov cx, 64 ;value to write |
; mov bh, [pci_dev] |
; mov al, 1 ;write a byte |
; mov ah, [pci_bus] |
; mov bl, 0x0D ;to Lantency Timer Register |
; call pci_write_reg |
;******Check latency setting*********** |
pcnet32_adjust_pci_device_Done: |
ret |
pcnet32_probe: |
mov ebp,[io_addr] |
call pcnet32_wio_reset |
xor ebx,ebx |
call pcnet32_wio_read_csr |
cmp eax,4 |
jne .try_dwio |
call pcnet32_wio_check |
and al,al |
jz .try_dwio |
; PutStr "Using WIO" |
mov esi,pcnet32_wio |
jmp .L1 |
.try_dwio: |
call pcnet32_dwio_reset |
xor ebx,ebx |
call pcnet32_dwio_read_csr |
cmp eax,4 |
jne .no_dev |
call pcnet32_dwio_check |
and al,al |
jz .no_dev |
; PutStr "Using DWIO" |
mov esi,pcnet32_dwio |
jmp .L1 |
.no_dev: |
; PutStr "PCNET32 not found" |
ret |
.L1: |
mov edi,pcnet32_access |
mov ecx,7 |
cld |
rep movsd |
mov ebx,88 |
call dword [pcnet32_access.read_csr] |
mov ecx,eax |
mov ebx,89 |
call dword [pcnet32_access.read_csr] |
shl eax,16 |
or eax,ecx |
mov ecx,eax |
and ecx,0xfff |
cmp ecx,3 |
jne .no_dev |
shr eax,12 |
and eax,0xffff |
mov [pcnet32_private.chip_version],eax |
; PutStr "PCNET32 chip version OK" |
mov [pcnet32_private.fdx],0 |
mov [pcnet32_private.mii],0 |
mov [pcnet32_private.fset],0 |
mov [pcnet32_private.dxsuflo],0 |
mov [pcnet32_private.ltint],0 |
mov eax,[pcnet32_private.chip_version] |
cmp eax,0x2420 |
je .L2 |
cmp eax,0x2430 |
je .L3 |
cmp eax,0x2621 |
je .L4 |
cmp eax,0x2623 |
je .L5 |
cmp eax,0x2624 |
je .L6 |
cmp eax,0x2625 |
je .L7 |
cmp eax,0x2626 |
je .L8 |
cmp eax,0x2627 |
je .L9 |
; PutStr "Invalid chip rev" |
jmp .no_dev |
.L2: |
; PutStr "PCnet/PCI 79C970" |
jmp .L10 |
.L3: |
; PutStr "PCnet/PCI 79C970" |
jmp .L10 |
.L4: |
; PutStr "PCnet/PCI II 79C970A" |
mov [pcnet32_private.fdx],1 |
jmp .L10 |
.L5: |
; PutStr "PCnet/FAST 79C971" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
mov [pcnet32_private.fset],1 |
mov [pcnet32_private.ltint],1 |
jmp .L10 |
.L6: |
; PutStr "PCnet/FAST+ 79C972" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
mov [pcnet32_private.fset],1 |
jmp .L10 |
.L7: |
; PutStr "PCnet/FAST III 79C973" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
jmp .L10 |
.L8: |
; PutStr "PCnet/Home 79C978" |
mov [pcnet32_private.fdx],1 |
mov ebx,49 |
call dword [pcnet32_access.read_bcr] |
call dword [pcnet32_access.write_bcr] |
jmp .L10 |
.L9: |
; PutStr "PCnet/FAST III 79C975" |
mov [pcnet32_private.fdx],1 |
mov [pcnet32_private.mii],1 |
.L10: |
cmp [pcnet32_private.fset],1 |
jne .L11 |
mov ebx,18 |
call dword [pcnet32_access.read_bcr] |
or eax,0x800 |
call dword [pcnet32_access.write_bcr] |
mov ebx,80 |
call dword [pcnet32_access.read_csr] |
and eax,0xc00 |
or eax,0xc00 |
call dword [pcnet32_access.write_csr] |
mov [pcnet32_private.dxsuflo],1 |
mov [pcnet32_private.ltint],1 |
.L11: |
; read MAC |
mov edi,node_addr |
mov edx,ebp |
mov ecx,6 |
.Lmac: |
in al,dx |
stosb |
inc edx |
loop .Lmac |
; PutStr "MAC read" |
call pcnet32_adjust_pci_device |
; PutStr "PCI done" |
mov eax,PCNET32_PORT_ASEL |
mov [pcnet32_private.options],eax |
mov [pcnet32_private.mode],word 0x0003 |
mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) |
mov esi,node_addr |
mov edi,pcnet32_private.phys_addr |
cld |
movsd |
movsw |
mov [pcnet32_private.filter],dword 0 |
mov [pcnet32_private.filter+4],dword 0 |
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring |
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring |
; PutStr "Switching to 32" |
mov ebx,20 |
mov eax,2 |
call dword [pcnet32_access.write_bcr] |
mov ebx,1 |
mov eax,(pcnet32_private and 0xffff) |
call dword [pcnet32_access.write_csr] |
mov ebx,2 |
mov eax,(pcnet32_private shr 16) and 0xffff |
call dword [pcnet32_access.write_csr] |
mov ebx,0 |
mov eax,1 |
call dword [pcnet32_access.write_csr] |
mov esi,1 |
call delay_ms |
call pcnet32_reset |
mov eax, [pci_data] |
mov [eth_status], eax |
ret |
pcnet32_poll: |
xor eax,eax |
mov [eth_rx_data_len],ax |
mov eax,[pcnet32_private.cur_rx] |
and eax,PCNET32_RX_RING_MOD_MASK |
mov ebx,eax |
imul esi,eax,PCNET32_PKT_BUF_SZ |
add esi,pcnet32_rxb |
shl ebx,4 |
add ebx,pcnet32_rx_ring |
mov cx,[ebx+pcnet32_rx_head.status] |
test cx,0x8000 |
jnz .L1 |
cmp ch,3 |
jne .L1 |
; PutStr "PCNETRX" |
mov ecx,[ebx+pcnet32_rx_head.msg_length] |
and ecx,0xfff |
sub ecx,4 |
mov [eth_rx_data_len],cx |
push ecx |
shr ecx,2 |
mov edi,Ether_buffer |
cld |
rep movsd |
pop ecx |
and ecx,3 |
rep movsb |
mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG |
or [ebx+pcnet32_rx_head.status],word 0x8000 |
inc [pcnet32_private.cur_rx] |
.L1: |
ret |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
pcnet32_xmit: |
push edi |
push esi |
push ebx |
push ecx |
; PutStr "PCNETTX" |
mov esi,edi |
mov edi,[pcnet32_private.cur_tx] |
imul edi,PCNET32_PKT_BUF_SZ |
add edi,pcnet32_txb ; edi=ptxb |
mov eax,edi |
cld ; copy MAC |
movsd |
movsw |
mov esi,node_addr |
cld |
movsd |
movsw |
mov [edi],bx |
add edi,2 |
mov esi,[esp+8] |
mov ecx,[esp] |
push ecx |
shr ecx,2 |
cld |
rep movsd |
pop ecx |
and ecx,3 |
rep movsb |
; mov ecx,[esp] |
; add ecx,14 ; ETH_HLEN |
; xor eax,eax |
; pad to min length (60=ETH_ZLEN) |
; cmp ecx,60 |
; jae .L1 |
; sub ecx,60 |
; cld |
; rep stosb |
;.L1: |
mov edi,pcnet32_tx_ring+0 ; entry=0 |
mov ecx,[esp] |
add ecx,14 |
cmp cx,60 |
jae .L1 |
mov cx,60 |
.L1: |
neg cx |
mov [edi+pcnet32_tx_head.length],cx |
mov [edi+pcnet32_tx_head.misc],dword 0 |
mov [edi+pcnet32_tx_head.base],eax |
mov [edi+pcnet32_tx_head.status],word 0x8300 |
; trigger an immediate send poll |
mov ebx,0 |
mov eax,0x0008 ; 0x0048 |
mov ebp,[io_addr] |
call dword [pcnet32_access.write_csr] |
mov dword [pcnet32_private.cur_tx],0 |
; wait for TX to complete |
mov ecx,[timer_ticks];[0xfdf0] |
add ecx,100 |
.L2: |
mov ax,[edi+pcnet32_tx_head.status] |
test ax,0x8000 |
jz .L3 |
cmp ecx,[timer_ticks];[0xfdf0] |
jb .L4 |
mov esi,10 |
call delay_ms |
jnz .L2 |
.L4: |
; PutStr "PCNET: Send timeout" |
.L3: |
mov dword [edi+pcnet32_tx_head.base],0 |
pop ecx |
pop ebx |
pop esi |
pop edi |
ret |
/kernel/branches/gfx_kernel/network/eth_drv/rtl8029.inc |
---|
0,0 → 1,955 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; RTL8029.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.2 31 July 2002 ;; |
;; ;; |
;; This driver is based on the ns8390 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett, ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; While this implementation handles only PCI bus RTL8029 ;; |
;; hardware, it can be easily adapted to other NE2000 clone ;; |
;; products. I just dont have any to try! ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************** |
; Interface |
; rtl8029_reset |
; rtl8029_probe |
; rtl8029_poll |
; rtl8029_transmit |
; |
;******************************************************************** |
;************************************************************************** |
; 8390 Register Definitions |
;************************************************************************** |
D8390_P0_COMMAND equ 0x00 |
D8390_P0_PSTART equ 0x01 |
D8390_P0_PSTOP equ 0x02 |
D8390_P0_BOUND equ 0x03 |
D8390_P0_TSR equ 0x04 |
D8390_P0_TPSR equ 0x04 |
D8390_P0_TBCR0 equ 0x05 |
D8390_P0_TBCR1 equ 0x06 |
D8390_P0_ISR equ 0x07 |
D8390_P0_RSAR0 equ 0x08 |
D8390_P0_RSAR1 equ 0x09 |
D8390_P0_RBCR0 equ 0x0A |
D8390_P0_RBCR1 equ 0x0B |
D8390_P0_RSR equ 0x0C |
D8390_P0_RCR equ 0x0C |
D8390_P0_TCR equ 0x0D |
D8390_P0_DCR equ 0x0E |
D8390_P0_IMR equ 0x0F |
D8390_P1_COMMAND equ 0x00 |
D8390_P1_PAR0 equ 0x01 |
D8390_P1_PAR1 equ 0x02 |
D8390_P1_PAR2 equ 0x03 |
D8390_P1_PAR3 equ 0x04 |
D8390_P1_PAR4 equ 0x05 |
D8390_P1_PAR5 equ 0x06 |
D8390_P1_CURR equ 0x07 |
D8390_P1_MAR0 equ 0x08 |
D8390_COMMAND_PS0 equ 0x0 ; Page 0 select |
D8390_COMMAND_PS1 equ 0x40 ; Page 1 select |
D8390_COMMAND_PS2 equ 0x80 ; Page 2 select |
D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control |
D8390_COMMAND_RD1 equ 0x10 |
D8390_COMMAND_RD0 equ 0x08 |
D8390_COMMAND_TXP equ 0x04 ; transmit packet |
D8390_COMMAND_STA equ 0x02 ; start |
D8390_COMMAND_STP equ 0x01 ; stop |
D8390_COMMAND_RD2_STA equ 0x22 |
D8390_COMMAND_RD2_STP equ 0x21 |
D8390_COMMAND_RD1_STA equ 0x12 |
D8390_COMMAND_RD0_STA equ 0x0A |
D8390_COMMAND_PS0_RD2_STP equ 0x21 |
D8390_COMMAND_PS1_RD2_STP equ 0x61 |
D8390_COMMAND_PS0_RD2_STA equ 0x22 |
D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26 |
D8390_RCR_MON equ 0x20 ; monitor mode |
D8390_DCR_FT1 equ 0x40 |
D8390_DCR_LS equ 0x08 ; Loopback select |
D8390_DCR_WTS equ 0x01 ; Word transfer select |
D8390_DCR_FT1_LS equ 0x48 |
D8390_DCR_WTS_FT1_LS equ 0x49 |
D8390_ISR_PRX equ 0x01 ; successful recv |
D8390_ISR_PTX equ 0x02 ; successful xmit |
D8390_ISR_RXE equ 0x04 ; receive error |
D8390_ISR_TXE equ 0x08 ; transmit error |
D8390_ISR_OVW equ 0x10 ; Overflow |
D8390_ISR_CNT equ 0x20 ; Counter overflow |
D8390_ISR_RDC equ 0x40 ; Remote DMA complete |
D8390_ISR_RST equ 0x80 ; reset |
D8390_RSTAT_PRX equ 0x01 ; successful recv |
D8390_RSTAT_CRC equ 0x02 ; CRC error |
D8390_RSTAT_FAE equ 0x04 ; Frame alignment error |
D8390_RSTAT_OVER equ 0x08 ; FIFO overrun |
D8390_TXBUF_SIZE equ 6 |
D8390_RXBUF_END equ 32 |
D8390_PAGE_SIZE equ 256 |
ETH_ALEN equ 6 |
ETH_HLEN equ 14 |
ETH_ZLEN equ 60 |
ETH_FRAME_LEN equ 1514 |
FLAG_PIO equ 0x01 |
FLAG_16BIT equ 0x02 |
ASIC_PIO equ 0 |
VENDOR_NONE equ 0 |
VENDOR_WD equ 1 |
VENDOR_NOVELL equ 2 |
VENDOR_3COM equ 3 |
NE_ASIC_OFFSET equ 0x10 |
NE_RESET equ 0x0F ; Used to reset card |
NE_DATA equ 0x00 ; Used to read/write NIC mem |
MEM_8192 equ 32 |
MEM_16384 equ 64 |
MEM_32768 equ 128 |
ISA_MAX_ADDR equ 0x400 |
uglobal |
eth_flags: db 0 |
eth_vendor: db 0 |
eth_nic_base: dw 0 |
eth_asic_base: dw 0 |
eth_memsize: db 0 |
eth_rx_start: db 0 |
eth_tx_start: db 0 |
eth_bmem: dd 0 |
eth_rmem: dd 0 |
romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
endg |
iglobal |
test_data: db 'NE*000 memory',0 |
test_buffer: db ' ',0 |
endg |
uglobal |
eth_type: dw 0 |
pkthdr: db 0,0,0,0 ; status, next, (short) len |
pktoff: dw 0 |
eth_rx_data_ptr: dd 0 |
eth_tmp_len: dw 0 |
endg |
;*************************************************************************** |
; Function |
; eth_pio_read |
; |
; Description |
; Read a frame from the ethernet card via Programmed I/O |
; src in ebx |
; cnt in ecx |
; dst in edi |
;*************************************************************************** |
eth_pio_read: |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epr_001 |
inc ecx |
and ecx, 0xFFFFFFFE |
epr_001: |
mov al, D8390_COMMAND_RD2_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov al, cl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov al, ch |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov al, bl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR0 |
out dx, al |
mov al, bh |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR1 |
out dx, al |
mov al, D8390_COMMAND_RD0_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov dx, [eth_asic_base] |
add dx, ASIC_PIO |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epr_003 |
shr ecx, 1 |
epr_002: |
; 2 bytes at a time |
in ax, dx |
mov [edi], ax |
add edi, 2 |
loop epr_002 |
ret |
epr_003: |
; 1 byte at a time |
in al, dx |
mov [edi], al |
inc edi |
loop epr_003 |
ret |
;*************************************************************************** |
; Function |
; eth_pio_write |
; |
; Description |
; writes a frame to the ethernet card via Programmed I/O |
; dst in ebx |
; cnt in ecx |
; src in esi |
;*************************************************************************** |
eth_pio_write: |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epw_001 |
inc ecx |
and ecx, 0xFFFFFFFE |
epw_001: |
mov al, D8390_COMMAND_RD2_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov al, D8390_ISR_RDC |
mov dx, [eth_nic_base] |
add dx, D8390_P0_ISR |
out dx, al |
mov al, cl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov al, ch |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov al, bl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR0 |
out dx, al |
mov al, bh |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR1 |
out dx, al |
mov al, D8390_COMMAND_RD1_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov dx, [eth_asic_base] |
add dx, ASIC_PIO |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epw_003 |
shr ecx, 1 |
epw_002: |
; 2 bytes at a time |
mov ax, [esi] |
add esi, 2 |
out dx, ax |
loop epw_002 |
jmp epw_004 |
epw_003: |
; 1 byte at a time |
mov al, [esi] |
inc esi |
out dx, al |
loop epw_003 |
epw_004: |
mov dx, [eth_nic_base] |
add dx, D8390_P0_ISR |
epw_005: |
in al, dx |
and al, D8390_ISR_RDC |
cmp al, D8390_ISR_RDC |
jne epw_005 |
ret |
;*************************************************************************** |
; Function |
; rtl8029_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; No inputs |
; All registers destroyed |
; |
;*************************************************************************** |
rtl8029_reset: |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, FLAG_16BIT |
jne nsr_001 |
mov al, 0x49 |
jmp nsr_002 |
nsr_001: |
mov al, 0x48 |
nsr_002: |
out dx, al |
xor al, al |
mov dx, bx |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, 0x20 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TCR |
mov al, 2 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TPSR |
mov al, [eth_tx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, [eth_rx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, [eth_memsize] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_BOUND |
mov al, [eth_memsize] |
dec al |
out dx, al |
mov dx, bx |
add dx, D8390_P0_ISR |
mov al, 0xff |
out dx, al |
mov dx, bx |
add dx, D8390_P0_IMR |
xor al, al |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS1_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P1_PAR0 |
mov esi, node_addr |
mov ecx, ETH_ALEN |
nsr_003: |
mov al, [esi] |
out dx, al |
inc esi |
inc dx |
loop nsr_003 |
mov dx, bx |
add dx, D8390_P1_MAR0 |
mov ecx, ETH_ALEN |
mov al, 0xff |
nsr_004: |
out dx, al |
inc dx |
loop nsr_004 |
mov dx, bx |
add dx, D8390_P1_CURR |
mov al, [eth_rx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STA |
out dx, al |
mov dx, bx |
add dx, D8390_P0_ISR |
mov al, 0xff |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TCR |
mov al, 0 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, 4 |
out dx, al |
ret |
;*************************************************************************** |
; Function |
; rtl8029_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; |
;*************************************************************************** |
rtl8029_probe: |
mov eax, [io_addr] |
mov [eth_nic_base], ax ; The IO address space is 16 bit only |
mov al, VENDOR_NONE |
mov [eth_vendor], al |
mov al, [eth_vendor] |
cmp al, VENDOR_NONE |
jne ep_check_have_vendor |
xor eax, eax |
mov [eth_bmem], eax |
mov al, FLAG_PIO |
mov [eth_flags], al |
mov ax, [eth_nic_base] |
add ax, NE_ASIC_OFFSET |
mov [eth_asic_base], ax |
mov al, MEM_16384 |
mov [eth_memsize], al |
mov al, 32 |
mov [eth_tx_start], al |
add al, D8390_TXBUF_SIZE |
mov [eth_rx_start], al |
mov dx, [eth_asic_base] |
add dx, NE_RESET |
in al, dx |
out dx, al |
in al, 0x84 |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, D8390_RCR_MON |
out dx, al |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, D8390_DCR_FT1_LS |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, MEM_8192 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, MEM_16384 |
out dx, al |
mov esi, test_data |
mov ebx, 8192 |
mov ecx, 14 |
call eth_pio_write |
mov ebx, 8192 |
mov ecx, 14 |
mov edi, test_buffer |
call eth_pio_read |
mov esi, test_buffer |
mov edi, test_data |
mov ecx, 13 |
cld |
rep cmpsb |
je ep_set_vendor |
mov al, [eth_flags] |
or al, FLAG_16BIT |
mov [eth_flags], al |
mov al, MEM_32768 |
mov [eth_memsize], al |
mov al, 64 |
mov [eth_tx_start], al |
add al, D8390_TXBUF_SIZE |
mov [eth_rx_start], al |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, D8390_DCR_WTS_FT1_LS |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, MEM_16384 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, MEM_32768 |
out dx, al |
mov esi, test_data |
mov ebx, 16384 |
mov ecx, 14 |
call eth_pio_write |
mov ebx, 16384 |
mov ecx, 14 |
mov edi, test_buffer |
call eth_pio_read |
mov esi, test_buffer |
mov edi, test_data |
mov ecx, 13 |
cld |
rep cmpsb |
ep_set_vendor: |
; this bit is odd - probably left over from my hacking |
mov ax, [eth_nic_base] |
cmp ax, 0 |
je rtl8029_exit |
cmp ax, ISA_MAX_ADDR |
jbe ep_001 |
mov al, [eth_flags] |
or al, FLAG_16BIT |
mov [eth_flags], al |
ep_001: |
mov al, VENDOR_NOVELL |
mov [eth_vendor], al |
mov ebx, 0 |
mov ecx, 16 |
mov edi, romdata |
call eth_pio_read |
mov ecx, ETH_ALEN |
mov esi, romdata |
mov edi, node_addr |
mov bl, [eth_flags] |
and bl, FLAG_16BIT |
ep_002: |
mov al, [esi] |
mov [edi], al |
inc edi |
inc esi |
cmp bl, FLAG_16BIT |
jne ep_003 |
inc esi |
ep_003: |
loop ep_002 |
ep_check_have_vendor: |
mov al, [eth_vendor] |
cmp al, VENDOR_NONE |
je rtl8029_exit |
cmp al, VENDOR_3COM |
je ep_reset_card |
mov eax, [eth_bmem] |
mov [eth_rmem], eax |
ep_reset_card: |
; Reset the card |
call rtl8029_reset |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
rtl8029_exit: |
ret |
;*************************************************************************** |
; Function |
; rtl8029_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; |
;*************************************************************************** |
rtl8029_poll: |
mov eax, Ether_buffer |
mov [eth_rx_data_ptr], eax |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_RSR |
in al, dx |
and al, D8390_RSTAT_PRX |
cmp al, D8390_RSTAT_PRX |
jne nsp_exit |
mov dx, bx |
add dx, D8390_P0_BOUND |
in al, dx |
inc al |
cmp al, [eth_memsize] |
jb nsp_001 |
mov al, [eth_rx_start] |
nsp_001: |
mov ch, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS1 |
out dx, al |
mov dx, bx |
add dx, D8390_P1_CURR |
in al, dx ; get current page |
mov cl, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0 |
out dx, al |
cmp cl, [eth_memsize] |
jb nsp_002 |
mov cl, [eth_rx_start] |
nsp_002: |
cmp cl, ch |
je nsp_exit |
xor ax, ax |
mov ah, ch |
mov [pktoff], ax |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_003 |
movzx ebx, word [pktoff] |
mov edi, pkthdr |
mov ecx, 4 |
call eth_pio_read |
jmp nsp_004 |
nsp_003: |
mov edi, [eth_rmem] |
movzx eax, word [pktoff] |
add edi, eax |
mov eax, [edi] |
mov [pkthdr], eax |
nsp_004: |
mov ax, [pktoff] |
add ax, 4 |
mov [pktoff], ax |
mov ax, [pkthdr + 2] |
sub ax, 4 |
mov [eth_tmp_len], ax |
cmp ax, ETH_ZLEN |
jb nsp_exit |
cmp ax, ETH_FRAME_LEN |
ja nsp_exit |
mov al, [pkthdr] |
and al, D8390_RSTAT_PRX |
cmp al, D8390_RSTAT_PRX |
jne nsp_exit |
; Right, we can now get the data |
mov ax, [eth_tmp_len] |
mov [eth_rx_data_len], ax |
xor ebx, ebx |
mov bh, [eth_memsize] |
sub bx, [pktoff] |
cmp [eth_tmp_len], bx |
jbe nsp_005 |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_006 |
push ebx |
mov ecx, ebx |
xor ebx, ebx |
mov bx, [pktoff] |
mov edi, [eth_rx_data_ptr] |
call eth_pio_read |
pop ebx |
jmp nsp_007 |
nsp_006: |
; Not implemented, as we are using PIO mode on this card |
nsp_007: |
xor ax, ax |
mov ah, [eth_rx_start] |
mov [pktoff], ax |
mov eax, [eth_rx_data_ptr] |
add eax, ebx |
mov [eth_rx_data_ptr], eax |
mov ax, [eth_tmp_len] |
sub ax, bx |
mov [eth_tmp_len], ax |
nsp_005: |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_008 |
xor ebx, ebx |
mov bx, [pktoff] |
xor ecx, ecx |
mov cx, [eth_tmp_len] |
mov edi, [eth_rx_data_ptr] |
call eth_pio_read |
jmp nsp_009 |
nsp_008: |
; Not implemented, as we are using PIO mode on this card |
nsp_009: |
mov al, [pkthdr+1] |
cmp al, [eth_rx_start] |
jne nsp_010 |
mov al, [eth_memsize] |
nsp_010: |
mov dx, [eth_nic_base] |
add dx, D8390_P0_BOUND |
dec al |
out dx, al |
nsp_exit: |
ret |
;*************************************************************************** |
; Function |
; rtl8029_transmit |
; |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
;*************************************************************************** |
rtl8029_transmit: |
mov [eth_type], bx |
pusha |
mov esi, edi |
xor bx, bx |
mov bh, [eth_tx_start] |
mov ecx, ETH_ALEN |
call eth_pio_write |
mov esi, node_addr |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_ALEN |
mov ecx, ETH_ALEN |
call eth_pio_write |
mov esi, eth_type |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_ALEN |
add bx, ETH_ALEN |
mov ecx, 2 |
call eth_pio_write |
popa |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_HLEN |
push ecx |
call eth_pio_write |
pop ecx |
add ecx, ETH_HLEN |
cmp ecx, ETH_ZLEN |
jae nst_001 |
mov ecx, ETH_ZLEN |
nst_001: |
push ecx |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STA |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TPSR |
mov al, [eth_tx_start] |
out dx, al |
pop ecx |
mov dx, bx |
add dx, D8390_P0_TBCR0 |
mov al, cl |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TBCR1 |
mov al, ch |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_TXP_RD2_STA |
out dx, al |
ret |
/kernel/branches/gfx_kernel/network/eth_drv/rtl8139.inc |
---|
0,0 → 1,595 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; RTL8139.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.2 11 August 2003 ;; |
;; ;; |
;; Driver for chips of RealTek 8139 family ;; |
;; References: ;; |
;; www.realtek.com.hw - data sheets ;; |
;; rtl8139.c - linux driver ;; |
;; 8139too.c - linux driver ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; Copyright 2003 Endre Kozma, ;; |
;; endre.kozma@axelero.hu ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
ETH_ALEN equ 6 |
ETH_HLEN equ (2 * ETH_ALEN + 2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
PCI_REG_COMMAND equ 0x04 ; command register |
PCI_BIT_PIO equ 0 ; bit0: io space control |
PCI_BIT_MMIO equ 1 ; bit1: memory space control |
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master |
RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0 |
RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4 |
RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor |
RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor |
RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address |
RTL8139_REG_COMMAND equ 0x37 ; command register |
RTL8139_REG_CAPR equ 0x38 ; current address of packet read |
RTL8139_REG_IMR equ 0x3c ; interrupt mask register |
RTL8139_REG_ISR equ 0x3e ; interrupt status register |
RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register |
RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0 |
RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1 |
RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2 |
RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3 |
RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0 |
RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0 |
RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1 |
RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2 |
RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3 |
RTL8139_REG_MPC equ 0x4c ; missed packet counter |
RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register |
RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1 |
RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4 |
RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register |
RTL8139_REG_BMCR equ 0x62 ; basic mode control register |
RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register |
; 5.1 packet header |
RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes |
RTL8139_BIT_LONG equ 3 ; total packet length > 4k |
RTL8139_BIT_CRC equ 2 ; crc error occured |
RTL8139_BIT_FAE equ 1 ; frame alignment error occured |
RTL8139_BIT_ROK equ 0 ; received packet is ok |
; 5.4 command register |
RTL8139_BIT_RST equ 4 ; reset bit |
RTL8139_BIT_RE equ 3 ; receiver enabled |
RTL8139_BIT_TE equ 2 ; transmitter enabled |
RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored |
; 5.6 interrupt status register |
RTL8139_BIT_ISR_TOK equ 2 ; transmit ok |
RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt |
RTL8139_BIT_ISR_ROK equ 0 ; receive ok |
; 5.7 transmit configyration register |
RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst |
RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16) |
; 5.8 receive configuration register |
RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold |
RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator |
RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst |
RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping |
RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356 |
RTL8139_BIT_AER equ 5 ; accept error packets |
RTL8139_BIT_AR equ 4 ; accept runt packets |
RTL8139_BIT_AB equ 3 ; accept broadcast packets |
RTL8139_BIT_AM equ 2 ; accept multicast packets |
RTL8139_BIT_APM equ 1 ; accept physical match packets |
RTL8139_BIT_AAP equ 0 ; accept all packets |
; 5.9 93C46/93C56 command register |
RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1 |
RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0 |
RTL8139_BIT_93C46_EECS equ 3 ; chip select |
RTL8139_BIT_93C46_EESK equ 2 ; serial data clock |
RTL8139_BIT_93C46_EEDI equ 1 ; serial data input |
RTL8139_BIT_93C46_EEDO equ 0 ; serial data output |
; 5.11 configuration register 1 |
RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1 |
RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips |
RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips |
RTL8139_BIT_PMEn equ 0 ; power management enabled |
; 5.14 configuration register 4 |
RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4 |
; 6.2 transmit status register |
RTL8139_BIT_ERTXTH equ 16 ; early TX threshold |
RTL8139_BIT_TOK equ 15 ; transmit ok |
RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed |
; 6.18 basic mode control register |
RTL8139_BIT_ANE equ 12 ; auto negotiation enable |
; 6.20 auto negotiation advertisement register |
RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex |
RTL8139_BIT_TX equ 7 ; 100base-T |
RTL8139_BIT_10FD equ 6 ; 10base-T full duplex |
RTL8139_BIT_10 equ 5 ; 10base-T |
RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001 |
; RX/TX buffer size |
RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k |
RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN) |
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC |
RTL8139_NUM_TX_DESC equ 4 |
RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC) |
RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16) |
RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==2048 |
RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256 |
RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==unlimited |
RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==no threshold |
RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \ |
or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \ |
or (1 shl RTL8139_BIT_NOWRAP) \ |
or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \ |
or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \ |
or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \ |
or (1 shl RTL8139_BIT_AM)) |
RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout |
EE_93C46_REG_ETH_ID equ 7 ; MAC offset |
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address |
EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address |
EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address |
EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress |
VER_RTL8139 equ 1100000b |
VER_RTL8139A equ 1110000b |
; VER_RTL8139AG equ 1110100b |
VER_RTL8139B equ 1111000b |
VER_RTL8130 equ VER_RTL8139B |
VER_RTL8139C equ 1110100b |
VER_RTL8100 equ 1111010b |
VER_RTL8100B equ 1110101b |
VER_RTL8139D equ VER_RTL8100B |
VER_RTL8139CP equ 1110110b |
VER_RTL8101 equ 1110111b |
IDX_RTL8139 equ 0 |
IDX_RTL8139A equ 1 |
IDX_RTL8139B equ 2 |
IDX_RTL8139C equ 3 |
IDX_RTL8100 equ 4 |
IDX_RTL8139D equ 5 |
IDX_RTL8139D equ 6 |
IDX_RTL8101 equ 7 |
; These two must be 4 byte aligned ( which they are ) |
rtl8139_rx_buff equ eth_data_start |
rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE) |
uglobal |
align 4 |
rtl8139_rx_buff_offset: dd 0 |
curr_tx_desc: dd 0 |
endg |
iglobal |
hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C |
db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101 |
HW_VER_ARRAY_SIZE = $-hw_ver_array |
endg |
uglobal |
hw_ver_id: db 0 |
endg |
;*************************************************************************** |
; Function |
; rtl8139_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
rtl8139_probe: |
; enable the device |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
call pci_read_reg |
mov cx, ax |
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) |
and cl, not (1 shl PCI_BIT_MMIO) |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
call pci_write_reg |
; get chip version |
mov edx, [io_addr] |
add edx, RTL8139_REG_TXCONFIG_2 |
in ax, dx |
shr ah, 2 |
shr ax, 6 |
and al, 01111111b |
mov ecx, HW_VER_ARRAY_SIZE-1 |
.chip_ver_loop: |
cmp al, [hw_ver_array+ecx] |
je .chip_ver_found |
dec ecx |
jns .chip_ver_loop |
xor cl, cl ; default RTL8139 |
.chip_ver_found: |
mov [hw_ver_id], cl |
; wake up the chip |
mov edx, [io_addr] |
add edx, RTL8139_REG_HLTCLK |
mov al, 'R' ; run the clock |
out dx, al |
; unlock config and BMCR registers |
add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
out dx, al |
; enable power management |
add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR |
in al, dx |
cmp byte [hw_ver_id], IDX_RTL8139B |
jl .old_chip |
; set LWAKE pin to active high (default value). |
; it is for Wake-On-LAN functionality of some motherboards. |
; this signal is used to inform the motherboard to execute a wake-up process. |
; only at newer chips. |
or al, (1 shl RTL8139_BIT_PMEn) |
and al, not (1 shl RTL8139_BIT_LWACT) |
out dx, al |
add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1 |
in al, dx |
and al, not (1 shl RTL8139_BIT_LWPTN) |
out dx, al |
jmp .finish_wake_up |
.old_chip: |
; wake up older chips |
and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN)) |
out dx, al |
.finish_wake_up: |
; lock config and BMCR registers |
xor al, al |
mov edx, [io_addr] |
add edx, RTL8139_REG_9346CR |
out dx, al |
;*************************************************************************** |
; Function |
; rt8139_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
rtl8139_reset: |
mov edx, [io_addr] |
add edx, RTL8139_REG_COMMAND |
mov al, 1 shl RTL8139_BIT_RST |
out dx, al |
mov cx, 1000 ; wait no longer for the reset |
.wait_for_reset: |
in al, dx |
test al, 1 shl RTL8139_BIT_RST |
jz .reset_completed ; RST remains 1 during reset |
dec cx |
jns .wait_for_reset |
.reset_completed: |
; get MAC (hardware address) |
mov ecx, 2 |
.mac_read_loop: |
lea eax, [EE_93C46_REG_ETH_ID+ecx] |
push ecx |
call rtl8139_read_eeprom |
pop ecx |
mov [node_addr+ecx*2], ax |
dec ecx |
jns .mac_read_loop |
; unlock config and BMCR registers |
mov edx, [io_addr] |
add edx, RTL8139_REG_9346CR |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
out dx, al |
; initialize multicast registers (no filtering) |
mov eax, 0xffffffff |
add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR |
out dx, eax |
add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0 |
out dx, eax |
; enable Rx/Tx |
mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE) |
add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4 |
out dx, al |
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold |
; accept broadcast packets, accept physical match packets |
mov ax, RTL8139_RX_CONFIG |
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
out dx, ax |
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 |
mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \ |
or (RTL8139_TXRR shl RTL8139_BIT_TXRR) |
add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG |
out dx, ax |
; enable auto negotiation |
add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG |
in ax, dx |
or ax, (1 shl RTL8139_BIT_ANE) |
out dx, ax |
; set auto negotiation advertisement |
add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR |
in ax, dx |
or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \ |
or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \ |
or (1 shl RTL8139_BIT_TXFD) |
out dx, ax |
; lock config and BMCR registers |
xor eax, eax |
add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR |
out dx, al |
; init RX/TX pointers |
mov [rtl8139_rx_buff_offset], eax |
mov [curr_tx_desc], eax |
; clear missing packet counter |
add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR |
out dx, eax |
; disable all interrupts |
add edx, RTL8139_REG_IMR - RTL8139_REG_MPC |
out dx, ax |
; set RxBuffer address, init RX buffer offset, init TX ring |
mov eax, rtl8139_rx_buff |
add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR |
out dx, eax |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
ret |
;*************************************************************************** |
; Function |
; rtl8139_read_eeprom |
; Description |
; reads eeprom type 93c46 and 93c56 |
; Parameters |
; al - word to be read (6bit in case of 93c46 and 8bit otherwise) |
; Return value |
; ax - word read in |
; Destroyed register(s) |
; eax, cx, ebx, edx |
; |
;*************************************************************************** |
rtl8139_read_eeprom: |
movzx ebx, al |
mov edx, [io_addr] |
add edx, RTL8139_REG_RXCONFIG |
in al, dx |
test al, (1 shl RTL8139_BIT_9356SEL) |
jz .type_93c46 |
; and bl, 01111111b ; don't care first bit |
or bx, EE_93C56_READ_CMD ; it contains start bit |
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter |
jmp .read_eeprom |
.type_93c46: |
and bl, 00111111b |
or bx, EE_93C46_READ_CMD ; it contains start bit |
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter |
.read_eeprom: |
add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0 |
; mov al, (1 shl RTL8139_BIT_93C46_EEM1) |
; out dx, al |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom |
out dx, al |
.cmd_loop: |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
bt bx, cx |
jnc .zero_bit |
or al, (1 shl RTL8139_BIT_93C46_EEDI) |
.zero_bit: |
out dx, al |
; push eax |
; in eax, dx ; eeprom delay |
; pop eax |
or al, (1 shl RTL8139_BIT_93C46_EESK) |
out dx, al |
; in eax, dx ; eeprom delay |
dec cx |
jns .cmd_loop |
; in eax, dx ; eeprom delay |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
out dx, al |
mov cl, 0xf |
.read_loop: |
shl ebx, 1 |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) \ |
or (1 shl RTL8139_BIT_93C46_EESK) |
out dx, al |
; in eax, dx ; eeprom delay |
in al, dx |
and al, (1 shl RTL8139_BIT_93C46_EEDO) |
jz .dont_set |
inc ebx |
.dont_set: |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) |
out dx, al |
; in eax, dx ; eeprom delay |
dec cl |
jns .read_loop |
xor al, al |
out dx, al |
mov ax, bx |
ret |
;*************************************************************************** |
; Function |
; rtl8139_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; Destroyed registers |
; eax, edx, esi, edi |
; ToDo |
; for waiting of timeout the rtl8139 internal timer |
; should be used |
; |
;*************************************************************************** |
rtl8139_transmit: |
cmp ecx, MAX_ETH_FRAME_SIZE |
jg .finish ; packet is too long |
push ecx |
; check descriptor |
mov ecx, [curr_tx_desc] |
mov edx, [io_addr] |
lea edx, [edx+ecx*4+RTL8139_REG_TSD0] |
push edx ebx |
in ax, dx |
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
jz .send_packet |
test ax, 0x1fff ; or no size given |
jz .send_packet |
; wait for timeout |
mov ebx, RTL8139_TX_TIMEOUT |
mov eax, 0x5 ; delay x/100 secs |
int 0x40 |
in ax, dx |
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
jz .send_packet |
; chip hung, reset it |
call rtl8139_reset |
; reset the card |
.send_packet: |
; calculate tx_buffer address |
pop ebx |
push esi |
mov eax, MAX_ETH_FRAME_SIZE |
mul dword [curr_tx_desc] |
mov esi, edi |
lea edi, [rtl8139_tx_buff+eax] |
mov eax, edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi, node_addr |
movsd |
movsw |
; copy packet type |
mov [edi], bx |
add edi, 2 |
; copy the packet data |
pop esi edx ecx |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
push ecx |
and ecx, 3 |
rep movsb |
; set address |
add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0 |
out dx, eax |
; set size and early threshold |
pop eax ; pick up the size |
add eax, ETH_HLEN |
cmp eax, ETH_ZLEN |
jnc .no_pad |
mov eax, ETH_ZLEN |
.no_pad: |
or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH) |
add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0 |
out dx, eax |
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... |
inc dword [curr_tx_desc] |
and dword [curr_tx_desc], 3 |
.finish: |
ret |
;*************************************************************************** |
; Function |
; rtl8139_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Destroyed register(s) |
; eax, edx, ecx |
; |
;*************************************************************************** |
rtl8139_poll: |
mov word [eth_rx_data_len], 0 |
mov edx, [io_addr] |
add edx, RTL8139_REG_COMMAND |
in al, dx |
test al, (1 shl RTL8139_BIT_BUFE) |
jnz .finish |
; new packet received copy it from rx_buffer into Ether_buffer |
mov eax, rtl8139_rx_buff |
add eax, [rtl8139_rx_buff_offset] |
; check if packet is ok |
test byte [eax], (1 shl RTL8139_BIT_ROK) |
jz .reset_rx |
; packet is ok copy it into the Ether_buffer |
movzx ecx, word [eax+2] ; packet length |
sub ecx, 4 ; don't copy CRC |
mov word [eth_rx_data_len], cx |
push ecx |
shr ecx, 2 ; first copy dword-wise |
lea esi, [eax+4] ; don't copy the packet header |
mov edi, Ether_buffer |
cld |
rep movsd ; copy the dwords |
pop ecx |
and ecx, 3 |
rep movsb ; copy the rest bytes |
; update rtl8139_rx_buff_offset |
movzx eax, word [eax+2] ; packet length |
add eax, [rtl8139_rx_buff_offset] |
add eax, 4+3 ; packet header is 4 bytes long + dword alignment |
and eax, not 3 ; dword alignment |
cmp eax, RTL8139_RX_BUFFER_SIZE |
jl .no_wrap |
sub eax, RTL8139_RX_BUFFER_SIZE |
.no_wrap: |
mov [rtl8139_rx_buff_offset], eax |
; update CAPR register |
sub eax, 0x10 ; value 0x10 is a constant for CAPR |
add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND |
out dx, ax |
.finish: |
; clear active interrupt sources |
mov edx, [io_addr] |
add edx, RTL8139_REG_ISR |
in ax, dx |
out dx, ax |
ret |
.reset_rx: |
in al, dx ; read command register |
push eax |
and al, not (1 shl RTL8139_BIT_RE) |
out dx, al |
pop eax |
out dx, al |
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
mov ax, RTL8139_RX_CONFIG |
out dx, ax |
ret |
/kernel/branches/gfx_kernel/network/eth_drv/sis900.inc |
---|
0,0 → 1,1148 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SIS900.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.4 26 April 2004 ;; |
;; ;; |
;; This driver is based on the SIS900 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2004 Jason Delozier, ;; |
;; cordata51@hotmail.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; Updates: ;; |
;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************** |
; Interface |
; SIS900_reset |
; SIS900_probe |
; SIS900_poll |
; SIS900_transmit |
; |
;******************************************************************** |
;******************************************************************** |
; Comments: |
; Known to work with the following SIS900 ethernet cards: |
; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x91 |
; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x90 |
; |
; If your card is not listed, try it and let me know if it |
; functions properly and it will be aded to the list. If not |
; we may be able to add support for it. |
; |
; How To Use: |
; Add the following lines to Ethernet.inc in their appropriate locations |
; |
; include "Sis900.INC" |
; dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, |
; SIS900_transmit |
; dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, |
; SIS900_transmit ;untested |
; |
; ToDo: |
; - Enable MII interface for reading speed |
; and duplex settings. |
; |
; - Update Poll routine to support packet fragmentation. |
; |
; - Add additional support for other sis900 based cards |
; |
;******************************************************************** |
; comment the next line out if you don't want debug info printed |
; on the debug board. This option adds a lot of bytes to the driver |
; so it's worth to comment it out. |
; SIS900_DEBUG equ 1 |
;* buffers and descriptors |
cur_rx db 0 |
NUM_RX_DESC equ 4 ;* Number of RX descriptors * |
NUM_TX_DESC equ 1 ;* Number of TX descriptors * |
RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * |
TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer * |
uglobal |
align 4 |
txd: times (3 * NUM_TX_DESC) dd 0 |
rxd: times (3 * NUM_RX_DESC) dd 0 |
endg |
txb equ eth_data_start |
rxb equ txb + (NUM_TX_DESC * TX_BUFF_SZ) |
SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address * |
SIS900_ETH_HLEN equ 14 ;* Size of ethernet header * |
SIS900_ETH_ZLEN equ 60 ;* Minimum packet length * |
SIS900_DSIZE equ 0x00000fff |
SIS900_CRC_SIZE equ 4 |
SIS900_RFADDR_shift equ 16 |
;SIS900 Symbolic offsets to registers. |
SIS900_cr equ 0x0 ; Command Register |
SIS900_cfg equ 0x4 ; Configuration Register |
SIS900_mear equ 0x8 ; EEPROM Access Register |
SIS900_ptscr equ 0xc ; PCI Test Control Register |
SIS900_isr equ 0x10 ; Interrupt Status Register |
SIS900_imr equ 0x14 ; Interrupt Mask Register |
SIS900_ier equ 0x18 ; Interrupt Enable Register |
SIS900_epar equ 0x18 ; Enhanced PHY Access Register |
SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register |
SIS900_txcfg equ 0x24 ; Transmit Configuration Register |
SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register |
SIS900_rxcfg equ 0x34 ; Receive Configuration Register |
SIS900_flctrl equ 0x38 ; Flow Control Register |
SIS900_rxlen equ 0x3c ; Receive Packet Length Register |
SIS900_rfcr equ 0x48 ; Receive Filter Control Register |
SIS900_rfdr equ 0x4C ; Receive Filter Data Register |
SIS900_pmctrl equ 0xB0 ; Power Management Control Register |
SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register |
;SIS900 Command Register Bits |
SIS900_RELOAD equ 0x00000400 |
SIS900_ACCESSMODE equ 0x00000200 |
SIS900_RESET equ 0x00000100 |
SIS900_SWI equ 0x00000080 |
SIS900_RxRESET equ 0x00000020 |
SIS900_TxRESET equ 0x00000010 |
SIS900_RxDIS equ 0x00000008 |
SIS900_RxENA equ 0x00000004 |
SIS900_TxDIS equ 0x00000002 |
SIS900_TxENA equ 0x00000001 |
;SIS900 Configuration Register Bits |
SIS900_DESCRFMT equ 0x00000100 ; 7016 specific |
SIS900_REQALG equ 0x00000080 |
SIS900_SB equ 0x00000040 |
SIS900_POW equ 0x00000020 |
SIS900_EXD equ 0x00000010 |
SIS900_PESEL equ 0x00000008 |
SIS900_LPM equ 0x00000004 |
SIS900_BEM equ 0x00000001 |
SIS900_RND_CNT equ 0x00000400 |
SIS900_FAIR_BACKOFF equ 0x00000200 |
SIS900_EDB_MASTER_EN equ 0x00002000 |
;SIS900 Eeprom Access Reigster Bits |
SIS900_MDC equ 0x00000040 |
SIS900_MDDIR equ 0x00000020 |
SIS900_MDIO equ 0x00000010 ; 7016 specific |
SIS900_EECS equ 0x00000008 |
SIS900_EECLK equ 0x00000004 |
SIS900_EEDO equ 0x00000002 |
SIS900_EEDI equ 0x00000001 |
;SIS900 TX Configuration Register Bits |
SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding |
SIS900_MLB equ 0x20000000 ;Mac Loopback Enable |
SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup) |
SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du |
;SIS900 RX Configuration Register Bits |
SIS900_AJAB equ 0x08000000 ; |
SIS900_ATX equ 0x10000000 ;Accept Transmit Packets |
SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes) |
SIS900_AEP equ 0x80000000 ;accept error packets |
;SIS900 Interrupt Reigster Bits |
SIS900_WKEVT equ 0x10000000 |
SIS900_TxPAUSEEND equ 0x08000000 |
SIS900_TxPAUSE equ 0x04000000 |
SIS900_TxRCMP equ 0x02000000 |
SIS900_RxRCMP equ 0x01000000 |
SIS900_DPERR equ 0x00800000 |
SIS900_SSERR equ 0x00400000 |
SIS900_RMABT equ 0x00200000 |
SIS900_RTABT equ 0x00100000 |
SIS900_RxSOVR equ 0x00010000 |
SIS900_HIBERR equ 0x00008000 |
SIS900_SWINT equ 0x00001000 |
SIS900_MIBINT equ 0x00000800 |
SIS900_TxURN equ 0x00000400 |
SIS900_TxIDLE equ 0x00000200 |
SIS900_TxERR equ 0x00000100 |
SIS900_TxDESC equ 0x00000080 |
SIS900_TxOK equ 0x00000040 |
SIS900_RxORN equ 0x00000020 |
SIS900_RxIDLE equ 0x00000010 |
SIS900_RxEARLY equ 0x00000008 |
SIS900_RxERR equ 0x00000004 |
SIS900_RxDESC equ 0x00000002 |
SIS900_RxOK equ 0x00000001 |
;SIS900 Interrupt Enable Reigster Bits |
SIS900_IE equ 0x00000001 |
;SIS900 Revision ID |
SIS900B_900_REV equ 0x03 |
SIS630A_900_REV equ 0x80 |
SIS630E_900_REV equ 0x81 |
SIS630S_900_REV equ 0x82 |
SIS630EA1_900_REV equ 0x83 |
SIS630ET_900_REV equ 0x84 |
SIS635A_900_REV equ 0x90 |
SIS900_960_REV equ 0x91 |
;SIS900 Receive Filter Control Register Bits |
SIS900_RFEN equ 0x80000000 |
SIS900_RFAAB equ 0x40000000 |
SIS900_RFAAM equ 0x20000000 |
SIS900_RFAAP equ 0x10000000 |
SIS900_RFPromiscuous equ 0x70000000 |
;SIS900 Reveive Filter Data Mask |
SIS900_RFDAT equ 0x0000FFFF |
;SIS900 Eeprom Address |
SIS900_EEPROMSignature equ 0x00 |
SIS900_EEPROMVendorID equ 0x02 |
SIS900_EEPROMDeviceID equ 0x03 |
SIS900_EEPROMMACAddr equ 0x08 |
SIS900_EEPROMChecksum equ 0x0b |
;The EEPROM commands include the alway-set leading bit. |
;SIS900 Eeprom Command |
SIS900_EEread equ 0x0180 |
SIS900_EEwrite equ 0x0140 |
SIS900_EEerase equ 0x01C0 |
SIS900_EEwriteEnable equ 0x0130 |
SIS900_EEwriteDisable equ 0x0100 |
SIS900_EEeraseAll equ 0x0120 |
SIS900_EEwriteAll equ 0x0110 |
SIS900_EEaddrMask equ 0x013F |
SIS900_EEcmdShift equ 16 |
;For SiS962 or SiS963, request the eeprom software access |
SIS900_EEREQ equ 0x00000400 |
SIS900_EEDONE equ 0x00000200 |
SIS900_EEGNT equ 0x00000100 |
;General Varibles |
SIS900_pci_revision: db 0 |
SIS900_Status dd 0x03000000 |
sis900_specific_table: |
; dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0 |
; dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0 |
dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0 |
dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0 |
dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN |
dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0 |
dd SIS900_960_REV,SIS960_get_mac_addr,0 |
dd SIS900B_900_REV,SIS900_get_mac_addr,0 |
dd 0,0,0,0 ; end of list |
sis900_get_mac_func: dd 0 |
sis900_special_func: dd 0 |
sis900_table_entries: db 8 |
;*************************************************************************** |
; Function |
; SIS900_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
;not done - still need to probe mii transcievers |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0 |
end if |
SIS900_probe: |
;******Wake Up Chip******* |
mov al, 4 |
mov bh, [pci_dev] |
mov ecx, 0 |
mov ah, [pci_bus] |
mov bl, 0x40 |
call pci_write_reg |
;*******Set some PCI Settings********* |
call SIS900_adjust_pci_device |
;*****Get Card Revision****** |
mov al, 1 ;one byte to read |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x08 ;Revision Register |
call pci_read_reg |
mov [SIS900_pci_revision], al ;save the revision for later use |
;****** Look up through the sis900_specific_table |
mov esi,sis900_specific_table |
.probe_loop: |
cmp dword [esi],0 ; Check if we reached end of the list |
je .probe_loop_failed |
cmp al,[esi] ; Check if revision is OK |
je .probe_loop_ok |
add esi,12 ; Advance to next entry |
jmp .probe_loop |
.probe_loop_failed: |
jmp SIS900_Probe_Unsupported |
;*********Find Get Mac Function********* |
.probe_loop_ok: |
mov eax,[esi+4] ; Get pointer to "get MAC" function |
mov [sis900_get_mac_func],eax |
mov eax,[esi+8] ; Get pointer to special initialization fn |
mov [sis900_special_func],eax |
;******** Get MAC ******** |
call dword [sis900_get_mac_func] |
;******** Call special initialization fn if requested ******** |
cmp dword [sis900_special_func],0 |
je .no_special_init |
call dword [sis900_special_func] |
.no_special_init: |
;******** Set table entries ******** |
mov al,[SIS900_pci_revision] |
cmp al,SIS635A_900_REV |
jae .ent16 |
cmp al,SIS900B_900_REV |
je .ent16 |
jmp .ent8 |
.ent16: |
mov byte [sis900_table_entries],16 |
.ent8: |
;*******Probe for mii transceiver******* |
;TODO!!********************* |
;*******Initialize Device******* |
call sis900_init |
ret |
SIS900_Probe_Unsupported: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Str_Unsupported |
call sys_msg_board_str |
end if |
ret |
;*************************************************************************** |
; Function: sis900_init |
; |
; Description: resets the ethernet controller chip and various |
; data structures required for sending and receiving packets. |
; |
; Arguments: |
; |
; returns: none |
;not done |
;*************************************************************************** |
sis900_init: |
call SIS900_reset ;Done |
call SIS900_init_rxfilter ;Done |
call SIS900_init_txd ;Done |
call SIS900_init_rxd ;Done |
call SIS900_set_rx_mode ;done |
call SIS900_set_tx_mode |
;call SIS900_check_mode |
ret |
;*************************************************************************** |
; Function |
; SIS900_reset |
; Description |
; disables interrupts and soft resets the controller chip |
; |
;done+ |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Reset_Failed db 'Reset Failed ',0 |
end if |
SIS900_reset: |
;******Disable Interrupts and reset Receive Filter******* |
mov ebp, [io_addr] ; base address |
xor eax, eax ; 0 to initialize |
lea edx,[ebp+SIS900_ier] |
out dx, eax ; Write 0 to location |
lea edx,[ebp+SIS900_imr] |
out dx, eax ; Write 0 to location |
lea edx,[ebp+SIS900_rfcr] |
out dx, eax ; Write 0 to location |
;*******Reset Card*********************************************** |
lea edx,[ebp+SIS900_cr] |
in eax, dx ; Get current Command Register |
or eax, SIS900_RESET ; set flags |
or eax, SIS900_RxRESET ; |
or eax, SIS900_TxRESET ; |
out dx, eax ; Write new Command Register |
;*******Wait Loop************************************************ |
lea edx,[ebp+SIS900_isr] |
mov ecx, [SIS900_Status] ; Status we would like to see from card |
mov ebx, 2001 ; only loop 1000 times |
SIS900_Wait: |
dec ebx ; 1 less loop |
jz SIS900_DoneWait_e ; 1000 times yet? |
in eax, dx ; move interrup status to eax |
and eax, ecx |
xor ecx, eax |
jz SIS900_DoneWait |
jmp SIS900_Wait |
SIS900_DoneWait_e: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Reset_Failed |
call sys_msg_board_str |
end if |
SIS900_DoneWait: |
;*******Set Configuration Register depending on Card Revision******** |
lea edx,[ebp+SIS900_cfg] |
mov eax, SIS900_PESEL ; Configuration Register Bit |
mov bl, [SIS900_pci_revision] ; card revision |
mov cl, SIS635A_900_REV ; Check card revision |
cmp bl, cl |
je SIS900_RevMatch |
mov cl, SIS900B_900_REV ; Check card revision |
cmp bl, cl |
je SIS900_RevMatch |
out dx, eax ; no revision match |
jmp SIS900_Reset_Complete |
SIS900_RevMatch: ; Revision match |
or eax, SIS900_RND_CNT ; Configuration Register Bit |
out dx, eax |
SIS900_Reset_Complete: |
mov eax, [pci_data] |
mov [eth_status], eax |
ret |
;*************************************************************************** |
; Function: sis_init_rxfilter |
; |
; Description: sets receive filter address to our MAC address |
; |
; Arguments: |
; |
; returns: |
;done+ |
;*************************************************************************** |
SIS900_init_rxfilter: |
;****Get Receive Filter Control Register ******** |
mov ebp, [io_addr] ; base address |
lea edx,[ebp+SIS900_rfcr] |
in eax, dx ; get register |
push eax |
;****disable packet filtering before setting filter******* |
mov eax, SIS900_RFEN ;move receive filter enable flag |
not eax ;1s complement |
pop ebx ;and with our saved register |
and eax, ebx ;disable receiver |
push ebx ;save filter for another use |
out dx, eax ;set receive disabled |
;********load MAC addr to filter data register********* |
xor ecx, ecx |
SIS900_RXINT_Mac_Write: |
;high word of eax tells card which mac byte to write |
mov eax, ecx |
lea edx,[ebp+SIS900_rfcr] |
shl eax, 16 ; |
out dx, eax ; |
lea edx,[ebp+SIS900_rfdr] |
mov ax, word [node_addr+ecx*2] ; Get Mac ID word |
out dx, ax ; Send Mac ID |
inc cl ; send next word |
cmp cl, 3 ; more to send? |
jne SIS900_RXINT_Mac_Write |
;********enable packet filitering ***** |
pop eax ;old register value |
lea edx,[ebp+SIS900_rfcr] |
or eax, SIS900_RFEN ;enable filtering |
out dx, eax ;set register |
ret |
;*************************************************************************** |
;* |
;* Function: sis_init_txd |
;* |
;* Description: initializes the Tx descriptor |
;* |
;* Arguments: |
;* |
;* returns: |
;*done |
;*************************************************************************** |
SIS900_init_txd: |
;********** initialize TX descriptor ************** |
mov [txd], dword 0 ;put link to next descriptor in link field |
mov [txd+4],dword 0 ;clear status field |
mov [txd+8], dword txb ;save address to buffer ptr field |
;*************** load Transmit Descriptor Register *************** |
mov dx, [io_addr] ; base address |
add dx, SIS900_txdp ; TX Descriptor Pointer |
mov eax, txd ; First Descriptor |
out dx, eax ; move the pointer |
ret |
;*************************************************************************** |
;* Function: sis_init_rxd |
;* |
;* Description: initializes the Rx descriptor ring |
;* |
;* Arguments: |
;* |
;* Returns: |
;*done |
;*************************************************************************** |
SIS900_init_rxd: |
xor ecx,ecx |
mov [cur_rx], cl ;Set cuurent rx discriptor to 0 |
;******** init RX descriptors ******** |
SIS900_init_rxd_Loop: |
mov eax, ecx ;current descriptor |
imul eax, 12 ; |
mov ebx, ecx ;determine next link descriptor |
inc ebx ; |
cmp ebx, NUM_RX_DESC ; |
jne SIS900_init_rxd_Loop_0 ; |
xor ebx, ebx ; |
SIS900_init_rxd_Loop_0: ; |
imul ebx, 12 ; |
add ebx, rxd ; |
mov [rxd+eax], ebx ;save link to next descriptor |
mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size |
mov ebx, ecx ;find where the buf is located |
imul ebx,RX_BUFF_SZ ; |
add ebx, rxb ; |
mov [rxd+eax+8], ebx ;save buffer pointer |
inc ecx ;next descriptor |
cmp ecx, NUM_RX_DESC ; |
jne SIS900_init_rxd_Loop ; |
;********* load Receive Descriptor Register with address of first |
; descriptor********* |
mov dx, [io_addr] |
add dx, SIS900_rxdp |
mov eax, rxd |
out dx, eax |
ret |
;*************************************************************************** |
;* Function: sis900_set_tx_mode |
;* |
;* Description: |
;* sets the transmit mode to allow for full duplex |
;* |
;* |
;* Arguments: |
;* |
;* Returns: |
;* |
;* Comments: |
;* If you are having problems transmitting packet try changing the |
;* Max DMA Burst, Possible settings are as follows: |
;* 0x00000000 = 512 bytes |
;* 0x00100000 = 4 bytes |
;* 0x00200000 = 8 bytes |
;* 0x00300000 = 16 bytes |
;* 0x00400000 = 32 bytes |
;* 0x00500000 = 64 bytes |
;* 0x00600000 = 128 bytes |
;* 0x00700000 = 256 bytes |
;*************************************************************************** |
SIS900_set_tx_mode: |
mov ebp,[io_addr] |
lea edx,[ebp+SIS900_cr] |
in eax, dx ; Get current Command Register |
or eax, SIS900_TxENA ;Enable Receive |
out dx, eax |
lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset |
mov eax, SIS900_ATP ;allow automatic padding |
or eax, SIS900_HBI ;allow heartbeat ignore |
or eax, SIS900_CSI ;allow carrier sense ignore |
or eax, 0x00600000 ;Max DMA Burst |
or eax, 0x00000100 ;TX Fill Threshold |
or eax, 0x00000020 ;TX Drain Threshold |
out dx, eax |
ret |
;*************************************************************************** |
;* Function: sis900_set_rx_mode |
;* |
;* Description: |
;* sets the receive mode to accept all broadcast packets and packets |
;* with our MAC address, and reject all multicast packets. Also allows |
;* full-duplex |
;* |
;* Arguments: |
;* |
;* Returns: |
;* |
;* Comments: |
;* If you are having problems receiving packet try changing the |
;* Max DMA Burst, Possible settings are as follows: |
;* 0x00000000 = 512 bytes |
;* 0x00100000 = 4 bytes |
;* 0x00200000 = 8 bytes |
;* 0x00300000 = 16 bytes |
;* 0x00400000 = 32 bytes |
;* 0x00500000 = 64 bytes |
;* 0x00600000 = 128 bytes |
;* 0x00700000 = 256 bytes |
;*************************************************************************** |
SIS900_mc_filter: times 16 dw 0 |
SIS900_set_rx_mode: |
mov ebp,[io_addr] |
;**************update Multicast Hash Table in Receive Filter |
mov ebx, 0xffff |
xor cl, cl |
SIS900_set_rx_mode_Loop: |
mov eax, ecx |
shl eax, 1 |
mov [SIS900_mc_filter+eax], ebx |
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset |
mov eax, 4 ;determine table entry |
add al, cl |
shl eax, 16 |
out dx, eax ;tell card which entry to modify |
lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset |
mov eax, ebx ;entry value |
out dx, ax ;write value to table in card |
inc cl ;next entry |
cmp cl,[sis900_table_entries] ; |
jl SIS900_set_rx_mode_Loop |
;*******Set Receive Filter Control Register************* |
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset |
mov eax, SIS900_RFAAB ;accecpt all broadcast packets |
or eax, SIS900_RFAAM ;accept all multicast packets |
or eax, SIS900_RFAAP ;Accept all packets |
or eax, SIS900_RFEN ;enable receiver filter |
out dx, eax |
;******Enable Receiver************ |
lea edx,[ebp+SIS900_cr] ; Command Register offset |
in eax, dx ; Get current Command Register |
or eax, SIS900_RxENA ;Enable Receive |
out dx, eax |
;*********Set |
lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset |
mov eax, SIS900_ATX ;Accept Transmit Packets |
; (Req for full-duplex and PMD Loopback) |
or eax, 0x00600000 ;Max DMA Burst |
or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes |
out dx, eax ; |
ret |
;*************************************************************************** |
; * SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model |
; * @pci_dev: the sis900 pci device |
; * @net_dev: the net device to get address for |
; * |
; * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM |
; * is shared by |
; * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first |
; * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access |
; * by LAN, otherwise is not. After MAC address is read from EEPROM, send |
; * EEDONE signal to refuse EEPROM access by LAN. |
; * The EEPROM map of SiS962 or SiS963 is different to SiS900. |
; * The signature field in SiS962 or SiS963 spec is meaningless. |
; * MAC address is read into @net_dev->dev_addr. |
; *done |
;* |
;* Return 0 is EAX = failure |
;*Done+ |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0 |
SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0 |
SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0 |
SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0 |
end if |
SIS960_get_mac_addr: |
mov ebp,[io_addr] |
;**********Send Request for eeprom access********************* |
lea edx,[ebp+SIS900_mear] ; Eeprom access register |
mov eax, SIS900_EEREQ ; Request access to eeprom |
out dx, eax ; Send request |
xor ebx,ebx ; |
;******Loop 4000 times and if access not granted error out***** |
SIS96X_Get_Mac_Wait: |
in eax, dx ;get eeprom status |
and eax, SIS900_EEGNT ;see if eeprom access granted flag is set |
jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom |
inc ebx ;else keep waiting |
cmp ebx, 4000 ;have we tried 4000 times yet? |
jl SIS96X_Get_Mac_Wait ;if not ask again |
xor eax, eax ;return zero in eax indicating failure |
;*******Debug ********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Failed |
call sys_msg_board_str |
end if |
jmp SIS960_get_mac_addr_done |
;**********EEprom access granted, read MAC from card************* |
SIS900_Got_EEP_Access: |
; zero based so 3-16 bit reads will take place |
mov ecx, 2 |
SIS96x_mac_read_loop: |
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address |
add eax, ecx ;Current Mac Byte Offset |
push ecx |
call sis900_read_eeprom ;try to read 16 bits |
pop ecx |
mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID varible |
dec ecx ;one less word to read |
jns SIS96x_mac_read_loop ;if more read more |
mov eax, 1 ;return non-zero indicating success |
;*******Debug Print MAC ID to debug window********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Address2 |
call sys_msg_board_str |
mov edx, node_addr |
call Create_Mac_String |
end if |
;**********Tell EEPROM We are Done Accessing It********************* |
SIS960_get_mac_addr_done: |
lea edx,[ebp+SIS900_mear] ; Eeprom access register |
mov eax, SIS900_EEDONE ;tell eeprom we are done |
out dx,eax |
ret |
;*************************************************************************** |
;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model |
;* @pci_dev: the sis900 pci device |
;* @net_dev: the net device to get address for |
;* |
;* Older SiS900 and friends, use EEPROM to store MAC address. |
;* MAC address is read from read_eeprom() into @net_dev->dev_addr. |
;* done/untested |
;*************************************************************************** |
SIS900_get_mac_addr: |
;*******Debug ********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Start |
call sys_msg_board_str |
end if |
;******** check to see if we have sane EEPROM ******* |
mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature |
call sis900_read_eeprom ;try to read 16 bits |
cmp ax, 0xffff |
je SIS900_Bad_Eeprom |
cmp ax, 0 |
je SIS900_Bad_Eeprom |
;**************Read MacID************** |
; zero based so 3-16 bit reads will take place |
mov ecx, 2 |
SIS900_mac_read_loop: |
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address |
add eax, ecx ;Current Mac Byte Offset |
push ecx |
call sis900_read_eeprom ;try to read 16 bits |
pop ecx |
mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID storage |
dec ecx ;one less word to read |
jns SIS900_mac_read_loop ;if more read more |
mov eax, 1 ;return non-zero indicating success |
;*******Debug Print MAC ID to debug window********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Address |
call sys_msg_board_str |
mov edx, node_addr |
call Create_Mac_String |
end if |
ret |
SIS900_Bad_Eeprom: |
xor eax, eax |
;*******Debug ********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Failed |
call sys_msg_board_str |
end if |
ret |
;*************************************************************************** |
;* Get_Mac_SIS635_900_REV: - Get MAC address for model 635 |
;* |
;* |
;*************************************************************************** |
Get_Mac_SIS635_900_REV: |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Start |
call sys_msg_board_str |
end if |
mov ebp,[io_addr] |
lea edx,[ebp+SIS900_rfcr] |
in eax,dx |
mov edi,eax ; EDI=rfcrSave |
lea edx,[ebp+SIS900_cr] |
or eax,SIS900_RELOAD |
out dx,eax |
xor eax,eax |
out dx,eax |
; Disable packet filtering before setting filter |
lea edx,[ebp+SIS900_rfcr] |
mov eax,edi |
and edi,not SIS900_RFEN |
out dx,eax |
; Load MAC to filter data register |
xor ecx,ecx |
mov esi,node_addr |
.get_mac_loop: |
lea edx,[ebp+SIS900_rfcr] |
mov eax,ecx |
shl eax,SIS900_RFADDR_shift |
out dx,eax |
lea edx,[ebp+SIS900_rfdr] |
in eax,dx |
mov [esi],ax |
add esi,2 |
inc ecx |
cmp ecx,3 |
jne .get_mac_loop |
; Enable packet filtering |
;lea edx,[ebp+SIS900_rfcr] |
;mov eax,edi |
;or eax,SIS900_RFEN |
;out dx, eax |
;*******Debug Print MAC ID to debug window********************** |
if defined SIS900_DEBUG |
mov esi,SIS900_Debug_Str_GetMac_Address |
call sys_msg_board_str |
mov edx, node_addr |
call Create_Mac_String |
end if |
ret |
;*************************************************************************** |
;* Function: sis900_read_eeprom |
;* |
;* Description: reads and returns a given location from EEPROM |
;* |
;* Arguments: eax - location: requested EEPROM location |
;* |
;* Returns: eax : contents of requested EEPROM location |
;* |
; Read Serial EEPROM through EEPROM Access Register, Note that location is |
; in word (16 bits) unit */ |
;done+ |
;*************************************************************************** |
sis900_read_eeprom: |
push esi |
push edx |
push ecx |
push ebx |
mov ebp,[io_addr] |
mov ebx, eax ;location of Mac byte to read |
or ebx, SIS900_EEread ; |
lea edx,[ebp+SIS900_mear] ; Eeprom access register |
xor eax, eax ; start send |
out dx,eax |
call SIS900_Eeprom_Delay_1 |
mov eax, SIS900_EECLK |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
;************ Shift the read command (9) bits out. ********* |
mov cl, 8 ; |
sis900_read_eeprom_Send: |
mov eax, 1 |
shl eax, cl |
and eax, ebx |
jz SIS900_Read_Eeprom_8 |
mov eax, 9 |
jmp SIS900_Read_Eeprom_9 |
SIS900_Read_Eeprom_8: |
mov eax, 8 |
SIS900_Read_Eeprom_9: |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
or eax, SIS900_EECLK |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
cmp cl, 0 |
je sis900_read_eeprom_Send_Done |
dec cl |
jmp sis900_read_eeprom_Send |
;********************* |
sis900_read_eeprom_Send_Done: |
mov eax, SIS900_EECS ; |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
;********** Read 16-bits of data in *************** |
mov cx, 16 ;16 bits to read |
sis900_read_eeprom_Send2: |
mov eax, SIS900_EECS |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
or eax, SIS900_EECLK |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
in eax, dx |
shl ebx, 1 |
and eax, SIS900_EEDO |
jz SIS900_Read_Eeprom_0 |
or ebx, 1 |
SIS900_Read_Eeprom_0: |
dec cx |
jnz sis900_read_eeprom_Send2 |
;************** Terminate the EEPROM access. ************** |
xor eax, eax |
out dx, eax |
call SIS900_Eeprom_Delay_1 |
mov eax, SIS900_EECLK |
out dx, eax |
mov eax, ebx |
and eax, 0x0000ffff ;return only 16 bits |
pop ebx |
pop ecx |
pop edx |
pop esi |
ret |
;*************************************************************************** |
; Function |
; SIS900_Eeprom_Delay_1 |
; Description |
; |
; |
; |
; |
;*************************************************************************** |
SIS900_Eeprom_Delay_1: |
push eax |
in eax, dx |
pop eax |
ret |
;*************************************************************************** |
; Function |
; SIS900_poll |
; Description |
; polls card to see if there is a packet waiting |
; |
; Currently only supports one descriptor per packet, if packet is fragmented |
; between multiple descriptors you will lose part of the packet |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0 |
SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0 |
SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0 |
end if |
SIS900_poll: |
;**************Get Status ************** |
xor eax, eax ;get RX_Status |
mov [eth_rx_data_len], ax |
mov al, [cur_rx] ;find current discriptor |
imul eax, 12 ; |
mov ecx, [rxd+eax+4] ; get receive status |
;**************Check Status ************** |
mov ebx, ecx ;move status |
;Check RX_Status to see if packet is waiting |
and ebx, 0x80000000 |
jnz SIS900_poll_IS_packet |
ret |
;**********There is a packet waiting check it for errors************** |
SIS900_poll_IS_packet: |
mov ebx, ecx ;move status |
and ebx, 0x67C0000 ;see if there are any errors |
jnz SIS900_Poll_Error_Status |
;**************Check size of packet************* |
and ecx, SIS900_DSIZE ;get packet size minus CRC |
cmp cx, SIS900_CRC_SIZE |
;make sure packet contains data |
jle SIS900_Poll_Error_Size |
;*******Copy Good Packet to receive buffer****** |
sub cx, SIS900_CRC_SIZE ;dont want crc |
mov word [eth_rx_data_len], cx ;save size of packet |
;**********Continue copying packet**************** |
push ecx |
; first copy dword-wise, divide size by 4 |
shr ecx, 2 |
mov esi, [rxd+eax+8] ; set source |
mov edi, Ether_buffer ; set destination |
cld ; clear direction |
rep movsd ; copy the dwords |
pop ecx |
and ecx, 3 ; |
rep movsb |
;********Debug, tell user we have a good packet************* |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Pull_Packet_good |
call sys_msg_board_str |
end if |
jmp SIS900_Poll_Cnt ; |
;*************Error occured let user know through debug window*********** |
SIS900_Poll_Error_Status: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Pull_Bad_Packet_Status |
call sys_msg_board_str |
end if |
jmp SIS900_Poll_Cnt |
SIS900_Poll_Error_Size: |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Pull_Bad_Packet_Size |
call sys_msg_board_str |
end if |
;*************Increment to next available descriptor************** |
SIS900_Poll_Cnt: |
;Reset status, allow ethernet card access to descriptor |
mov ecx, RX_BUFF_SZ |
mov [rxd+eax+4], ecx ; |
inc [cur_rx] ;get next descriptor |
and [cur_rx],3 ;only 4 descriptors 0-3 |
;******Enable Receiver************ |
mov ebp, [io_addr] ; Base Address |
lea edx,[ebp+SIS900_cr] ; Command Register offset |
in eax, dx ; Get current Command Register |
or eax, SIS900_RxENA ;Enable Receive |
out dx, eax |
ret |
;*************************************************************************** |
; Function |
; SIS900_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
; only one transmit descriptor is used |
; |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0 |
SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0 |
end if |
SIS900_transmit: |
mov ebp, [io_addr] ; Base Address |
;******** Stop the transmitter ******** |
lea edx,[ebp+SIS900_cr] ; Command Register offset |
in eax, dx ; Get current Command Register |
or eax, SIS900_TxDIS ; Disable Transmitter |
out dx, eax |
;*******load Transmit Descriptor Register ******* |
lea edx,[ebp+SIS900_txdp] |
mov eax, txd |
out dx, eax |
;******* copy packet to descriptor******* |
push esi |
mov esi, edi ;copy destination addess |
mov edi, txb |
cld |
movsd |
movsw |
mov esi, node_addr ;copy my mac address |
movsd |
movsw |
mov [edi], bx ;copy packet type |
add edi, 2 |
pop esi ;restore pointer to source of packet |
push ecx ;save packet size |
shr ecx, 2 ;divide by 4, size in bytes send in dwords |
rep movsd ;copy data to decriptor |
pop ecx ;restore packet size |
push ecx ;save packet size |
and ecx, 3 ;last three bytes if not a multiple of 4 |
rep movsb |
;**************set length tag************** |
pop ecx ;restore packet size |
add ecx, SIS900_ETH_HLEN ;add header to length |
and ecx, SIS900_DSIZE ; |
;**************pad to minimum packet size **************not needed |
;cmp ecx, SIS900_ETH_ZLEN |
;jge SIS900_transmit_Size_Ok |
;push ecx |
;mov ebx, SIS900_ETH_ZLEN |
;sub ebx, ecx |
;mov ecx, ebx |
;rep movsb |
;pop ecx |
SIS900_transmit_Size_Ok: |
mov [txd+4], dword 0x80000000 ;card owns descriptor |
or [txd+4], ecx ;set size of packet |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Transmit_Packet |
call sys_msg_board_str |
end if |
;***************restart the transmitter ******** |
lea edx,[ebp+SIS900_cr] |
in eax, dx ; Get current Command Register |
or eax, SIS900_TxENA ; Enable Transmitter |
out dx, eax |
;****make sure packet transmitted successfully**** |
; mov esi,10 |
; call delay_ms |
mov eax, [txd+4] |
and eax, 0x6200000 |
jz SIS900_transmit_OK |
;**************Tell user there was an error through debug window |
if defined SIS900_DEBUG |
mov esi, SIS900_Debug_Transmit_Packet_Err |
call sys_msg_board_str |
end if |
SIS900_transmit_OK: |
;******** Disable interrupts by clearing the interrupt mask. ******** |
lea edx,[ebp+SIS900_imr] ; Interupt Mask Register |
xor eax, eax |
out dx,eax |
ret |
;*************************************************************************** |
;* Function: Create_Mac_String |
;* |
;* Description: Converts the 48 bit value to a string for display |
;* |
;* String Format: XX:XX:XX:XX:XX:XX |
;* |
;* Arguments: node_addr is location of 48 bit MAC ID |
;* |
;* Returns: Prints string to general debug window |
;* |
;* |
;done |
;*************************************************************************** |
if defined SIS900_DEBUG |
SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9' |
db 'A','B','C','D','E','F' |
Mac_str_build: times 20 db 0 |
Create_Mac_String: |
pusha |
xor ecx, ecx |
Create_Mac_String_loop: |
mov al,byte [edx+ecx];[node_addr+ecx] |
push eax |
shr eax, 4 |
and eax, 0x0f |
mov bl, byte [SIS900_Char_String+eax] |
mov [Mac_str_build+ecx*3], bl |
pop eax |
and eax, 0x0f |
mov bl, byte [SIS900_Char_String+eax] |
mov [Mac_str_build+1+ecx*3], bl |
cmp ecx, 5 |
je Create_Mac_String_done |
mov bl, ':' |
mov [Mac_str_build+2+ecx*3], bl |
inc ecx |
jmp Create_Mac_String_loop |
Create_Mac_String_done: ;Insert CR and Zero Terminate |
mov [Mac_str_build+2+ecx*3],byte 13 |
mov [Mac_str_build+3+ecx*3],byte 10 |
mov [Mac_str_build+4+ecx*3],byte 0 |
mov esi, Mac_str_build |
call sys_msg_board_str ;Print String to message board |
popa |
ret |
end if |
;*************************************************************************** |
;* Set device to be a busmaster in case BIOS neglected to do so. |
;* Also adjust PCI latency timer to a reasonable value, 64. |
;*************************************************************************** |
SIS900_adjust_pci_device: |
;*******Get current setting************************ |
mov al, 2 ;read a word |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x04 ;from command Register |
call pci_read_reg |
;******see if its already set as bus master******** |
mov bx, ax |
and bx,5 |
cmp bx,5 |
je SIS900_adjust_pci_device_Latency |
;******Make card a bus master******* |
mov cx, ax ;value to write |
mov bh, [pci_dev] |
mov al, 2 ;write a word |
or cx,5 |
mov ah, [pci_bus] |
mov bl, 0x04 ;to command register |
call pci_write_reg |
;******Check latency setting*********** |
SIS900_adjust_pci_device_Latency: |
;*******Get current latency setting************************ |
mov al, 1 ;read a byte |
mov bh, [pci_dev] |
mov ah, [pci_bus] |
mov bl, 0x0D ;from Lantency Timer Register |
call pci_read_reg |
;******see if its aat least 64 clocks******** |
cmp ax,64 |
jge SIS900_adjust_pci_device_Done |
;******Set latency to 32 clocks******* |
mov cx, 64 ;value to write |
mov bh, [pci_dev] |
mov al, 1 ;write a byte |
mov ah, [pci_bus] |
mov bl, 0x0D ;to Lantency Timer Register |
call pci_write_reg |
;******Check latency setting*********** |
SIS900_adjust_pci_device_Done: |
ret |
/kernel/branches/gfx_kernel/network/ip.inc |
---|
0,0 → 1,202 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; IP.INC ;; |
;; ;; |
;; IP Processes for Menuet OS TCP/IP stack ;; |
;; ;; |
;; Version 0.3 29 August 2002 ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************* |
; Interface |
; |
; ip_rx processes all packets received by the network layer |
; It calls the appropriate protocol handler |
; |
; |
; |
;******************************************************************* |
;*************************************************************************** |
; Function |
; ip_rx |
; |
; Description |
; Handles received IP packets |
; This is a kernel function, called by stack_handler |
; |
;*************************************************************************** |
ip_rx: |
; Look for a buffer to tx |
mov eax, IPIN_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je ipr_exit ; Exit if no buffer available |
push eax |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax ; Save the address in edx for use by future processes |
; Validate the IP checksum |
mov ebx, edx |
mov ah, [ebx + 10] |
mov al, [ebx + 11] ; Get the checksum in intel format |
mov [ebx + 10], word 0 ; clear checksum field - need to when |
; recalculating checksum |
; this needs two data pointers and two size #. |
; 2nd pointer can be of length 0 |
mov ebx, edx |
mov [checkAdd1], ebx |
mov [checkSize1], word 20 |
mov [checkAdd2], dword 0 |
mov [checkSize2], word 0 |
call checksum ; Recalculate IP checksum |
cmp ax, [checkResult] |
jnz ipr_dump |
; If the IP address is 255.255.255.255, accept it |
; - it is a broadcast packet, which we need for dhcp |
mov eax, [edx + 16] |
cmp eax, 0xffffffff |
je ipr_p0 |
; Validate the IP address, if it isn't broadcast |
cmp eax, [stack_ip] |
jnz ipr_dump |
ipr_p0: |
mov al, [edx] |
and al, 0x0f |
cmp al, 0x05 |
jnz ipr_dump |
cmp [edx+8], byte 0 |
jz ipr_dump |
mov ax, [edx + 6] |
and ax, 0xFFBF |
cmp ax, 0 |
jnz ipr_dump |
; Check the protocol, and call the appropriate handler |
; Each handler will re-use or free the queue buffer as appropriate |
mov al, [edx + 9] |
cmp al , PROTOCOL_ICMP |
jnz ipr_p1 |
pop eax |
call icmp_rx |
jmp ipr_exit |
ipr_p1: |
cmp al , PROTOCOL_TCP |
jnz ipr_p2 |
pop eax |
call tcp_rx |
jmp ipr_exit |
ipr_p2: |
cmp al , PROTOCOL_UDP |
jnz ipr_dump |
pop eax |
call udp_rx |
jmp ipr_exit |
ipr_dump: |
; No protocol handler available, so |
; silently dump the packet, freeing up the queue buffer |
; inc dword [dumped_rx_count] |
pop eax |
call freeBuff |
ipr_exit: |
ret |
;*************************************************************************** |
; Function |
; icmp_rx |
; |
; Description |
; ICMP protocol handler |
; This is a kernel function, called by ip_rx |
; edx contains the address of the buffer in use. |
; This buffer must be reused or marked as empty afterwards |
; |
;*************************************************************************** |
icmp_rx: |
cmp [edx + 20], byte 8 ; Is this an echo request? discard if not |
jz icmp_echo |
call freeBuff |
jmp icmp_exit |
icmp_echo: |
push eax |
mov [edx + 10], word 0 ; I think this was already done by IP rx |
; swap the source and destination addresses |
mov ecx, [edx + 16] |
mov eax, [edx + 12] |
mov [edx + 16], eax |
mov [edx + 12], ecx |
; recaluculate the IP header checksum |
mov ebx, edx |
mov [checkAdd1], ebx |
mov [checkSize1], word 20 |
mov [checkAdd2], dword 0 |
mov [checkSize2], word 0 |
call checksum |
mov ax, [checkResult] |
mov [edx + 10], ah |
mov [edx + 11], al ; ?? correct byte order? |
mov [edx + 20], byte 0 ; change the request to a response |
mov [edx + 22], word 0 ; clear ICMP checksum prior to re-calc |
; Calculate the length of the ICMP data ( IP payload) |
mov ah, [edx + 2] |
mov al, [edx + 3] |
sub ax, 20 |
mov [checkSize1], ax |
mov ebx, edx |
add ebx, 20 |
mov [checkAdd1], ebx |
mov [checkAdd2], dword 0 |
mov [checkSize2], word 0 |
call checksum |
mov ax, [checkResult] |
mov [edx + 22], ah |
mov [edx + 23], al |
; Queue packet for transmission |
pop ebx |
mov eax, NET1OUT_QUEUE |
call queue |
icmp_exit: |
ret |
/kernel/branches/gfx_kernel/network/queue.inc |
---|
0,0 → 1,214 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; QUEUE.INC ;; |
;; ;; |
;; Buffer queue management for Menuet OS TCP/IP Stack ;; |
;; ;; |
;; Version 0.3 29 August 2002 ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************* |
; Interface |
; |
; queueInit Configures the queues to empty |
; dequeue Removes a buffer pointer from a queue |
; queue Inserts a buffer pointer into a queue |
; freeBuff Adds the buffer pointer to the list of free buffers |
; queueSize Returns the number of entries in a queue |
; |
; The various defines for queue names can be found in stack.inc |
; |
;******************************************************************* |
;*************************************************************************** |
; Function |
; freeBuff |
; |
; Description |
; Adds a buffer number to the beginning of the free list. |
; buffer number in eax ( ms word zeroed ) |
; all other registers preserved |
; This always works, so no error returned |
;*************************************************************************** |
freeBuff: |
push ebx |
push ecx |
mov ebx, EMPTY_QUEUE |
shl ebx, 1 |
add ebx, queues |
cli ; Ensure that another process does not interfer |
movzx ecx, word [ebx] |
mov [ebx], ax |
shl eax, 1 |
add eax, queueList |
mov [eax], cx |
sti |
pop ecx |
pop ebx |
ret |
;*************************************************************************** |
; Function |
; queueSize |
; |
; Description |
; Counts the number of entries in a queue |
; queue number in ebx ( ms word zeroed ) |
; Queue size returned in eax |
; This always works, so no error returned |
;*************************************************************************** |
queueSize: |
xor eax, eax |
shl ebx, 1 |
add ebx, queues |
movzx ecx, word [ebx] |
cmp cx, NO_BUFFER |
je qs_exit |
qs_001: |
inc eax |
shl ecx, 1 |
add ecx, queueList |
movzx ecx, word [ecx] |
cmp cx, NO_BUFFER |
je qs_exit |
jmp qs_001 |
qs_exit: |
ret |
;*************************************************************************** |
; Function |
; queue |
; |
; Description |
; Adds a buffer number to the *end* of a queue |
; This is quite quick because these queues will be short |
; queue number in eax ( ms word zeroed ) |
; buffer number in ebx ( ms word zeroed ) |
; all other registers preserved |
; This always works, so no error returned |
;*************************************************************************** |
queue: |
push ebx |
shl ebx, 1 |
add ebx, queueList ; eax now holds address of queue entry |
mov [ebx], word NO_BUFFER ; This buffer will be the last |
cli |
shl eax, 1 |
add eax, queues ; eax now holds address of queue |
movzx ebx, word [eax] |
cmp bx, NO_BUFFER |
jne qu_001 |
pop ebx |
; The list is empty, so add this to the head |
mov [eax], bx |
jmp qu_exit |
qu_001: |
; Find the last entry |
shl ebx, 1 |
add ebx, queueList |
mov eax, ebx |
movzx ebx, word [ebx] |
cmp bx, NO_BUFFER |
jne qu_001 |
mov ebx, eax |
pop eax |
mov [ebx], ax |
qu_exit: |
sti |
ret |
;*************************************************************************** |
; Function |
; dequeue |
; |
; Description |
; removes a buffer number from the head of a queue |
; This is fast, as it unlinks the first entry in the list |
; queue number in eax ( ms word zeroed ) |
; buffer number returned in eax ( ms word zeroed ) |
; all other registers preserved |
; |
;*************************************************************************** |
dequeue: |
push ebx |
shl eax, 1 |
add eax, queues ; eax now holds address of queue |
mov ebx, eax |
cli |
movzx eax, word [eax] |
cmp ax, NO_BUFFER |
je dq_exit |
push eax |
shl eax, 1 |
add eax, queueList ; eax now holds address of queue entry |
mov ax, [eax] |
mov [ebx], ax |
pop eax |
dq_exit: |
sti |
pop ebx |
ret |
;*************************************************************************** |
; Function |
; queueInit |
; |
; Description |
; Initialises the queues to empty, and creates the free queue |
; list. |
; |
;*************************************************************************** |
queueInit: |
mov esi, queues |
mov ecx, NUMQUEUES |
mov ax, NO_BUFFER |
qi001: |
mov [esi], ax |
inc esi |
inc esi |
loop qi001 |
mov esi, queues + ( 2 * EMPTY_QUEUE ) |
; Initialise empty queue list |
xor ax, ax |
mov [esi], ax |
mov ecx, NUMQUEUEENTRIES - 1 |
mov esi, queueList |
qi002: |
inc ax |
mov [esi], ax |
inc esi |
inc esi |
loop qi002 |
mov ax, NO_BUFFER |
mov [esi], ax |
ret |
/kernel/branches/gfx_kernel/network/stack.inc |
---|
0,0 → 1,1784 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; STACK.INC ;; |
;; ;; |
;; TCP/IP stack for Menuet OS ;; |
;; ;; |
;; Version 0.7 4th July 2004 ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; Version 0.7 ;; |
;; Added a timer per socket to allow delays when rx window ;; |
;; gets below 1KB ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************* |
; Interface |
; The interfaces defined in ETHERNET.INC plus: |
; stack_init |
; stack_handler |
; app_stack_handler |
; app_socket_handler |
; checksum |
; |
;******************************************************************* |
; |
; IP Packet after reception - Normal IP packet format |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;0 |Version| IHL |Type of Service| Total Length | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;4 | Identification |Flags| Fragment Offset | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;8 | Time to Live | Protocol | Header Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;12 | Source Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;16 | Destination Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Data | |
; +-+-+-.......... -+ |
; TCP Payload ( Data field in IP datagram ) |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;20 | Source Port | Destination Port | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;24 | Sequence Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;28 | Acknowledgment Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;32 | Data | |U|A|P|R|S|F| | |
; | Offset| Reserved |R|C|S|S|Y|I| Window | |
; | | |G|K|H|T|N|N| | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;36 | Checksum | Urgent Pointer | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;40 | Options | Padding | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | data |
; |
; UDP Payload ( Data field in IP datagram ) |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Source Port | Destination Port | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Length ( UDP Header + Data ) | Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | UDP Data | |
; +-+-+-.......... -+ |
; |
; |
; Socket Descriptor + Buffer |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Status ( of this buffer ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Application Process ID | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Local IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Local IP Port | Unused ( set to 0 ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Remote IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Remote IP Port | Unused ( set to 0 ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 24| Rx Data Count INTEL format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 28| TCB STATE INTEL format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 32| TCB Timer (seconds) INTEL format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 36| ISS (Inital Sequence # used by this connection ) INET format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 40| IRS ( Inital Receive Sequence # ) INET format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 44| SND.UNA Seq # of unack'ed sent packets INET format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 48| SND.NXT Next send seq # to use INET format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 52| SND.WND Send window INET format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 56| RCV.NXT Next expected receive sequence # INET format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 60| RCV.WND Receive window INET format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 64| SEG.LEN Segment length INTEL format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 68| SEG.WND Segment window INTEL format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 76| RX Data | |
; +-+-+-.......... -+ |
; IP protocol numbers |
PROTOCOL_ICMP equ 1 |
PROTOCOL_TCP equ 6 |
PROTOCOL_UDP equ 17 |
; TIPBUFF status values |
BUFF_EMPTY equ 0 |
BUFF_RX_FULL equ 1 |
BUFF_ALLOCATED equ 2 |
BUFF_TX_FULL equ 3 |
NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX |
SOCK_EMPTY equ 0 ; socket not in use |
SOCK_OPEN equ 1 ; open issued, but no data sent |
; TCP opening modes |
SOCKET_PASSIVE equ 0 |
SOCKET_ACTIVE equ 1 |
; TCP TCB states |
TCB_LISTEN equ 1 |
TCB_SYN_SENT equ 2 |
TCB_SYN_RECEIVED equ 3 |
TCB_ESTABLISHED equ 4 |
TCB_FIN_WAIT_1 equ 5 |
TCB_FIN_WAIT_2 equ 6 |
TCB_CLOSE_WAIT equ 7 |
TCB_CLOSING equ 8 |
TCB_LAST_ACK equ 9 |
TCB_TIME_WAIT equ 10 |
TCB_CLOSED equ 11 |
TWOMSL equ 10 ; # of secs to wait before closing socket |
; socket buffers |
SOCKETBUFFSIZE equ 4096 ; state + config + buffer. |
SOCKETHEADERSIZE equ 76 ; thus 4096 - SOCKETHEADERSIZE bytes data |
NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20 |
NUMQUEUES equ 4 |
EMPTY_QUEUE equ 0 |
IPIN_QUEUE equ 1 |
IPOUT_QUEUE equ 2 |
NET1OUT_QUEUE equ 3 |
NO_BUFFER equ 0xFFFF |
IPBUFFSIZE equ 1500 ; MTU of an ethernet packet |
NUMQUEUEENTRIES equ NUM_IPBUFFERS |
NUMRESENDENTRIES equ 18 ; Buffers for TCP resend packets |
TCP_RETRIES equ 5 ; Number of times to resend a packet |
TCP_TIMEOUT equ 10 ; resend if not replied to in x hs |
; These are the 0x40 function codes for application access to the stack |
STACK_DRIVER_STATUS equ 52 |
SOCKET_INTERFACE equ 53 |
; 128KB allocated for the stack and network driver buffers and other |
; data requirements |
stack_data_start equ 0x700000 |
eth_data_start equ 0x700000 |
stack_data equ 0x704000 |
stack_data_end equ 0x71ffff |
; 32 bit word |
stack_config equ stack_data |
; 32 bit word - IP Address in network format |
stack_ip equ stack_data + 4 |
; 1 byte. 0 == inactive, 1 = active |
slip_active equ stack_data + 8 ; no longer used |
; 1 byte. 0 == inactive, 1 = active |
ethernet_active equ stack_data + 9 |
unused equ stack_data + 10 |
; word. Buffer number, -1 if none |
rx_buff_ptr equ stack_data + 12 |
; dword. Buffer number, -1 if none |
tx_buff_ptr equ stack_data + 16 |
; byte. |
slip_rx_state equ stack_data + 20 ; no longer used |
; byte |
slip_tx_state equ stack_data + 21 ; no longer used |
; dword. Index into data |
rx_data_ptr equ stack_data + 22 |
; dword. Index into data |
tx_data_ptr equ stack_data + 26 |
; word. Count of bytes to send |
tx_msg_len equ stack_data + 30 |
; Address of selected socket |
sktAddr equ stack_data + 32 |
; Parameter to checksum routine - data ptr |
checkAdd1 equ stack_data + 36 |
; Parameter to checksum routine - 2nd data ptr |
checkAdd2 equ stack_data + 40 |
; Parameter to checksum routine - data size |
checkSize1 equ stack_data + 44 |
; Parameter to checksum routine - 2nd data size |
checkSize2 equ stack_data + 46 |
; result of checksum routine |
checkResult equ stack_data + 48 |
; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len| |
pseudoHeader equ stack_data + 50 |
; receive and transmit IP buffer allocation |
sockets equ stack_data + 62 |
Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS) |
; 1560 byte buffer for rx / tx ethernet packets |
Ether_buffer equ Next_free2 |
Next_free3 equ Ether_buffer + 1560 |
last_1sTick equ Next_free3 |
IPbuffs equ Next_free3 + 1 |
queues equ IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE ) |
queueList equ queues + (2 * NUMQUEUES) |
last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES ) |
;resendQ equ queueList + ( 2 * NUMQUEUEENTRIES ) |
;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP |
; equ resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES ) |
resendQ equ 0x770000 |
resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP |
;*************************************************************************** |
; Function |
; stack_init |
; |
; Description |
; Clear all allocated memory to zero. This ensures that |
; on startup, the stack is inactive, and consumes no resources |
; This is a kernel function, called prior to the OS main loop |
; in set_variables |
; |
;*************************************************************************** |
stack_init: |
xor eax,eax |
mov edi,stack_data_start |
mov ecx,0x20000 / 4 ; Assume that we have 128KB of data |
cld |
rep stosd |
; Initialise TCP resend queue data structures |
mov eax, 0xFFFFFFFF |
mov edi, resendQ |
mov ecx, NUMRESENDENTRIES ; 1 dword per entry |
cld |
rep stosd |
mov eax, 0xFFFFFFFF |
mov [rx_buff_ptr], eax |
mov [tx_buff_ptr], eax |
; Put in some defaults : slip, 0x3f8, 4, ip=192.168.1.22 |
; Saves me entering them each boot up when debugging |
mov eax, 0x03f80401 |
mov [stack_config], eax |
mov eax, 0xc801a8c0 |
mov [stack_ip], eax |
call queueInit |
; The following block sets up the 1s timer |
mov al,0x0 |
out 0x70,al |
in al,0x71 |
mov [last_1sTick], al |
ret |
;*************************************************************************** |
; Function |
; stack_handler |
; |
; Description |
; The kernel loop routine for the stack |
; This is a kernel function, called in the main loop |
; |
;*************************************************************************** |
stack_handler: |
call ethernet_driver |
call ip_rx |
; Test for 10ms tick, call tcp timer |
mov eax, [timer_ticks] ;[0xfdf0] |
cmp eax, [last_1hsTick] |
je sh_001 |
mov [last_1hsTick], eax |
call tcp_tx_handler |
sh_001: |
; Test for 1 second event, call 1s timer functions |
mov al,0x0 ;second |
out 0x70,al |
in al,0x71 |
cmp al, [last_1sTick] |
je sh_exit |
mov [last_1sTick], al |
call arp_timer |
call tcp_tcb_handler |
sh_exit: |
ret |
;*************************************************************************** |
; Function |
; is_localport_unused |
; |
; Description |
; scans through all the active sockets , looking to see if the |
; port number specified in bx is in use as a localport number. |
; This is useful when you want a to generate a unique local port |
; number. |
; On return, eax = 1 for free, 0 for in use |
; |
;*************************************************************************** |
is_localport_unused: |
mov al, bh |
mov ah, bl |
mov bx, ax |
mov edx, SOCKETBUFFSIZE * NUM_SOCKETS |
mov ecx, NUM_SOCKETS |
mov eax, 0 ; Assume the return value is 'in use' |
ilu1: |
sub edx, SOCKETBUFFSIZE |
cmp [edx + sockets + 12], bx |
loopnz ilu1 ; Return back if the socket is occupied |
jz ilu_exit |
inc eax ; return port not in use |
ilu_exit: |
ret |
;*************************************************************************** |
; Function |
; get_free_socket |
; |
; Description |
; |
;*************************************************************************** |
get_free_socket: |
push ecx |
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
mov ecx, NUM_SOCKETS |
gfs1: |
sub eax, SOCKETBUFFSIZE |
cmp [eax + sockets], dword SOCK_EMPTY |
loopnz gfs1 ; Return back if the socket is occupied |
mov eax, ecx |
pop ecx |
jz gfs_exit |
mov eax, 0xFFFFFFFF |
gfs_exit: |
ret |
;*************************************************************************** |
; Function |
; checksum |
; |
; Description |
; checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult |
; Dont break anything; Most registers are used by the caller |
; This code is derived from the 'C' source, cksum.c, in the book |
; Internetworking with TCP/IP Volume II by D.E. Comer |
; |
;*************************************************************************** |
checksum: |
pusha |
xor edx, edx ; edx is the accumulative checksum |
xor ebx, ebx |
mov cx, [checkSize1] |
shr cx, 1 |
jz cs1_1 |
mov eax, [checkAdd1] |
cs1: |
mov bh, [eax] |
mov bl, [eax + 1] |
add eax, 2 |
add edx, ebx |
loopw cs1 |
cs1_1: |
and word [checkSize1], 0x01 |
jz cs_test2 |
mov bh, [eax] |
xor bl, bl |
add edx, ebx |
cs_test2: |
mov cx, [checkSize2] |
cmp cx, 0 |
jz cs_exit ; Finished if no 2nd buffer |
shr cx, 1 |
jz cs2_1 |
mov eax, [checkAdd2] |
cs2: |
mov bh, [eax] |
mov bl, [eax + 1] |
add eax, 2 |
add edx, ebx |
loopw cs2 |
cs2_1: |
and word [checkSize2], 0x01 |
jz cs_exit |
mov bh, [eax] |
xor bl, bl |
add edx, ebx |
cs_exit: |
mov ebx, edx |
shr ebx, 16 |
and edx, 0xffff |
add edx, ebx |
mov eax, edx |
shr eax, 16 |
add edx, eax |
not dx |
mov [checkResult], dx |
popa |
ret |
;*************************************************************************** |
; Function |
; app_stack_handler |
; |
; Description |
; This is an application service, called by int 0x40 fn 52 |
; It provides application access to the network interface layer |
; |
;*************************************************************************** |
app_stack_handler: |
cmp eax, 0 |
jnz not0 |
; Read the configuartion word |
mov eax, [stack_config] |
ret |
not0: |
cmp eax, 1 |
jnz not1 |
; read the IP address |
mov eax, [stack_ip] |
ret |
not1: |
cmp eax, 2 |
jnz not2 |
; write the configuration word |
mov [stack_config], ebx |
; <Slip shouldn't be active anyway - thats an operational issue.> |
; If ethernet now enabled, probe for the card, reset it and empty |
; the packet buffer |
; If all successfull, enable the card. |
; If ethernet now disabled, set it as disabled. Should really |
; empty the tcpip data area too. |
; ethernet interface is '3' in ls 7 bits |
and bl, 0x7f |
cmp bl, 3 |
je ash_eth_enable |
; Ethernet isn't enabled, so make sure that the card is disabled |
mov [ethernet_active], byte 0 |
ret |
ash_eth_enable: |
; Probe for the card. This will reset it and enable the interface |
; if found |
call eth_probe |
cmp eax, 0 |
je ash_eth_done ; Abort if no hardware found |
mov [ethernet_active], byte 1 |
ash_eth_done: |
ret |
not2: |
cmp eax, 3 |
jnz not3 |
; write the IP Address |
mov [stack_ip], ebx |
ret |
not3: |
cmp eax, 4 |
jnz not4 |
; Enabled the slip driver on the comm port |
; slip removed |
ret |
not4: |
cmp eax, 5 |
jnz not5 |
; Disable the slip driver on the comm port |
; slip removed |
not5: |
cmp eax, 6 |
jnz not6 |
; Insert an IP packet into the stacks received packet queue |
call stack_insert_packet |
ret |
not6: |
cmp eax, 7 |
jnz not7 |
; Test for any packets queued for transmission over the network |
not7: |
cmp eax, 8 |
jnz not8 |
call stack_get_packet |
; Extract a packet queued for transmission by the network |
ret |
not8: |
cmp eax, 9 |
jnz not9 |
; read the gateway IP address |
mov eax, [gateway_ip] |
ret |
not9: |
cmp eax, 10 |
jnz not10 |
; read the subnet mask |
mov eax, [subnet_mask] |
ret |
not10: |
cmp eax, 11 |
jnz not11 |
; write the gateway IP Address |
mov [gateway_ip], ebx |
ret |
not11: |
cmp eax, 12 |
jnz not12 |
; write the subnet mask |
mov [subnet_mask], ebx |
not12: |
cmp eax, 13 |
jnz not13 |
; read the dns |
mov eax, [dns_ip] |
ret |
not13: |
cmp eax, 14 |
jnz stack_driver_end |
; write the dns IP Address |
mov [dns_ip], ebx |
ret |
stack_driver_end: |
ret |
;*************************************************************************** |
; Function |
; app_socket_handler |
; |
; Description |
; This is an application service, called by int 0x40 |
; It provides application access to stack socket services |
; such as opening sockets |
; |
;*************************************************************************** |
app_socket_handler: |
cmp eax, 0 |
jnz nots0 |
call socket_open |
ret |
nots0: |
cmp eax, 1 |
jnz nots1 |
call socket_close |
ret |
nots1: |
cmp eax, 2 |
jnz nots2 |
call socket_poll |
ret |
nots2: |
cmp eax, 3 |
jnz nots3 |
call socket_read |
ret |
nots3: |
cmp eax, 4 |
jnz nots4 |
call socket_write |
ret |
nots4: |
cmp eax, 5 |
jnz nots5 |
call socket_open_tcp |
ret |
nots5: |
cmp eax, 6 |
jnz nots6 |
call socket_status |
ret |
nots6: |
cmp eax, 7 |
jnz nots7 |
call socket_write_tcp |
ret |
nots7: |
cmp eax, 8 |
jnz nots8 |
call socket_close_tcp |
ret |
nots8: |
cmp eax, 9 |
jnz nots9 |
call is_localport_unused |
ret |
nots9: |
cmp eax, 254 |
jnz notdump |
ret |
notdump: |
cmp eax, 255 |
jnz notsdebug |
; This sub function allows access to debugging information on the stack |
; ebx holds the request: |
; 100 : return length of empty queue |
; 101 : return length of IPOUT QUEUE |
; 102 : return length of IPIN QUEUE |
; 103 : return length of NET1OUT QUEUE |
; 200 : return # of ARP entries |
; 201 : return size of ARP table ( max # entries ) |
; 202 : select ARP table entry # |
; 203 : return IP of selected table entry |
; 204 : return High 4 bytes of MAC address of selected table entry |
; 205 : return low 2 bytes of MAC address of selected table entry |
; 206 : return status word of selected table entry |
; 207 : return Time to live of selected table entry |
; 2 : return number of IP packets received |
; 3 : return number of packets transmitted |
; 4 : return number of received packets dumped |
; 5 : return number of arp packets received |
; 6 : return status of packet driver |
; ( 0 == not active, FFFFFFFF = successful ) |
call stack_internal_status |
ret |
notsdebug: |
; Invalid Option |
ret |
uglobal |
ARPTmp: |
times 14 db 0 |
endg |
;*************************************************************************** |
; Function |
; stack_internal_status |
; |
; Description |
; Returns information about the internal status of the stack |
; This is only useful for debugging |
; It works with the ethernet driver |
; sub function in ebx |
; return requested data in eax |
; |
;*************************************************************************** |
stack_internal_status: |
cmp ebx, 100 |
jnz notsis100 |
; 100 : return length of EMPTY QUEUE |
mov ebx, EMPTY_QUEUE |
call queueSize |
ret |
notsis100: |
cmp ebx, 101 |
jnz notsis101 |
; 101 : return length of IPOUT QUEUE |
mov ebx, IPOUT_QUEUE |
call queueSize |
ret |
notsis101: |
cmp ebx, 102 |
jnz notsis102 |
; 102 : return length of IPIN QUEUE |
mov ebx, IPIN_QUEUE |
call queueSize |
ret |
notsis102: |
cmp ebx, 103 |
jnz notsis103 |
; 103 : return length of NET1OUT QUEUE |
mov ebx, NET1OUT_QUEUE |
call queueSize |
ret |
notsis103: |
cmp ebx, 200 |
jnz notsis200 |
; 200 : return num entries in arp table |
movzx eax, byte [NumARP] |
ret |
notsis200: |
cmp ebx, 201 |
jnz notsis201 |
; 201 : return arp table size |
mov eax, 20 ; ARP_TABLE_SIZE |
ret |
notsis201: |
cmp ebx, 202 |
jnz notsis202 |
; 202 - read the requested table entry |
; into a temporary buffer |
; ecx holds the entry number |
mov eax, ecx |
mov ecx, 14 ; ARP_ENTRY_SIZE |
mul ecx |
mov ecx, [eax + ARPTable] |
mov [ARPTmp], ecx |
mov ecx, [eax + ARPTable+4] |
mov [ARPTmp+4], ecx |
mov ecx, [eax + ARPTable+8] |
mov [ARPTmp+8], ecx |
mov cx, [eax + ARPTable+12] |
mov [ARPTmp+12], cx |
ret |
notsis202: |
cmp ebx, 203 |
jnz notsis203 |
; 203 - return IP address |
mov eax, [ARPTmp] |
ret |
notsis203: |
cmp ebx, 204 |
jnz notsis204 |
; 204 - return MAC high dword |
mov eax, [ARPTmp+4] |
ret |
notsis204: |
cmp ebx, 205 |
jnz notsis205 |
; 205 - return MAC ls word |
movzx eax, word [ARPTmp+8] |
ret |
notsis205: |
cmp ebx, 206 |
jnz notsis206 |
; 206 - return status word |
movzx eax, word [ARPTmp+10] |
ret |
notsis206: |
cmp ebx, 207 |
jnz notsis207 |
; 207 - return ttl word |
movzx eax, word [ARPTmp+12] |
ret |
notsis207: |
cmp ebx, 2 |
jnz notsis2 |
; 2 : return number of IP packets received |
mov eax, [ip_rx_count] |
ret |
notsis2: |
cmp ebx, 3 |
jnz notsis3 |
; 3 : return number of packets transmitted |
mov eax, [ip_tx_count] |
ret |
notsis3: |
cmp ebx, 4 |
jnz notsis4 |
; 4 : return number of received packets dumped |
mov eax, [dumped_rx_count] |
ret |
notsis4: |
cmp ebx, 5 |
jnz notsis5 |
; 5 : return number of arp packets received |
mov eax, [arp_rx_count] |
ret |
notsis5: |
cmp ebx, 6 |
jnz notsis6 |
; 6 : return status of packet driver |
; ( 0 == not active, FFFFFFFF = successful ) |
mov eax, [eth_status] |
ret |
notsis6: |
xor eax, eax |
ret |
;*************************************************************************** |
; Function |
; stack_get_packet |
; |
; Description |
; extracts an IP packet from the NET1 output queue |
; and sends the data to the calling process |
; pointer to data in edx |
; returns number of bytes read in eax |
; |
;*************************************************************************** |
stack_get_packet: |
; Look for a buffer to tx |
mov eax, NET1OUT_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je sgp_non_exit ; Exit if no buffer available |
push eax ; Save buffer number for freeing at end |
push edx |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
pop edx |
push eax ; save address of IP data |
; Get the address of the callers data |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add edx,[edi] |
mov edi, edx |
pop eax |
mov ecx, 1500 ; should get the actual number of bytes to write |
mov esi, eax |
cld |
rep movsb ; copy the data across |
; And finally, return the buffer to the free queue |
pop eax |
call freeBuff |
mov eax, 1500 |
ret |
sgp_non_exit: |
xor eax, eax |
ret |
;*************************************************************************** |
; Function |
; stack_insert_packet |
; |
; Description |
; writes an IP packet into the stacks receive queue |
; # of bytes to write in ecx |
; pointer to data in edx |
; returns 0 in eax ok, -1 == failed |
; |
;*************************************************************************** |
stack_insert_packet: |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je sip_err_exit |
push eax |
; save the pointers to the data buffer & size |
push edx |
push ecx |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax |
; So, edx holds the IPbuffer ptr |
pop ecx ; count of bytes to send |
mov ebx, ecx ; need the length later |
pop eax ; get callers ptr to data to send |
; Get the address of the callers data |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
mov esi, eax |
mov edi, edx |
cld |
rep movsb ; copy the data across |
pop ebx |
mov eax, IPIN_QUEUE |
call queue |
inc dword [ip_rx_count] |
mov eax, 0 |
ret |
sip_err_exit: |
mov eax, 0xFFFFFFFF |
ret |
;*************************************************************************** |
; Function |
; socket_open |
; |
; Description |
; find a free socket |
; local port in ebx |
; remote port in ecx |
; remote ip in edx |
; return socket # in eax, -1 if none available |
; |
;*************************************************************************** |
socket_open: |
call get_free_socket |
cmp eax, 0xFFFFFFFF |
jz so_exit |
; ax holds the socket number that is free. Get real address |
push eax |
shl eax, 12 |
add eax, sockets |
mov [eax], dword SOCK_OPEN |
mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
mov ebx, [stack_ip] |
mov [eax + 8], ebx ; Local IP |
mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
mov [eax + 16], edx ; Remote IP ( in Internet order ) |
mov [eax + 24], dword 0 ; recieved data count |
mov esi, [0x3010] |
mov ebx, [esi+TASKDATA.pid] |
mov [eax + 4], ebx ; save the process ID |
pop eax ; Get the socket number back, so we can return it |
so_exit: |
ret |
;*************************************************************************** |
; Function |
; socket_open_tcp |
; |
; Description |
; Opens a TCP socket in PASSIVE or ACTIVE mode |
; find a free socket |
; local port in ebx ( intel format ) |
; remote port in ecx ( intel format ) |
; remote ip in edx ( in Internet byte order ) |
; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE ) |
; return socket # in eax, -1 if none available |
; |
;*************************************************************************** |
socket_open_tcp: |
call get_free_socket |
cmp eax, 0xFFFFFFFF |
jz so_exit |
; ax holds the socket number that is free. Get real address |
push eax |
shl eax, 12 |
add eax, sockets |
mov [sktAddr], eax |
mov [eax], dword SOCK_OPEN |
; TODO - check this works! |
mov [eax + 72], dword 0 ; Reset the window timer. |
mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
mov ebx, [stack_ip] |
mov [eax + 8], ebx ; Local IP |
mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
mov [eax + 16], edx ; Remote IP ( in Internet order ) |
mov [eax + 24], dword 0 ; recieved data count |
; Now fill in TCB state |
mov ebx, TCB_LISTEN |
cmp esi, SOCKET_PASSIVE |
jz sot_001 |
mov ebx, TCB_SYN_SENT |
sot_001: |
mov [eax + 28], ebx ; Indicate the state of the TCB |
mov esi, [0x3010] |
mov ecx, [esi+TASKDATA.pid] |
mov [eax + 4], ecx ; save the process ID |
cmp ebx, TCB_LISTEN |
je sot_done |
; Now, if we are in active mode, then we have to send a SYN to the specified remote port |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je sot_done |
push eax |
mov bl, 0x02 ; SYN |
mov ecx, 0 |
call buildTCPPacket |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne sot_notlocal |
mov eax, IPIN_QUEUE |
sot_notlocal: |
; Send it. |
pop ebx |
call queue |
mov esi, [sktAddr] |
; increment SND.NXT in socket |
add esi, 48 |
call inc_inet_esi |
sot_done: |
pop eax ; Get the socket number back, so we can return it |
sot_exit: |
ret |
;*************************************************************************** |
; Function |
; socket_close |
; |
; Description |
; socket # in ebx |
; returns 0 for ok, -1 for socket not open (fail) |
; |
;*************************************************************************** |
socket_close: |
shl ebx, 12 |
add ebx, sockets |
mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
cmp [ebx], dword SOCK_EMPTY |
jz sc_exit |
; Clear the socket varaibles |
xor eax, eax |
mov edi,ebx |
mov ecx,SOCKETHEADERSIZE |
cld |
rep stosb |
sc_exit: |
ret |
;*************************************************************************** |
; Function |
; socket_close_tcp |
; |
; Description |
; socket # in ebx |
; returns 0 for ok, -1 for socket not open (fail) |
; |
;*************************************************************************** |
socket_close_tcp: |
; first, remove any resend entries |
pusha |
mov esi, resendQ |
mov ecx, 0 |
sct001: |
cmp ecx, NUMRESENDENTRIES |
je sct003 ; None left |
cmp [esi], bl |
je sct002 ; found one |
inc ecx |
add esi, 4 |
jmp sct001 |
sct002: |
dec dword [arp_rx_count] ; ************ TEST ONLY! |
mov [esi], byte 0xFF |
jmp sct001 |
sct003: |
popa |
shl ebx, 12 |
add ebx, sockets |
mov [sktAddr], ebx |
mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
cmp [ebx], dword SOCK_EMPTY |
jz sct_exit |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je stl_exit |
push eax |
mov bl, 0x11 ; FIN + ACK |
mov ecx, 0 |
mov esi, 0 |
call buildTCPPacket |
mov ebx, [sktAddr] |
; increament SND.NXT in socket |
mov esi, 48 |
add esi, ebx |
call inc_inet_esi |
; Get the socket state |
mov eax, [ebx + 28] |
cmp eax, TCB_LISTEN |
je destroyTCB |
cmp eax, TCB_SYN_SENT |
je destroyTCB |
cmp eax, TCB_SYN_RECEIVED |
je sct_finwait1 |
cmp eax, TCB_ESTABLISHED |
je sct_finwait1 |
; assume CLOSE WAIT |
; Send a fin, then enter last-ack state |
mov eax, TCB_LAST_ACK |
mov [ebx + 28], eax |
xor eax, eax |
jmp sct_send |
sct_finwait1: |
; Send a fin, then enter finwait2 state |
mov eax, TCB_FIN_WAIT_1 |
mov [ebx + 28], eax |
xor eax, eax |
sct_send: |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne sct_notlocal |
mov eax, IPIN_QUEUE |
sct_notlocal: |
; Send it. |
pop ebx |
call queue |
jmp sct_exit |
destroyTCB: |
pop eax |
; Clear the socket varaibles |
xor eax, eax |
mov edi,ebx |
mov ecx,SOCKETHEADERSIZE |
cld |
rep stosb |
sct_exit: |
ret |
;*************************************************************************** |
; Function |
; socket_poll |
; |
; Description |
; socket # in ebx |
; returns count in eax. |
; |
;*************************************************************************** |
socket_poll: |
shl ebx, 12 |
add ebx, sockets |
mov eax, [ebx + 24] |
ret |
;*************************************************************************** |
; Function |
; socket_status |
; |
; Description |
; socket # in ebx |
; returns TCB state in eax. |
; |
;*************************************************************************** |
socket_status: |
shl ebx, 12 |
add ebx, sockets |
mov eax, [ebx + 28] |
ret |
;*************************************************************************** |
; Function |
; socket_read |
; |
; Description |
; socket # in ebx |
; returns # of bytes remaining in eax, data in bl |
; |
;*************************************************************************** |
socket_read: |
shl ebx, 12 |
add ebx, sockets |
mov eax, [ebx + 24] ; get count of bytes |
mov ecx,1 |
test eax, eax |
jz sr2 |
dec eax |
mov esi, ebx ; esi is address of socket |
mov [ebx + 24], eax ; store new count |
movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte |
add esi, SOCKETHEADERSIZE |
mov edi, esi |
inc esi |
mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4 |
cld |
rep movsd |
xor ecx, ecx |
sr1: |
jmp sor_exit |
sr2: |
xor bl, bl |
sor_exit: |
ret |
;*************************************************************************** |
; Function |
; socket_write |
; |
; Description |
; socket in ebx |
; # of bytes to write in ecx |
; pointer to data in edx |
; returns 0 in eax ok, -1 == failed ( invalid socket, or |
; could not queue IP packet ) |
; |
;*************************************************************************** |
socket_write: |
; First, find the address of the socket descriptor |
shl ebx, 12 |
add ebx, sockets ; ebx = address of actual socket |
mov eax, 0xFFFFFFFF |
; If the socket is invalid, return with an error code |
cmp [ebx], dword SOCK_EMPTY |
je sw_exit |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je sw_exit |
; Save the queue entry number |
push eax |
; save the pointers to the data buffer & size |
push edx |
push ecx |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax |
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
; Fill in the IP header ( some data is in the socket descriptor) |
mov eax, [ebx + 8] |
mov [edx + 12], eax ; source IP |
mov eax, [ebx + 16] |
mov [edx + 16], eax ; Destination IP |
mov al, 0x45 |
mov [edx], al ; Version, IHL |
xor al, al |
mov [edx + 1], al ; Type of service |
pop eax ; Get the UDP data length |
push eax |
add eax, 20 + 8 ; add IP header and UDP header lengths |
mov [edx + 2], ah |
mov [edx + 3], al |
xor al, al |
mov [edx + 4], al |
mov [edx + 5], al |
mov al, 0x40 |
mov [edx + 6], al |
xor al, al |
mov [edx + 7], al |
mov al, 0x20 |
mov [edx + 8], al |
mov al, 17 |
mov [edx + 9], al |
; Checksum left unfilled |
xor ax, ax |
mov [edx + 10], ax |
; Fill in the UDP header ( some data is in the socket descriptor) |
mov ax, [ebx + 12] |
mov [edx + 20], ax |
mov ax, [ebx + 20] |
mov [edx + 20 + 2], ax |
pop eax |
push eax |
add eax, 8 |
mov [edx + 20 + 4], ah |
mov [edx + 20 + 5], al |
; Checksum left unfilled |
xor ax, ax |
mov [edx + 20 + 6], ax |
pop ecx ; count of bytes to send |
mov ebx, ecx ; need the length later |
pop eax ; get callers ptr to data to send |
; Get the address of the callers data |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
mov esi, eax |
mov edi, edx |
add edi, 28 |
cld |
rep movsb ; copy the data across |
; we have edx as IPbuffer ptr. |
; Fill in the UDP checksum |
; First, fill in pseudoheader |
mov eax, [edx + 12] |
mov [pseudoHeader], eax |
mov eax, [edx + 16] |
mov [pseudoHeader+4], eax |
mov ax, 0x1100 ; 0 + protocol |
mov [pseudoHeader+8], ax |
add ebx, 8 |
mov eax, ebx |
mov [pseudoHeader+10], ah |
mov [pseudoHeader+11], al |
mov eax, pseudoHeader |
mov [checkAdd1], eax |
mov [checkSize1], word 12 |
mov eax, edx |
add eax, 20 |
mov [checkAdd2], eax |
mov eax, ebx |
mov [checkSize2], ax ; was eax!! mjh 8/7/02 |
call checksum |
; store it in the UDP checksum ( in the correct order! ) |
mov ax, [checkResult] |
; If the UDP checksum computes to 0, we must make it 0xffff |
; (0 is reserved for 'not used') |
cmp ax, 0 |
jne sw_001 |
mov ax, 0xffff |
sw_001: |
mov [edx + 20 + 6], ah |
mov [edx + 20 + 7], al |
; Fill in the IP header checksum |
mov eax, edx |
mov [checkAdd1], eax |
mov [checkSize1], word 20 |
mov [checkAdd2], dword 0 |
mov [checkSize2], word 0 |
call checksum |
mov ax, [checkResult] |
mov [edx + 10], ah |
mov [edx + 11], al |
; Check destination IP address. |
; If it is the local host IP, route it back to IP_RX |
pop ebx |
mov eax, NET1OUT_QUEUE |
mov ecx, [ edx + 16] |
mov edx, [stack_ip] |
cmp edx, ecx |
jne sw_notlocal |
mov eax, IPIN_QUEUE |
sw_notlocal: |
; Send it. |
call queue |
xor eax, eax |
sw_exit: |
ret |
;*************************************************************************** |
; Function |
; socket_write_tcp |
; |
; Description |
; socket in ebx |
; # of bytes to write in ecx |
; pointer to data in edx |
; returns 0 in eax ok, -1 == failed ( invalid socket, or |
; could not queue IP packet ) |
; |
;*************************************************************************** |
socket_write_tcp: |
; First, find the address of the socket descriptor |
shl ebx, 12 |
add ebx, sockets ; ebx = address of actual socket |
mov [sktAddr], ebx |
mov eax, 0xFFFFFFFF |
; If the socket is invalid, return with an error code |
cmp [ebx], dword SOCK_EMPTY |
je swt_exit |
; If the sockets window timer is nonzero, do not queue packet |
; TODO - done |
cmp [ebx + 72], dword 0 |
jne swt_exit |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je swt_exit |
push eax |
mov bl, 0x10 ; ACK |
; Get the address of the callers data |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add edx,[edi] |
mov esi, edx |
pop eax |
push eax |
push ecx |
call buildTCPPacket |
pop ecx |
; Check destination IP address. |
; If it is the local host IP, route it back to IP_RX |
pop ebx |
push ecx |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne swt_notlocal |
mov eax, IPIN_QUEUE |
swt_notlocal: |
pop ecx |
push ebx ; save ipbuffer number |
call queue |
mov esi, [sktAddr] |
; increament SND.NXT in socket |
; Amount to increment by is in ecx |
add esi, 48 |
call add_inet_esi |
pop ebx |
; Copy the IP buffer to a resend queue |
; If there isn't one, dont worry about it for now |
mov esi, resendQ |
mov ecx, 0 |
swt003: |
cmp ecx, NUMRESENDENTRIES |
je swt001 ; None found |
cmp [esi], byte 0xFF |
je swt002 ; found one |
inc ecx |
add esi, 4 |
jmp swt003 |
swt002: |
push ebx |
; OK, we have a buffer descriptor ptr in esi. |
; resend entry # in ecx |
; Populate it |
; socket # |
; retries count |
; retry time |
; fill IP buffer associated with this descriptor |
mov eax, [sktAddr] |
sub eax, sockets |
shr eax, 12 ; get skt # |
mov [esi], al |
mov [esi + 1], byte TCP_RETRIES |
mov [esi + 2], word TCP_TIMEOUT |
inc ecx |
; Now get buffer location, and copy buffer across. argh! more copying,, |
mov edi, resendBuffer - IPBUFFSIZE |
swt002a: |
add edi, IPBUFFSIZE |
loop swt002a |
; we have dest buffer location in edi |
pop eax |
; convert source buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov esi, eax |
; do copy |
mov ecx, IPBUFFSIZE |
cld |
rep movsb |
inc dword [arp_rx_count] ; ************ TEST ONLY! |
swt001: |
xor eax, eax |
swt_exit: |
ret |
; Below, the main network layer source code is included |
; |
include "queue.inc" |
include "ip.inc" |
include "tcp.inc" |
include "udp.inc" |
include "eth_drv/ethernet.inc" |
/kernel/branches/gfx_kernel/network/tcp.inc |
---|
0,0 → 1,1243 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; TCP.INC ;; |
;; ;; |
;; TCP Processes for Menuet OS TCP/IP stack ;; |
;; ;; |
;; Version 0.6 4th July 2004 ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; v0.6 : Added reset handling in the established state ;; |
;; Added a timer per socket to allow delays when rx window ;; |
;; gets below 1KB ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************* |
; Interface |
; |
; tcp_tx_handler Handles the TCP transmit queue |
; tcp_rx The protocol handler for received data |
; buildTCPPacket fills in the packet headers and data |
; tcpStateMachine Main state machine for received TCP packets |
; tcp_tcb_handler 1s timer, to erase tcb's in TIME_WAIT state |
; |
;******************************************************************* |
;*************************************************************************** |
; Function |
; tcp_tcb_handler |
; |
; Description |
; Handles sockets in the timewait state, closing them |
; when the TCB timer expires |
; |
;*************************************************************************** |
tcp_tcb_handler: |
; scan through all the sockets, decrementing active timers |
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
mov ecx, NUM_SOCKETS |
tth1: |
sub eax, SOCKETBUFFSIZE |
cmp [eax + sockets + 32], dword 0 |
jne tth2 |
tth1a: |
cmp [eax + sockets + 72], dword 0 |
jne tth4 |
loop tth1 |
ret |
tth2: |
; decrement it, delete socket if TCB timer = 0 & socket in timewait state |
pusha |
dec dword [eax + sockets + 32] |
cmp [eax + sockets + 32], dword 0 |
jne tth3 |
cmp [eax + sockets + 28], dword TCB_TIME_WAIT |
jne tth3 |
; OK, delete socket |
mov edi, eax |
add edi, sockets |
xor eax, eax |
mov ecx, SOCKETHEADERSIZE |
cld |
rep stosb |
tth3: |
popa |
jmp tth1a |
loop tth1 |
ret |
; TODO - prove it works! |
tth4: |
dec dword [eax + sockets + 72] |
loop tth1 |
ret |
tth_exit: |
ret |
;*************************************************************************** |
; Function |
; tcp_tx_handler |
; |
; Description |
; Handles queued TCP data |
; This is a kernel function, called by stack_handler |
; |
;*************************************************************************** |
tcp_tx_handler: |
; decrement all resend buffers timers. If they |
; expire, queue them for sending, and restart the timer. |
; If the retries counter reach 0, delete the entry |
mov esi, resendQ |
mov ecx, 0 |
tth001: |
cmp ecx, NUMRESENDENTRIES |
je tth003 ; None left |
cmp [esi], byte 0xFF |
jne tth002 ; found one |
inc ecx |
add esi, 4 |
jmp tth001 |
tth002: |
; we have one. decrement it's timer by 1 |
dec word [esi+2] |
mov ax, [esi+2] |
cmp ax, 0 |
je tth002a |
inc ecx |
add esi, 4 |
jmp tth001 ; Timer not zero, so move on |
tth002a: |
mov bl, 0xff |
; restart timer, and decrement retries |
; After the first resend, back of on next, by a factor of 5 |
mov [esi+2], word TCP_TIMEOUT * 5 |
dec byte [esi+1] |
mov al, [esi+1] |
cmp al, 0 |
jne tth004 |
; retries now 0, so delete from queue |
xchg [esi], bl |
tth004: |
; resend packet |
pusha |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
jne tth004z |
; TODO - try again in 10ms. |
cmp bl, 0xff |
jne tth004za |
mov [esi], bl |
tth004za: |
; Mark it to expire in 10ms - 1 tick |
mov [esi+1], byte 1 |
mov [esi+2], word 1 |
jmp tth005 |
tth004z: |
; we have a buffer # in ax |
push eax |
push ecx |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
; we have the buffer address in eax |
mov edi, eax |
pop ecx |
; get resend data address |
inc ecx |
; Now get buffer location, and copy buffer across. argh! more copying,, |
mov esi, resendBuffer - IPBUFFSIZE |
tth004a: |
add esi, IPBUFFSIZE |
loop tth004a |
; we have resend buffer location in esi |
mov ecx, IPBUFFSIZE |
; copy data across |
cld |
rep movsb |
; queue packet |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ edi + 16 ] |
cmp edx, ecx |
jne tth004b |
mov eax, IPIN_QUEUE |
tth004b: |
pop ebx |
call queue |
tth005: |
popa |
inc ecx |
add esi, 4 |
jmp tth001 |
tth003: |
ret |
;*************************************************************************** |
; Function |
; tcp_rx |
; |
; Description |
; TCP protocol handler |
; This is a kernel function, called by ip_rx |
; IP buffer address given in edx |
; IP buffer number in eax |
; Free up (or re-use) IP buffer when finished |
; |
;*************************************************************************** |
tcp_rx: |
; The process is as follows. |
; Look for a socket with matching remote IP, remote port, local port |
; if not found, then |
; look for remote IP + local port match ( where sockets remote port = 0) |
; if not found, then |
; look for a socket where local socket port == IP packets remote port |
; where sockets remote port, remote IP = 0 |
; discard if not found |
; Call sockets tcbStateMachine, with pointer to packet. |
; the state machine will not delete the packet, so do that here. |
push eax |
; Look for a socket where |
; IP Packet TCP Destination Port = local Port |
; IP Packet SA = Remote IP |
; IP Packet TCP Source Port = remote Port |
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
mov ecx, NUM_SOCKETS |
ss1: |
sub eax, SOCKETBUFFSIZE |
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr |
cmp [eax + sockets + 12], bx ; compare with socket's local port |
jnz nxttst1 ; different - try next socket |
movzx ebx, word [edx + 20] ; get the source port from the TCP hdr |
cmp [eax + sockets + 20], bx ; compare with socket's remote port |
jnz nxttst1 ; different - try next socket |
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr |
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP |
jnz nxttst1 ; different - try next socket |
; We have a complete match - use this socket |
jmp tcprx_001 |
nxttst1: |
loop ss1 ; Return back if no match |
; If we got here, there was no match |
; Look for a socket where |
; IP Packet TCP Destination Port = local Port |
; IP Packet SA = Remote IP |
; socket remote Port = 0 |
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
mov ecx, NUM_SOCKETS |
ss2: |
sub eax, SOCKETBUFFSIZE |
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr |
cmp [eax + sockets + 12], bx ; compare with socket's local port |
jnz nxttst2 ; different - try next socket |
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr |
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP |
jnz nxttst2 ; different - try next socket |
mov ebx, 0 |
cmp [eax + sockets + 20], bx ; only match a remote socket of 0 |
jnz nxttst2 ; different - try next socket |
; We have a complete match - use this socket |
jmp tcprx_001 |
nxttst2: |
loop ss2 ; Return back if no match |
; If we got here, there was no match |
; Look for a socket where |
; IP Packet TCP Destination Port = local Port |
; socket Remote IP = 0 |
; socket remote Port = 0 |
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
mov ecx, NUM_SOCKETS |
ss3: |
sub eax, SOCKETBUFFSIZE |
movzx ebx, word [edx + 22] ; get destination port from the TCP hdr |
cmp [eax + sockets + 12], bx ; compare with socket's local port |
jnz nxttst3 ; different - try next socket |
mov ebx, 0 |
cmp [eax + sockets + 20], bx ; only match a remote socket of 0 |
jnz nxttst3 ; different - try next socket |
mov ebx, 0 |
cmp [eax + sockets + 16], ebx ; only match a socket remote IP of 0 |
jnz nxttst3 ; different - try next socket |
; We have a complete match - use this socket |
jmp tcprx_001 |
nxttst3: |
loop ss3 ; Return back if no match |
; If we got here, we need to reject the packet |
inc dword [dumped_rx_count] |
jmp tcprx_exit |
tcprx_001: |
; We have a valid socket/TCB, so call the TCB State Machine for that skt. |
; socket is pointed to by [eax + sockets] |
; IP packet is pointed to by [edx] |
; IP buffer number is on stack ( it will be popped at the end) |
call tcpStateMachine |
tcprx_exit: |
pop eax |
call freeBuff |
ret |
;*************************************************************************** |
; Function |
; buildTCPPacket |
; |
; Description |
; builds an IP Packet with TCP data fully populated for transmission |
; You may destroy any and all registers |
; TCP control flags specified in bl |
; This TCB is in [sktAddr] |
; User data pointed to by esi |
; Data length in ecx |
; Transmit buffer number in eax |
; |
;*************************************************************************** |
buildTCPPacket: |
push ecx ; Save data length |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax |
mov [edx + 33], bl ; TCP flags |
mov ebx, [sktAddr] |
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
; Fill in the IP header ( some data is in the socket descriptor) |
mov eax, [ebx + 8] |
mov [edx + 12], eax ; source IP |
mov eax, [ebx + 16] |
mov [edx + 16], eax ; Destination IP |
mov al, 0x45 |
mov [edx], al ; Version, IHL |
xor al, al |
mov [edx + 1], al ; Type of service |
pop eax ; Get the TCP data length |
push eax |
add eax, 20 + 20 ; add IP header and TCP header lengths |
mov [edx + 2], ah |
mov [edx + 3], al |
xor al, al |
mov [edx + 4], al |
mov [edx + 5], al |
mov al, 0x40 |
mov [edx + 6], al |
xor al, al |
mov [edx + 7], al |
mov al, 0x20 |
mov [edx + 8], al |
mov al, 6 ; TCP protocol |
mov [edx + 9], al |
; Checksum left unfilled |
xor ax, ax |
mov [edx + 10], ax |
; Fill in the TCP header ( some data is in the socket descriptor) |
mov ax, [ebx + 12] |
mov [edx + 20], ax ; Local Port |
mov ax, [ebx + 20] |
mov [edx + 20 + 2], ax ; desitination Port |
; Checksum left unfilled |
xor ax, ax |
mov [edx + 20 + 16], ax |
; sequence number |
mov eax, [ebx + 48] |
mov [edx + 20 + 4], eax |
; ack number |
mov eax, [ebx + 56] |
mov [edx + 20 + 8], eax |
; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size) |
; 768 bytes seems better |
mov ax, 0x0003 |
mov [edx + 20 + 14], ax |
; Urgent pointer (0) |
mov ax, 0 |
mov [edx + 20 + 18], ax |
; data offset ( 0x50 ) |
mov al, 0x50 |
mov [edx + 20 + 12], al |
pop ecx ; count of bytes to send |
mov ebx, ecx ; need the length later |
cmp ebx, 0 |
jz btp_001 |
mov edi, edx |
add edi, 40 |
cld |
rep movsb ; copy the data across |
btp_001: |
; we have edx as IPbuffer ptr. |
; Fill in the TCP checksum |
; First, fill in pseudoheader |
mov eax, [edx + 12] |
mov [pseudoHeader], eax |
mov eax, [edx + 16] |
mov [pseudoHeader+4], eax |
mov ax, 0x0600 ; 0 + protocol |
mov [pseudoHeader+8], ax |
add ebx, 20 |
mov eax, ebx |
mov [pseudoHeader+10], ah |
mov [pseudoHeader+11], al |
mov eax, pseudoHeader |
mov [checkAdd1], eax |
mov [checkSize1], word 12 |
mov eax, edx |
add eax, 20 |
mov [checkAdd2], eax |
mov eax, ebx |
mov [checkSize2], ax |
call checksum |
; store it in the TCP checksum ( in the correct order! ) |
mov ax, [checkResult] |
mov [edx + 20 + 16], ah |
mov [edx + 20 + 17], al |
; Fill in the IP header checksum |
mov eax, edx |
mov [checkAdd1], eax |
mov [checkSize1], word 20 |
mov [checkAdd2], dword 0 |
mov [checkSize2], word 0 |
call checksum |
mov ax, [checkResult] |
mov [edx + 10], ah |
mov [edx + 11], al |
ret |
; Increments the 32 bit value pointed to by esi in internet order |
inc_inet_esi: |
push eax |
add esi, 3 |
mov al, byte[esi] |
inc al |
mov byte[esi], al |
cmp al, 0 |
jnz iie_exit |
dec esi |
mov al, byte[esi] |
inc al |
mov byte[esi], al |
cmp al, 0 |
jnz iie_exit |
dec esi |
mov al, byte[esi] |
inc al |
mov byte[esi], al |
cmp al, 0 |
jnz iie_exit |
dec esi |
mov al, byte[esi] |
inc al |
mov byte[esi], al |
iie_exit: |
pop eax |
ret |
; Increments the 32 bit value pointed to by esi in internet order |
; by the value in ecx |
add_inet_esi: |
push eax |
mov al, [esi] |
shl eax, 8 |
inc esi |
mov al, [esi] |
shl eax, 8 |
inc esi |
mov al, [esi] |
shl eax, 8 |
inc esi |
mov al, [esi] |
add eax, ecx |
mov [esi], al |
dec esi |
shr eax, 8 |
mov [esi], al |
dec esi |
shr eax, 8 |
mov [esi], al |
dec esi |
shr eax, 8 |
mov [esi], al |
pop eax |
ret |
iglobal |
TCBStateHandler: |
dd stateTCB_LISTEN |
dd stateTCB_SYN_SENT |
dd stateTCB_SYN_RECEIVED |
dd stateTCB_ESTABLISHED |
dd stateTCB_FIN_WAIT_1 |
dd stateTCB_FIN_WAIT_2 |
dd stateTCB_CLOSE_WAIT |
dd stateTCB_CLOSING |
dd stateTCB_LAST_ACK |
dd stateTCB_TIME_WAIT |
dd stateTCB_CLOSED |
endg |
;*************************************************************************** |
; Function |
; tcpStateMachine |
; |
; Description |
; TCP state machine |
; This is a kernel function, called by tcp_rx |
; |
; IP buffer address given in edx |
; Socket/TCB address in [eax + sockets] |
; |
; The IP buffer will be released by the caller |
;*************************************************************************** |
tcpStateMachine: |
mov ebx, sockets |
add ebx, eax |
mov [sktAddr], ebx |
; as a packet has been received, update the TCB timer |
mov ecx, TWOMSL |
mov [ebx + 32], ecx |
; If the received packet has an ACK bit set, |
; remove any packets in the resend queue that this |
; received packet acknowledges |
pusha |
mov cl, [edx + 33] |
and cl, 0x10 |
cmp cl, 0x10 |
jne tsm001 ; No ACK, so no data yet |
; get skt number in al |
shr eax, 12 |
; The ack number is in [edx + 28], inet format |
; skt in al |
mov esi, resendQ |
mov ecx, 0 |
t001: |
cmp ecx, NUMRESENDENTRIES |
je t003 ; None left |
cmp [esi], al |
je t002 ; found one |
inc ecx |
add esi, 4 |
jmp t001 |
t002: ; Can we delete this buffer? |
; If yes, goto t004. No, goto t001 |
; Get packet data address |
push ecx |
inc ecx |
; Now get buffer location, and copy buffer across. argh! more copying,, |
mov edi, resendBuffer - IPBUFFSIZE |
t002a: |
add edi, IPBUFFSIZE |
loop t002a |
; we have dest buffer location in edi. incoming packet in edx. |
; Get this packets sequence number |
; preserve al, ecx, esi, edx |
mov cl, [edi + 24] |
shl ecx, 8 |
mov cl, [edi + 25] |
shl ecx, 8 |
mov cl, [edi + 26] |
shl ecx, 8 |
mov cl, [edi + 27] |
movzx ebx, byte [edi + 3] |
mov bh, [edi + 2] |
sub ebx, 40 |
add ecx, ebx ; ecx is now seq# of last byte +1, intel format |
; get recievd ack #, in intel format |
mov bl, [edx + 28] |
shl ebx, 8 |
mov bl, [edx + 29] |
shl ebx, 8 |
mov bl, [edx + 30] |
shl ebx, 8 |
mov bl, [edx + 31] |
cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que |
; DANGER! need to handle case that we have just |
; passed the 2**32, and wrapped round! |
pop ecx |
jae t004 ; if rx > old, delete old |
inc ecx |
add esi, 4 |
jmp t001 |
t004: |
dec dword [arp_rx_count] ; ************ TEST ONLY! |
mov [esi], byte 0xFF |
inc ecx |
add esi, 4 |
jmp t001 |
t003: |
tsm001: |
popa |
; Call handler for given TCB state |
mov ebx, [eax + sockets+28] |
cmp ebx, TCB_LISTEN |
jb tsm_exit |
cmp ebx, TCB_CLOSED |
ja tsm_exit |
dec ebx |
call dword [TCBStateHandler+ebx*4] |
tsm_exit: |
ret |
stateTCB_LISTEN: |
; In this case, we are expecting a SYN packet |
; For now, if the packet is a SYN, process it, and send a response |
; If not, ignore it |
; Look at control flags |
mov bl, [edx + 33] |
and bl, 0x02 |
cmp bl, 0x02 |
jnz stl_exit |
; We have a SYN. update the socket with this IP packets details, |
; And send a response |
mov ebx, [edx + 12] ; IP source address |
mov [eax + sockets + 16], ebx |
mov bx, [edx + 20] ; IP source port |
mov [eax + sockets + 20], bx |
mov ebx, [edx + 24] ; IRS |
mov [eax + sockets + 40], ebx |
mov [eax + sockets + 56], ebx |
mov esi, sockets |
add esi, eax |
add esi, 56 |
call inc_inet_esi ; RCV.NXT |
mov ebx, [eax + sockets + 36] ; ISS |
mov [eax + sockets + 48], ebx ; SND.NXT |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je stl_exit |
push eax |
mov bl, 0x12 ; SYN + ACK |
mov ecx, 0 |
mov esi, 0 |
call buildTCPPacket |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne stl_notlocal |
mov eax, IPIN_QUEUE |
stl_notlocal: |
; Send it. |
pop ebx |
call queue |
mov ebx, TCB_SYN_RECEIVED |
mov esi, [sktAddr] |
mov [esi + 28], ebx |
; increament SND.NXT in socket |
add esi, 48 |
call inc_inet_esi |
stl_exit: |
ret |
stateTCB_SYN_SENT: |
; We are awaiting an ACK to our SYN, with a SYM |
; Look at control flags - expecting an ACK |
mov bl, [edx + 33] |
and bl, 0x12 |
cmp bl, 0x12 |
jnz stss_exit |
mov ebx, TCB_ESTABLISHED |
mov esi, [sktAddr] |
mov [esi + 28], ebx |
; Store the recv.nxt field |
mov eax, [edx + 24] |
; Update our recv.nxt field |
mov esi, [sktAddr] |
add esi, 56 |
mov [esi], eax |
call inc_inet_esi |
; Send an ACK |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je stss_exit |
push eax |
mov bl, 0x10 ; ACK |
mov ecx, 0 |
mov esi, 0 |
call buildTCPPacket |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne stss_notlocal |
mov eax, IPIN_QUEUE |
stss_notlocal: |
; Send it. |
pop ebx |
call queue |
stss_exit: |
ret |
stateTCB_SYN_RECEIVED: |
; In this case, we are expecting an ACK packet |
; For now, if the packet is an ACK, process it, |
; If not, ignore it |
; Look at control flags - expecting an ACK |
mov bl, [edx + 33] |
and bl, 0x10 |
cmp bl, 0x10 |
jnz stsr_exit |
mov ebx, TCB_ESTABLISHED |
mov esi, [sktAddr] |
mov [esi + 28], ebx |
stsr_exit: |
ret |
stateTCB_ESTABLISHED: |
; Here we are expecting data, or a request to close |
; OR both... |
; Did we receive a FIN or RST? |
mov bl, [edx + 33] |
and bl, 0x05 |
cmp bl, 0 |
je ste_chkack |
; It was a fin or reset. |
; Remove resend entries from the queue - I dont want to send any more data |
pusha |
mov ebx, [sktAddr] |
sub ebx, sockets |
shr ebx, 12 ; get skt # |
mov esi, resendQ |
mov ecx, 0 |
ste001: |
cmp ecx, NUMRESENDENTRIES |
je ste003 ; None left |
cmp [esi], bl |
je ste002 ; found one |
inc ecx |
add esi, 4 |
jmp ste001 |
ste002: |
dec dword [arp_rx_count] ; ************ TEST ONLY! |
mov [esi], byte 0xFF |
jmp ste001 |
ste003: |
popa |
; was it a reset? |
mov bl, [edx + 33] |
and bl, 0x04 |
cmp bl, 0x04 |
jne ste003a |
mov esi, [sktAddr] |
mov ebx, TCB_CLOSED |
mov [esi + 28], ebx |
jmp ste_exit |
ste003a: |
; Send an ACK to that fin, and enter closewait state |
mov esi, [sktAddr] |
mov ebx, TCB_CLOSE_WAIT |
mov [esi + 28], ebx |
add esi, 56 |
mov eax, [esi] ; save original |
call inc_inet_esi |
;; jmp ste_ack - NO, there may be data |
ste_chkack: |
; Check that we received an ACK |
mov bl, [edx + 33] |
and bl, 0x10 |
cmp bl, 0x10 |
jnz ste_exit |
; TODO - done, I think! |
; First, look at the incoming window. If this is less than or equal to 1024, |
; Set the socket window timer to 1. This will stop an additional packets being |
; queued. |
; ** I may need to tweak this value, since I do not know how many packets are already queued |
mov ch, [edx + 34] |
mov cl, [edx + 35] |
cmp cx, 1024 |
ja ste004 |
mov ecx, [sktAddr] |
mov [ecx+72], dword 1 |
ste004: |
; OK, here is the deal |
; My recv.nct field holds the seq of the expected next rec byte |
; if the recevied sequence number is not equal to this, do not |
; increment the recv.nxt field, do not copy data - just send a |
; repeat ack. |
; recv.nxt is in dword [edx+24], in inext format |
; recv seq is in [sktAddr]+56, in inet format |
; just do a comparision |
mov ecx, [sktAddr] |
add ecx, 56 |
cmp [ecx - 56 + 28], dword TCB_CLOSE_WAIT |
mov ecx, [ecx] |
jne stenofin |
mov ecx, eax |
stenofin: |
cmp ecx, [edx+24] |
jne ste_ack |
; Read the data bytes, store in socket buffer |
xor ecx, ecx |
mov ch, [edx + 2] |
mov cl, [edx + 3] |
sub ecx, 40 ; Discard 40 bytes of header |
cmp ecx, 0 |
jnz ste_data ; Read data, if any |
; If we had received a fin, we need to ACK it. |
mov esi, [sktAddr] |
mov ebx, [esi + 28] |
cmp ebx, TCB_CLOSE_WAIT |
jz ste_ack |
jnz ste_exit |
ste_data: |
push ecx |
mov esi, [sktAddr] |
add [esi + 24], ecx ; increment the count of bytes in buffer |
mov eax, [esi + 4] ; get socket owner PID |
push eax |
mov eax, [esi + 24] ; get # of bytes already in buffer |
; point to the location to store the data |
add esi, eax |
sub esi, ecx |
add esi, SOCKETHEADERSIZE |
add edx, 40 ; edx now points to the data |
mov edi, esi |
mov esi, edx |
cld |
rep movsb ; copy the data across |
; flag an event to the application |
pop eax |
mov ecx,1 |
mov esi,0x3020+TASKDATA.pid |
news: |
cmp [esi],eax |
je foundPID1 |
inc ecx |
add esi,0x20 |
cmp ecx,[0x3004] |
jbe news |
foundPID1: |
shl ecx,8 |
or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event |
pop ecx |
; Update our recv.nxt field |
mov esi, [sktAddr] |
add esi, 56 |
call add_inet_esi |
ste_ack: |
; Send an ACK |
; Now construct the response, and queue for sending by IP |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je ste_exit |
push eax |
mov bl, 0x10 ; ACK |
mov ecx, 0 |
mov esi, 0 |
call buildTCPPacket |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne ste_notlocal |
mov eax, IPIN_QUEUE |
ste_notlocal: |
; Send it. |
pop ebx |
call queue |
ste_exit: |
ret |
stateTCB_FIN_WAIT_1: |
; We can either receive an ACK of a fin, or a fin |
mov bl, [edx + 33] |
and bl, 0x10 |
cmp bl, 0x10 |
jnz stfw1_001 |
; It was an ACK |
mov esi, [sktAddr] |
mov ebx, TCB_FIN_WAIT_2 |
mov [esi + 28], ebx |
jmp stfw1_exit |
stfw1_001: |
; It must be a fin then |
mov esi, [sktAddr] |
mov ebx, TCB_CLOSING |
mov [esi + 28], ebx |
add esi, 56 |
call inc_inet_esi |
; Send an ACK |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je stfw1_exit |
push eax |
mov bl, 0x10 ; ACK |
mov ecx, 0 |
mov esi, 0 |
call buildTCPPacket |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne stfw1_notlocal |
mov eax, IPIN_QUEUE |
stfw1_notlocal: |
; Send it. |
pop ebx |
call queue |
stfw1_exit: |
ret |
stateTCB_FIN_WAIT_2: |
mov esi, [sktAddr] |
; Get data length |
xor ecx, ecx |
mov ch, [edx+2] |
mov cl, [edx+3] |
sub ecx, 40 |
mov bl, [edx + 33] |
and bl, 0x01 |
cmp bl, 0x01 |
jne stfw2001 |
; Change state, as we have a fin |
mov ebx, TCB_TIME_WAIT |
mov [esi + 28], ebx |
inc ecx ; FIN is part of the sequence space |
stfw2001: |
add esi, 56 |
call add_inet_esi |
; Send an ACK |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je stfw2_exit |
push eax |
mov bl, 0x10 ; ACK |
mov ecx, 0 |
mov esi, 0 |
call buildTCPPacket |
mov eax, NET1OUT_QUEUE |
mov edx, [stack_ip] |
mov ecx, [ sktAddr ] |
mov ecx, [ ecx + 16 ] |
cmp edx, ecx |
jne stfw2_notlocal |
mov eax, IPIN_QUEUE |
stfw2_notlocal: |
; Send it. |
pop ebx |
call queue |
; Only delete the socket if we received the FIN |
mov bl, [edx + 33] |
and bl, 0x01 |
cmp bl, 0x01 |
jne stfw2_exit |
; mov edi, [sktAddr] |
; delete the socket. Should really wait for 2MSL |
; xor eax, eax |
; mov ecx,SOCKETHEADERSIZE |
; cld |
; rep stosb |
stfw2_exit: |
ret |
stateTCB_CLOSE_WAIT: |
; Intentionally left empty |
; socket_close_tcp handles this |
ret |
stateTCB_CLOSING: |
; We can either receive an ACK of a fin, or a fin |
mov bl, [edx + 33] |
and bl, 0x10 |
cmp bl, 0x10 |
jnz stc_exit |
; It was an ACK |
mov edi, [sktAddr] |
; delete the socket |
xor eax, eax |
mov ecx,SOCKETHEADERSIZE |
cld |
rep stosb |
stc_exit: |
ret |
stateTCB_LAST_ACK: |
; Look at control flags - expecting an ACK |
mov bl, [edx + 33] |
and bl, 0x10 |
cmp bl, 0x10 |
jnz stla_exit |
mov edi, [sktAddr] |
; delete the socket |
xor eax, eax |
mov ecx,SOCKETHEADERSIZE |
cld |
rep stosb |
stla_exit: |
ret |
stateTCB_TIME_WAIT: |
ret |
stateTCB_CLOSED: |
ret |
/kernel/branches/gfx_kernel/network/udp.inc |
---|
0,0 → 1,137 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; UDP.INC ;; |
;; ;; |
;; UDP Processes for Menuet OS TCP/IP stack ;; |
;; ;; |
;; Version 0.3 29 August 2002 ;; |
;; ;; |
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************* |
; Interface |
; |
; udp_rx Handles received IP packets with the UDP protocol |
; |
;******************************************************************* |
;*************************************************************************** |
; Function |
; udp_rx |
; |
; Description |
; UDP protocol handler |
; This is a kernel function, called by ip_rx |
; IP buffer address given in edx |
; Free up (or re-use) IP buffer when finished |
; |
;*************************************************************************** |
udp_rx: |
push eax |
; First validate the header & checksum. Discard buffer if error |
; Look for a socket where |
; IP Packet UDP Destination Port = local Port |
; IP Packet SA = Remote IP |
movzx ebx, word [edx + 22] ; get the local port from |
; the IP packet's UDP header |
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
mov ecx, NUM_SOCKETS |
fs1: |
sub eax, SOCKETBUFFSIZE |
cmp [eax + sockets + 12], bx ; bx will hold the 'wrong' value, |
; but the comparision is correct |
loopnz fs1 ; Return back if no match |
jz fs_done |
; No match, so exit |
jmp udprx_001 |
fs_done: |
; For dhcp, we must allow any remote server to respond. |
; I will accept the first incoming response to be the one |
; I bind to, if the socket is opened with a destination IP address of |
; 255.255.255.255 |
mov ebx, [eax + sockets + 16] |
cmp ebx, 0xffffffff |
je udprx_002 |
mov ebx, [edx + 12] ; get the Source address from the IP packet |
cmp [eax + sockets + 16], ebx |
jne udprx_001 ; Quit if the source IP is not valid |
udprx_002: |
; OK - we have a valid UDP packet for this socket. |
; First, update the sockets remote port number with the incoming msg |
; - it will have changed |
; from the original ( 69 normally ) to allow further connects |
movzx ebx, word [edx + 20] ; get the UDP source port |
; ( was 69, now new ) |
mov [eax + sockets + 20], bx |
; Now, copy data to socket. We have socket address as [eax + sockets]. |
; We have IP packet in edx |
; get # of bytes in ecx |
movzx ecx, byte [edx + 3] ; total length of IP packet. Subtract |
mov ch, byte [edx + 2] ; 20 + 8 gives data length |
sub ecx, 28 |
mov ebx, eax |
add ebx, sockets ; ebx = address of actual socket |
mov eax, [ebx+ 4] ; get socket owner PID |
push eax |
mov eax, [ebx + 24] ; get # of bytes already in buffer |
add [ebx + 24], ecx ; increment the count of bytes in buffer |
; point to the location to store the data |
add ebx, eax |
add ebx, SOCKETHEADERSIZE |
; ebx = location for first byte, ecx has count, |
; edx points to data |
add edx, 28 ; edx now points to the data |
mov edi, ebx |
mov esi, edx |
cld |
rep movsb ; copy the data across |
; flag an event to the application |
pop eax |
mov ecx,1 |
mov esi,0x3020+TASKDATA.pid |
newsearch: |
cmp [esi],eax |
je foundPID |
inc ecx |
add esi,0x20 |
cmp ecx,[0x3004] |
jbe newsearch |
foundPID: |
shl ecx,8 |
or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event |
mov [check_idle_semaphore],200 |
udprx_001: |
pop eax |
call freeBuff ; Discard the packet |
ret |
/kernel/branches/gfx_kernel/skin/base.bmp |
---|
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/gfx_kernel/skin/base_1.bmp |
---|
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/gfx_kernel/skin/default.asm |
---|
0,0 → 1,31 |
include 'me_skin.inc' |
SKIN_PARAMS \ |
height = bmp_base.height,\ ; skin height |
margins = [5:1:43:1],\ ; margins [left:top:right:bottom] |
colors active = [binner=0x00081d:\ ; border inner color |
bouter=0x00081d:\ ; border outer color |
bframe=0x0054e7],\ ; border frame color |
colors inactive = [binner=0x00081d:\ ; border inner color |
bouter=0x00081d:\ ; border outer color |
bframe=0x1a8acc],\ ; border frame color |
dtp = 'myblue.dtp' ; dtp colors |
SKIN_BUTTONS \ |
close = [-21:3][16:16],\ ; buttons coordinates |
minimize = [-39:3][16:16] ; [left:top][width:height] |
SKIN_BITMAPS \ |
left active = bmp_left,\ ; skin bitmaps pointers |
left inactive = bmp_left1,\ |
oper active = bmp_oper,\ |
oper inactive = bmp_oper1,\ |
base active = bmp_base,\ |
base inactive = bmp_base1 |
BITMAP bmp_left ,'left.bmp' ; skin bitmaps |
BITMAP bmp_oper ,'oper.bmp' |
BITMAP bmp_base ,'base.bmp' |
BITMAP bmp_left1,'left_1.bmp' |
BITMAP bmp_oper1,'oper_1.bmp' |
BITMAP bmp_base1,'base_1.bmp' |
/kernel/branches/gfx_kernel/skin/left.bmp |
---|
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/gfx_kernel/skin/left_1.bmp |
---|
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/gfx_kernel/skin/me_skin.inc |
---|
0,0 → 1,235 |
;============================================================================ |
; This file should be used to generate skins of new standard |
;============================================================================ |
; skin file structure: |
;---------------------------------------------------------------------------- |
; header: |
; dd 'SKIN' |
; dd = version (1 for now) |
; dd @ params |
; dd @ buttons |
; dd @ bitmaps |
; ... |
;---------------------------------------------------------------------------- |
; NOTE: order of sections listed below is insignificant |
; since they're identified by pointer in above header |
;---------------------------------------------------------------------------- |
; ... |
; params: |
; dd = skin height |
; dw = right margin |
; dw = left margin |
; dw = bottom margin |
; dw = top margin |
; dd = inner line color |
; dd = outer line color |
; dd = frame color |
; dd = dtp file size |
; ?? = dtp file itself |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; buttons: |
; dd = button type (1 = close, 2 = minimize) |
; dw = left button coord (could be negative) |
; dw = top button coord (could be negative) |
; dw = button width |
; dw = button height |
; ... etc for all buttons |
; dd = 0 (end of buttons list) |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; bitmaps: |
; dw = bitmap kind (1 = left, 2 = oper, 3 = base) |
; dw = bitmap type (1 = active, 0 = inactive) |
; dd @ bitmap |
; ... etc for all bitmaps |
; dd 0 (end of bitmaps list) |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; bitmap: |
; dd = bitmap width |
; dd = bitmap height |
; ?? = raw bitmap data |
; ... etc for all bitmaps |
; ... |
;============================================================================ |
dd 'SKIN',1,__params__,__buttons__,__bitmaps__ |
struc BITMAPFILEHEADER { |
.bfType dw ? ; WORD |
.bfSize dd ? ; DWORD |
.bfReserved1 dw ? ; WORD |
.bfReserved2 dw ? ; WORD |
.bfOffBits dd ? ; DWORD |
} |
struc BITMAPINFOHEADER { |
.biSize dd ? ; DWORD |
.biWidth dd ? ; LONG |
.biHeight dd ? ; LONG |
.biPlanes dw ? ; WORD |
.biBitCount dw ? ; WORD |
.biCompression dd ? ; DWORD |
.biSizeImage dd ? ; DWORD |
.biXPelsPerMeter dd ? ; LONG |
.biYPelsPerMeter dd ? ; LONG |
.biClrUsed dd ? ; DWORD |
.biClrImportant dd ? ; DWORD |
} |
struc _bmp { |
.h BITMAPFILEHEADER |
.i BITMAPINFOHEADER |
} |
virtual at 0 |
_bmp _bmp |
end virtual |
macro BITMAP _name*,_fname* |
{ |
local w,h,a,r,g,b |
virtual at 0 |
file _fname |
load w dword from _bmp.i.biWidth |
load h dword from _bmp.i.biHeight |
end virtual |
align 4 |
label _name |
.width = w |
.height = h |
dd w,h |
a=54+(w*3+(w mod 4))*(h-1) |
size = $ |
repeat h |
repeat w |
virtual at 0 |
file _fname |
load r from a+0 |
load g from a+1 |
load b from a+2 |
end virtual |
db r,g,b |
a=a+3 |
end repeat |
a=a-w*3*2-(w mod 4) |
end repeat |
} |
macro define_colors name,[col,val] |
{ |
common |
local a,b,c |
forward |
match =binner,col \{ a = val \} |
match =bouter,col \{ b = val \} |
match =bframe,col \{ c = val \} |
common |
name equ a,b,c |
} |
macro SKIN_PARAMS [a] |
{ |
common |
local _height,_margins,_colors,_colors_1,_dtp,_dtp_sz |
__params__: |
forward |
match qq == ww,a |
\{ |
match =height,qq \\{ _height = ww \\} |
match =margins,qq \\{ |
match [q1:q2:q3:q4],ww |
\\\{ |
_margins equ q3,q1,q4,q2 |
\\\} |
\\} |
match =colors =active,qq |
\\{ |
match [q10==q11:q20==q21:q30==q31],ww |
\\\{ |
define_colors _colors,q10,q11,q20,q21,q30,q31 |
\\\} |
\\} |
match =colors =inactive,qq |
\\{ |
match [q10==q11:q20==q21:q30==q31],ww |
\\\{ |
define_colors _colors_1,q10,q11,q20,q21,q30,q31 |
\\\} |
\\} |
match =dtp,qq \\{ _dtp equ ww \\} |
\} |
common |
dd _height |
dw _margins |
dd _colors,_colors_1 |
virtual at 0 |
file _dtp |
_dtp_sz = $ |
end virtual |
dd _dtp_sz |
file _dtp |
} |
macro SKIN_BUTTONS [a] |
{ |
common |
local btn |
__buttons__: |
forward |
match qq == ww,a |
\{ |
btn = 0 |
match =close,qq \\{ btn = 1 \\} |
match =minimize,qq \\{ btn = 2 \\} |
match [q1:q2][q3:q4],ww |
\\{ |
if btn <> 0 |
dd btn |
dw q1,q2,q3,q4 |
end if |
\\} |
\} |
common |
dd 0 |
} |
macro SKIN_BITMAPS [a] |
{ |
common |
local bmp |
__bitmaps__: |
forward |
match qq == ww,a |
\{ |
bmp=-1 |
match qqq =active,qq \\{ bmp = 1 \\} |
match qqq =inactive,qq \\{ bmp = 0 \\} |
match =left qqq,qq |
\\{ |
if bmp >= 0 |
dw 1,bmp |
dd ww |
end if |
\\} |
match =oper qqq,qq |
\\{ |
if bmp >= 0 |
dw 2,bmp |
dd ww |
end if |
\\} |
match =base qqq,qq |
\\{ |
if bmp >= 0 |
dw 3,bmp |
dd ww |
end if |
\\} |
\} |
common |
dd 0 |
} |
/kernel/branches/gfx_kernel/skin/myblue.dtp |
---|
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/gfx_kernel/skin/oper.bmp |
---|
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/gfx_kernel/skin/oper_1.bmp |
---|
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/gfx_kernel/sound/playnote.inc |
---|
0,0 → 1,135 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; PLAYNOTE.INC version 1.1 22 November 2003 ;; |
;; ;; |
;; Player Notes for Speaker PC ;; |
;; subfunction #55 from function #55 Menuet OS ;; |
;; ;; |
;; Copyright 2003 VaStaNi ;; |
;; vastani@ukr.net ;; |
;; >>>- SIMPLY - QUICKLY - SHORTLY -<<< ;; |
;; ;; |
;; Note: playnote.txt ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
kontrOctave dw 0x4742, 0x4342, 0x3F7C, 0x3BEC, 0x388F, 0x3562 |
dw 0x3264, 0x2F8F, 0x2CE4, 0x2A5F, 0x2802, 0x25BF |
memAdrNote dd 0 |
pidProcessNote dd 0 |
slotProcessNote dd 0 |
count_timer_Note dd 1 |
mem8253r42 dw 0 |
countDelayNote db 0 |
playNote: |
; jmp NotPlayNotes |
mov esi, [memAdrNote] |
or esi, esi ; ESI = 0 ? - OFF Notes Play ? |
jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure |
cmp eax, [count_timer_Note] |
jb NotPlayNotes |
push eax |
inc eax |
mov [count_timer_Note], eax |
mov al, [countDelayNote] |
dec al ; decrement counter Delay for Playing Note |
jz NewLoadNote@Delay |
cmp al, 0xFF ; this is first Note Play ? |
jne NextDelayNote |
;This is FIRST Note, save counter channel 2 chip 8253 |
mov al, 0xB6 ; control byte to timer chip 8253 |
out 0x43, al ; Send it to the control port chip 8253 |
in al, 0x42 ; Read Lower byte counter channel 2 chip 8253 |
mov ah, al ; AH = Lower byte counter channel 2 |
in al, 0x42 ; Read Upper byte counter channel 2 chip 8253 |
mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253 |
NewLoadNote@Delay: |
cld |
; lodsb ; load AL - counter Delay |
call ReadNoteByte |
or al, al ; THE END ? |
jz EndPlayNote |
cmp al, 0x81 |
jnc NoteforOctave |
mov [countDelayNote], al |
; lodsw ; load AX - counter for Note! |
call ReadNoteByte |
mov ah,al |
call ReadNoteByte |
xchg al,ah |
jmp pokeNote |
EndPlayNote: ; THE END Play Notes! |
in al, 0x61 ; Get contents of system port B chip 8255 |
and al, 0xFC ; Turn OFF timer and speaker |
out 0x61, al ; Send out new values to port B chip 8255 |
mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253 |
xchg al, ah ; reverse byte in word |
out 0x42, al ; restore Lower byte counter channel 2 |
mov al, ah ; AL = Upper byte counter channel 2 |
out 0x42, al ; restore Upper byte channel 2 |
xor eax, eax ; EAX = 0 |
mov [memAdrNote], eax ; clear header control Delay-Note string |
NextDelayNote: |
mov [countDelayNote], al ; save new counter delay Note |
pop eax |
NotPlayNotes: |
RET |
NoteforOctave: |
sub al, 0x81 ; correction value for delay Note |
mov [countDelayNote], al ; save counter delay this new Note |
; lodsb ; load pack control code |
call ReadNoteByte |
cmp al, 0xFF ; this is PAUSE ? |
jne packCode ; no, this is PACK CODE |
in al, 0x61 ; Get contents of system port B chip 8255 |
and al, 0xFC ; Turn OFF timer and speaker |
out 0x61, al ; Send out new values to port B chip 8255 |
jmp saveESI |
packCode: |
mov cl, al ; save code |
and al, 0xF ; clear upper bits |
dec al ; correction |
add al, al ; transform number to offset constant |
movsx eax, al ; EAX - offset |
add eax, dword kontrOctave ; EAX - address from constant |
mov ax, [eax] ; read constant |
shr cl, 4 ; transform for number Octave |
shr ax, cl ; calculate from Note this Octave! |
pokeNote: |
out 0x42, al ; Lower byte Out to channel 2 timer chip 8253 |
mov al, ah |
out 0x42, al ; Upper byte Out to channel 2 timer chip 8253 |
in al, 0x61 ; Get contents of system port B chip 8255 |
or al, 3 ; Turn ON timer and speaker |
out 0x61, al ; Send out new values to port B chip 8255 |
saveESI: |
; mov [memAdrNote], esi ; save new header control Delay-Note string |
pop eax |
RET |
ReadNoteByte: |
;result: |
; al - note |
push eax |
push ebx |
push ecx |
push edx |
mov eax,[pidProcessNote] |
call pid_to_slot |
test eax,eax |
jz .failed |
lea ebx,[esp+12] |
mov ecx,1 |
mov edx,[memAdrNote] |
inc [memAdrNote] |
call read_process_memory |
.failed: |
pop edx |
pop ecx |
pop ebx |
pop eax |
ret |
;------------------- END CODE ------------------- |
/kernel/branches/gfx_kernel/sound/sb16.inc |
---|
0,0 → 1,350 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SB16.INC ;; |
;; ;; |
;; Sound Blaster 16 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; - 11.07.2002 8 bit stereo mode - Ville Turjanmaa ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
SB16_load_music equ 0xc0000000 |
SB16_play_music equ 0xc0000001 |
DMAPage equ 0x2A |
Rate equ 44100 |
SB16Buffer equ 0x2A0000 |
SB16_Status equ SB16Buffer+65536 |
iglobal |
sound_data_format dd 0x1 |
sound_data_length dd 65536 |
sound_data_freq dd 44100 |
endg |
sound_interface: |
cmp eax,0 ; Load data |
jne no_SB16_load_music |
mov edi,[0x3010] |
add edi,TASKDATA.mem_start |
add ebx,[edi] |
call code_SB16_load_music |
ret |
no_SB16_load_music: |
cmp eax,1 ; Play data |
jne no_SB16_play_music |
call code_SB16_play_music |
ret |
no_SB16_play_music: |
cmp eax,2 ; Set data formats |
jne no_SB16_data_format |
cmp ebx,0 ; ebx=0 play format |
jne no_sound_format |
mov [sound_data_format],ecx ; 1=8b mono, 2=8b stereo |
ret |
no_sound_format: |
cmp ebx,1 ; ebx=1 data length |
jne no_sound_length |
mov [sound_data_length],ecx ; |
ret |
no_sound_length: |
cmp ebx,2 ; ebx=2 sound data frequency |
jne no_sound_freq |
mov [sound_data_freq],ecx |
ret |
no_sound_freq: |
ret |
no_SB16_data_format: |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
cmp eax, edi ; this is subfunction #55 ? |
jne retFunc55 ; if no then return. |
cmp byte [sound_flag],0 |
jne retFunc55 |
movzx eax, byte [countDelayNote] |
or al, al ; player is busy ? |
jnz retFunc55 ; return counter delay Note |
; mov eax, [0x3010] |
; mov eax, [eax+0x10] ; address application im memory |
; add eax, edx ; add offset Delay-Note string |
; mov [memAdrNote], eax |
mov [memAdrNote],edx |
mov eax,[0x3010] |
mov eax,[eax+TASKDATA.pid] |
mov [pidProcessNote],eax |
xor eax, eax ; Ok! EAX = 0 |
retFunc55: |
mov [esp+36], eax ; return value EAX for application |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
ret |
code_SB16_play_music: |
cmp [sound_data_format],1 |
jne no_sound_8bm |
call sb_play_8b_mono |
ret |
no_sound_8bm: |
cmp [sound_data_format],2 |
jne no_sound_8bs |
call sb_play_8b_stereo |
ret |
no_sound_8bs: |
ret |
Blaster_command: |
push eax |
push ecx |
push edx |
mov dx,word [sb16] |
add dx,0xc |
mov cx,1000 |
bcl1: |
in al,dx |
and al,128 |
jz bcl2 |
loop bcl1 |
bcl2: |
mov al,[esp+8] |
mov dx,[esp+0] |
add dx,word [sb16] |
out dx,al |
pop edx |
pop ecx |
pop eax |
ret |
sb_play_8b_stereo: |
pusha |
call sb_set_dma |
call sb_set_stereo |
mov dx,0xc |
mov al,0xa8 |
call Blaster_command |
mov al,0x40 |
call Blaster_command |
mov al,245 |
call Blaster_command |
mov al,0x48 |
call Blaster_command |
mov al,0xff |
call Blaster_command |
call Blaster_command |
mov al,0x91 |
call Blaster_command |
popa |
ret |
sb_set_stereo: |
push eax |
push edx |
call sb_wait |
mov dx,word [sb16] |
add dx,0x4 |
mov al,0xe |
out dx,al |
inc dx |
in al,dx |
and al,253 |
or al,2 ; stereo |
out dx,al |
pop edx |
pop eax |
ret |
code_SB16_load_music: |
cmp byte [SB16_Status],1 |
je nol |
mov edi,SB16Buffer |
mov esi,ebx |
mov ecx,65536/4 |
cld |
rep movsd |
nol: ret |
iglobal |
dma_table db 0x87,0x83,0x81,0x82 |
endg |
;-------------------------------- |
; program dma |
;-------------------------------- |
sb_set_dma: |
pusha |
mov eax,[sound_dma] |
add eax,4 |
out 0xa,al |
mov al,0 |
out 0xc,al |
mov eax,[sound_dma] |
add eax,0x48 |
out 0xb,al |
mov edx,[sound_dma] |
shl edx,1 |
mov al,0 |
out dx,al |
mov al,0 |
out dx,al |
mov edx,[sound_dma] |
add edx,dma_table |
movzx edx,byte [edx] |
mov al,DMAPage |
out dx,al |
mov edx,[sound_dma] |
shl edx,1 |
inc edx |
mov eax,[sound_data_length] |
dec eax |
and eax,0xff |
; mov al,(DataLength-1) and 0xff |
out dx,al |
mov eax,[sound_data_length] |
dec eax |
shr eax,8 |
; mov al,(DataLength-1) shr 8 |
out dx,al |
mov eax,[sound_dma] ; DMA |
out 0xa,al |
popa |
ret |
sb_play_8b_mono: |
call sb_set_dma |
cmp byte [SB16_Status],1 |
jne contsb16 |
jmp retserve |
contsb16: |
mov dx,word [sb16] |
add dx,4 |
mov ecx,[sound_dma] |
mov ax,0x01 |
shl ax,cl |
shl ax,8 |
add ax,0x81 |
out dx,ax |
mov ax,0f280h ;enable irq5 |
out dx,ax |
adr1_SB: mov dx,word [sb16] |
add dx,0ch |
in al,dx |
and al,080h |
jnz adr1_SB |
call sb_set_stereo |
mov al,0d1h |
out dx,al |
mov dx,word [sb16] |
add dx,0ch |
call sb_wait |
mov al,40h ; Rate |
out dx,al |
call sb_wait |
mov al,256-1000000/Rate |
out dx,al |
call sb_wait |
mov al,14h ; Datalength |
out dx,al |
call sb_wait |
mov eax,[sound_data_length] |
dec eax |
and eax,0xff |
;mov al,(DataLength-1) and 0xff |
out dx,al |
call sb_wait |
mov eax,[sound_data_length] |
dec eax |
shr eax,8 |
;mov al,(DataLength-1) shr 8 |
out dx,al |
retserve: |
ret |
sb_wait: in al,dx ;wait |
and al,080h |
jnz sb_wait |
ret |
;**************************************** |
; END CODE SB16 by Minazzi Paolo |
;*************************************** |
/kernel/branches/gfx_kernel/video/vesa12.inc |
---|
0,0 → 1,987 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; VESA12.INC ;; |
;; ;; |
;; Vesa 1.2 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Ville Turjanmaa ;; |
;; ;; |
;; quickcode@mail.ru - bankswitch for S3 cards ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; A complete video driver should include the following types of function |
; |
; Putpixel |
; Getpixel |
; |
; Drawimage |
; Drawbar |
; |
; Drawbackground |
; |
; |
; Modifying the set_bank -function is mostly enough |
; for different Vesa 1.2 setups. |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
; set_bank for Trident videocards, work on Trident 9440 |
; modified by Mario79 |
;set_bank: |
;cli |
;cmp al,[0xfff2] |
;je retsb |
;mov [0xfff2],al |
;push dx |
;mov dx,3D8h |
;out dx,al |
;pop dx |
;retsb: |
;sti |
;ret |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
; set_bank for S3 videocards, work on S3 ViRGE PCI (325) |
; modified by kmeaw |
set_bank: |
pushfd |
cli |
cmp al,[0xfff2] |
je retsb |
mov [0xfff2],al |
push ax |
push dx |
push cx |
mov cl, al |
mov dx, 0x3D4 |
mov al, 0x38 |
out dx, al ;CR38 Register Lock 1 ;Note: Traditionally 48h is used to |
;unlock and 00h to lock |
inc dx |
mov al, 0x48 |
out dx, al ;3d5 -? |
dec dx |
mov al, 0x31 |
out dx, al ;CR31 Memory Configuration Register |
;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear. |
;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h, |
;for the 864/964 see index 69h. |
inc dx |
in al, dx |
dec dx |
mov ah, al |
mov al, 0x31 |
out dx, ax |
mov al, ah |
or al, 9 |
inc dx |
out dx, al |
dec dx |
mov al, 0x35 |
out dx, al ;CR35 CRT Register Lock |
inc dx |
in al, dx |
dec dx |
and al, 0xF0 |
mov ch, cl |
and ch, 0x0F |
or ch, al |
mov al, 0x35 |
out dx, al |
inc dx |
mov al, ch |
out dx, ax |
dec dx |
mov al, 0x51 ;Extended System Control 2 Register |
out dx, al |
inc dx |
in al, dx |
dec dx |
and al, 0xF3 |
shr cl, 2 |
and cl, 0x0C |
or cl, al |
mov al, 0x51 |
out dx, al |
inc dx |
mov al, cl |
out dx, al |
dec dx |
mov al, 0x38 |
out dx, al |
inc dx |
xor al, al |
out dx, al |
dec dx |
pop cx |
pop dx |
pop ax |
retsb: |
popfd |
ret |
;Set bank function for Intel 810/815 chipsets |
; *****Modified by Protopopius, Russia.***** |
; ********* http://menuetos.hut.ru ************** |
; ************************************************ |
; |
;set_bank: |
;cli |
;cmp al,[0xfff2] |
;je retsb |
;mov [0xfff2],al |
;push ax |
;push dx |
;mov dx,3CEh |
;mov ah,al ; Save value for later use |
;mov al,10h ; Index GR10 (Address Mapping) |
;out dx,al ; Select GR10 |
;inc dl |
;mov al,3 ; Set bits 0 and 1 (Enable linear page mapping) |
;out dx,al ; Write value |
;dec dl |
;mov al,11h ; Index GR11 (Page Selector) |
;out dx,al ; Select GR11 |
;inc dl |
;mov al,ah ; Write address |
;out dx,al ; Write the value |
;pop dx |
;pop ax |
;retsb: |
;sti |
;ret |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!} |
;set_bank: |
; cli |
; cmp al,[0xfff2] |
; je retsb |
; mov [0xfff2],al |
; push ax |
; push dx |
; mov ah,al |
; mov dx,0x03D4 |
; mov al,0x39 |
; out dx,al |
; inc dl |
; mov al,0xA5 |
; out dx,al |
; dec dl |
; mov al,6Ah |
; out dx,al |
; inc dl |
; mov al,ah |
; out dx,al |
; dec dl |
; mov al,0x39 |
; out dx,al |
; inc dl |
; mov al,0x5A |
; out dx,al |
; dec dl |
; pop dx |
; pop ax |
; |
; retsb: |
; ret |
vesa12_drawbackground: |
call [disable_mouse] |
push eax |
push ebx |
push ecx |
push edx |
xor edx,edx |
mov eax,dword[WinMapAddress-8] |
mov ebx,dword[WinMapAddress-4] |
mul ebx |
mov ebx,3 |
mul ebx |
mov [imax],eax |
mov eax,[draw_data+32+RECT.left] |
mov ebx,[draw_data+32+RECT.top] |
mov edi,0 ;no force |
v12dp3: |
push eax |
push ebx |
mov esi,0x300000 |
cmp [WinMapAddress-12],dword 1 ; tiled background |
jne no_vesa12_tiled_bgr |
push edx |
xor edx,edx |
mov ecx,[WinMapAddress-8] |
div ecx |
mov eax,edx |
push eax |
mov eax,ebx |
xor edx,edx |
mov ecx,[WinMapAddress-4] |
div ecx |
mov ebx,edx |
pop eax |
pop edx |
no_vesa12_tiled_bgr: |
cmp [WinMapAddress-12],dword 2 ; stretched background |
jne no_vesa12_stretched_bgr |
push edx |
imul eax,dword [WinMapAddress-8] |
xor edx,edx |
mov ecx,[0xfe00] |
inc ecx |
div ecx |
push eax |
mov eax,ebx |
imul eax,dword [WinMapAddress-4] |
xor edx,edx |
mov ecx,[0xfe04] |
inc ecx |
div ecx |
mov ebx,eax |
pop eax |
pop edx |
no_vesa12_stretched_bgr: |
push eax |
mov eax,ebx |
xor edx,edx |
mov ebx,[WinMapAddress-8] |
add ebx,[WinMapAddress-8] |
add ebx,[WinMapAddress-8] |
mul ebx |
mov esi,eax |
pop eax |
add esi,eax |
add esi,eax |
add esi,eax |
add esi,0x300000 |
pop ebx |
pop eax |
v12di4: |
mov ecx,[esi] |
pusha |
mov esi,eax |
mov edi,ebx |
mov eax,[0xfe00] |
add eax,1 |
mul ebx |
add eax,esi |
add eax,WinMapAddress |
cmp [eax],byte 1 |
jnz v12nbgp |
mov eax,[0xfe08] |
mov ebx,edi |
mul ebx |
add eax,esi |
add eax,esi |
add eax,esi |
cmp [0xFBF1],byte 24 |
jz v12bgl3 |
add eax,esi |
v12bgl3: |
push ebx |
push eax |
sub eax,[0xfe80] |
shr eax,16 |
call set_bank |
pop eax |
and eax,65535 |
add eax,0xa0000 |
pop ebx |
mov [eax],cx |
add eax,2 |
shr ecx,16 |
mov [eax],cl |
sti |
v12nbgp: |
popa |
add esi,3 |
inc eax |
cmp eax,[draw_data+32+RECT.right] |
jg v12nodp31 |
jmp v12dp3 |
v12nodp31: |
mov eax,[draw_data+32+RECT.left] |
inc ebx |
cmp ebx,[draw_data+32+RECT.bottom] |
jg v12dp4 |
jmp v12dp3 |
v12dp4: |
pop edx |
pop ecx |
pop ebx |
pop eax |
ret |
vesa12_drawbar: |
call [disable_mouse] |
;; mov [novesachecksum],dword 0 |
sub edx,ebx |
sub ecx,eax |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
mov ecx,[0x3010] |
add eax,[ecx-twdw+WDATA.box.left] |
add ebx,[ecx-twdw+WDATA.box.top] |
push eax |
mov eax,ebx ; y |
mov ebx,[0xfe08] |
mul ebx |
pop ecx |
add eax,ecx ; x |
add eax,ecx |
add eax,ecx |
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start |
jz dbpi2412 |
add eax,ecx |
dbpi2412: |
add eax,[0xfe80] |
mov edi,eax |
; x size |
mov eax,[esp+4] ; [esp+6] |
mov ecx,eax |
add ecx,eax |
add ecx,eax |
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size |
jz dbpi24312 |
add ecx,eax |
dbpi24312: |
mov ebx,[esp+0] |
; check limits ? |
push eax |
push ecx |
mov eax,[0x3010] |
mov ecx,[eax+draw_data-0x3000+RECT.left] |
cmp ecx,0 |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-0x3000+RECT.top] |
cmp ecx,0 |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-0x3000+RECT.right] |
cmp ecx,[0xfe00] |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-0x3000+RECT.bottom] |
cmp ecx,[0xfe04] |
jnz dbcblimitlset12 |
pop ecx |
pop eax |
push dword 0 |
jmp dbcblimitlno12 |
dbcblimitlset12: |
pop ecx |
pop eax |
push dword 1 |
dbcblimitlno12: |
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? |
jz dbpi24bit12 |
jmp dbpi32bit12 |
; DRAWBAR 24 BBP |
dbpi24bit12: |
push eax |
push ebx |
push edx |
mov eax,ecx |
mov ebx,3 |
div ebx |
mov ecx,eax |
pop edx |
pop ebx |
pop eax |
cld |
dbnewpi12: |
push ebx |
push edi |
push ecx |
xor edx,edx |
mov eax,edi |
sub eax,[0xfe80] |
mov ebx,3 |
div ebx |
add eax,WinMapAddress |
mov ebx,[0x3000] |
cld |
dbnp2412: |
mov dl,[eax] |
push eax |
push ecx |
cmp dl,bl |
jnz dbimp24no12 |
cmp [esp+5*4],dword 0 |
jz dbimp24yes12 |
; call dbcplimit |
; jnz dbimp24no12 |
dbimp24yes12: |
push edi |
mov eax,edi |
sub eax,[0xfe80] |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,0xa0000 |
mov eax,[esp+8+3*4+16+4+4] |
stosw |
shr eax,16 |
stosb |
sti |
pop edi |
add edi,3 |
pop ecx |
pop eax |
inc eax |
loop dbnp2412 |
jmp dbnp24d12 |
dbimp24no12: |
pop ecx |
pop eax |
cld |
add edi,3 |
inc eax |
loop dbnp2412 |
dbnp24d12: |
mov eax,[esp+3*4+16+4] |
test eax,0x80000000 |
jz nodbgl2412 |
cmp al,0 |
jz nodbgl2412 |
dec eax |
mov [esp+3*4+16+4],eax |
nodbgl2412: |
pop ecx |
pop edi |
pop ebx |
add edi,[0xfe08] |
dec ebx |
jz dbnonewpi12 |
jmp dbnewpi12 |
dbnonewpi12: |
add esp,7*4 |
ret |
; DRAWBAR 32 BBP |
dbpi32bit12: |
cld |
shr ecx,2 |
dbnewpi3212: |
push ebx |
push edi |
push ecx |
mov eax,edi |
sub eax,[0xfe80] |
shr eax,2 |
add eax,WinMapAddress |
mov ebx,[0x3000] |
cld |
dbnp3212: |
mov dl,[eax] |
push eax |
push ecx |
cmp dl,bl |
jnz dbimp32no12 |
cmp [esp+5*4],dword 0 |
jz dbimp32yes12 |
; call dbcplimit |
; jnz dbimp32no12 |
dbimp32yes12: |
push edi |
mov eax,edi |
sub eax,[0xfe80] |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,0xa0000 |
mov eax,[esp+8+3*4+16+4+4] |
stosw |
shr eax,16 |
stosb |
sti |
pop edi |
add edi,4 |
inc ebp |
pop ecx |
pop eax |
inc eax |
loop dbnp3212 |
jmp dbnp32d12 |
dbimp32no12: |
pop ecx |
pop eax |
inc eax |
add edi,4 |
inc ebp |
loop dbnp3212 |
dbnp32d12: |
mov eax,[esp+12+16+4] |
test eax,0x80000000 |
jz nodbgl3212 |
cmp al,0 |
jz nodbgl3212 |
dec eax |
mov [esp+12+16+4],eax |
nodbgl3212: |
pop ecx |
pop edi |
pop ebx |
add edi,[0xfe08] |
dec ebx |
jz nodbnewpi3212 |
jmp dbnewpi3212 |
nodbnewpi3212: |
add esp,7*4 |
ret |
Vesa12_putpixel24: |
mov edi,eax ; x |
mov eax,ebx ; y |
lea edi,[edi+edi*2] |
mov ebx,[0xfe08] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,0xa0000 |
mov eax,[esp+28] |
stosw |
shr eax,16 |
mov [edi],al |
sti |
ret |
Vesa12_putpixel32: |
mov edi,eax ; x |
mov eax,ebx ; y |
shl edi,2 |
mov ebx,[0xfe08] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,0xa0000 |
mov ecx,[esp+28] |
mov [edi],ecx |
sti |
ret |
Vesa12_getpixel24: |
mov edi,eax ; x |
mov eax,ebx ; y |
lea edi,[edi+edi*2] |
mov ebx,[0xfe08] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,0xa0000 |
mov ecx,[edi] |
and ecx,255*256*256+255*256+255 |
sti |
ret |
Vesa12_getpixel32: |
mov edi,eax ; x |
mov eax,ebx ; y |
shl edi,2 |
mov ebx,[0xfe08] |
xor edx,edx |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,0xa0000 |
mov ecx,[edi] |
and ecx,255*256*256+255*256+255 |
sti |
ret |
vesa12_putimage: |
; mov ebx,image |
; mov ecx,320*65536+240 |
; mov edx,20*65536+20 |
call [disable_mouse] |
mov [novesachecksum],dword 0 |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
movzx eax,word [esp+2] |
movzx ebx,word [esp+0] |
mov ecx,[0x3010] |
add eax,[ecx-twdw+WDATA.box.left] |
add ebx,[ecx-twdw+WDATA.box.top] |
push eax |
mov eax,ebx ; y |
mov ebx,[0xfe08] |
mul ebx |
pop ecx |
add eax,ecx ; x |
add eax,ecx |
add eax,ecx |
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start |
jz pi2412 |
add eax,ecx |
pi2412: |
add eax,[0xfe80] |
mov edi,eax |
; x size |
movzx eax,word [esp+6] |
mov ecx,eax |
add ecx,eax |
add ecx,eax |
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size |
jz pi24312 |
add ecx,eax |
pi24312: |
mov esi,[esp+8] |
movzx ebx,word [esp+4] |
; check limits while draw ? |
push eax |
push ecx |
mov eax,[0x3010] |
mov ecx,[eax+draw_data-0x3000+RECT.left] |
cmp ecx,0 |
jnz dbcblimitlset212 |
mov ecx,[eax+draw_data-0x3000+RECT.top] |
cmp ecx,0 |
jnz dbcblimitlset212 |
mov ecx,[eax+draw_data-0x3000+RECT.right] |
cmp ecx,[0xfe00] |
jnz dbcblimitlset212 |
mov ecx,[eax+draw_data-0x3000+RECT.bottom] |
cmp ecx,[0xfe04] |
jnz dbcblimitlset212 |
pop ecx |
pop eax |
push dword 0 |
jmp dbcblimitlno212 |
dbcblimitlset212: |
pop ecx |
pop eax |
push dword 1 |
dbcblimitlno212: |
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? |
jz pi24bit12 |
jmp pi32bit12 |
pi24bit12: |
cld |
push eax |
push ebx |
push edx |
xor edx,edx |
mov eax,ecx |
mov ebx,3 |
div ebx |
mov ecx,eax |
pop edx |
pop ebx |
pop eax |
newpi12: |
push edi |
push esi |
push ecx |
push ebx |
xor edx,edx |
mov eax,edi |
sub eax,[0xfe80] |
mov ebx,3 |
div ebx |
add eax,WinMapAddress |
mov ebx,[0x3000] |
mov bh,[esp+4*4] |
np2412: |
cmp bl,[eax] |
jnz imp24no12 |
mov edx,[esi] |
cmp bh,0 |
jz imp24yes12 |
; call dbcplimit |
; jnz imp24no12 |
imp24yes12: |
push eax |
push edi |
mov eax,edi |
sub eax,[0xfe80] |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,0xa0000 |
mov [edi],edx |
shr edx,2 |
mov [edi+2],dl |
sti |
pop edi |
pop eax |
imp24no12: |
inc eax |
add esi,3 |
add edi,3 |
dec ecx |
jnz np2412 |
np24d12: |
pop ebx |
pop ecx |
pop esi |
pop edi |
add edi,[0xfe08] |
xor eax,eax |
mov ax,[esp+4+2+4] |
lea eax,[eax+eax*2] |
add esi,eax |
dec ebx |
jz nonewpi12 |
jmp newpi12 |
nonewpi12: |
add esp,7*4 |
mov eax,0 |
ret |
pi32bit12: |
cld |
shr ecx,2 |
newpi3212: |
push edi |
push esi |
push ecx |
push ebx |
mov eax,edi |
sub eax,[0xfe80] |
shr eax,2 |
add eax,WinMapAddress |
mov ebx,[0x3000] |
mov bh,[esp+4*4] |
np3212: |
cmp bl,[eax] |
jnz imp32no12 |
mov edx,[esi] |
cmp bh,0 |
jz imp32yes12 |
; call dbcplimit |
; jnz imp32no12 |
imp32yes12: |
push eax |
push edi |
mov eax,edi |
sub eax,[0xfe80] |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,0xa0000 |
mov [edi],edx |
sti |
pop edi |
pop eax |
imp32no12: |
inc eax |
add esi,3 |
add edi,4 |
dec ecx |
jnz np3212 |
np32d12: |
pop ebx |
pop ecx |
pop esi |
pop edi |
add edi,[0xfe08] |
movzx eax,word [esp+4+2+4] |
lea eax,[eax+eax*2] |
add esi,eax |
dec ebx |
jz nonewpi3212 |
jmp newpi3212 |
nonewpi3212: |
add esp,7*4 |
mov eax,0 |
ret |
vesa12_read_screen_pixel: |
and eax,0x3FFFFF |
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? |
jz v12rsp24 |
mov edi,eax |
shl edi,2 |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,0xa0000 |
mov eax,[edi] |
and eax,0x00ffffff |
ret |
v12rsp24: |
imul eax,3 |
mov edi,eax |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,0xa0000 |
mov eax,[edi] |
and eax,0x00ffffff |
ret |
/kernel/branches/gfx_kernel/video/vesa20.inc |
---|
0,0 → 1,1112 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; VESA20.INC ;; |
;; ;; |
;; Vesa 2.0 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Ville Turjanmaa ;; |
;; Alexey, kgaz@crosswindws.net ;; |
;; - Voodoo compatible graphics ;; |
;; Juan M. Caravaca ;; |
;; - Graphics optimimizations eg. drawline ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; If you're planning to write your own video driver I suggest |
; you replace the VESA12.INC file and see those instructions. |
ScreenWidth equ 0xfe00 |
ScreenHeight equ 0xfe04 |
BytesPerScanLine equ 0xfe08 |
LFBAddress equ 0xfe80 |
ScreenBPP equ 0xfbf1 |
WinMapAddress equ 0x460000 |
;************************************************* |
; getpixel |
; |
; in: |
; eax = x coordinate |
; ebx = y coordinate |
; |
; ret: |
; ecx = 00 RR GG BB |
__sys_getpixel: |
push eax ebx edx edi |
call dword [0xe024] |
pop edi edx ebx eax |
ret |
Vesa20_getpixel24: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [eax+eax*2] ; edi = x*3 |
add edi, ebx ; edi = x*3+(y*y multiplier) |
add edi, [LFBAddress] ; ebx = where pixel is in memory |
mov ecx, [edi] |
and ecx, 0xffffff |
ret |
Vesa20_getpixel32: |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) |
add edi, [LFBAddress] ; ebx = where pixel is in memory |
mov ecx, [edi] |
and ecx, 0xffffff |
ret |
;************************************************* |
virtual at esp |
putimg: |
.real_sx dd ? |
.real_sy dd ? |
.image_sx dd ? |
.image_sy dd ? |
.image_cx dd ? |
.image_cy dd ? |
.pti dd ? |
.abs_cx dd ? |
.abs_cy dd ? |
.line_increment dd ? |
.source_bpp dd ? |
.winmap_newline dd ? |
.screen_newline dd ? |
.stack_data = 4*13 |
end virtual |
align 4 |
; ebx = pointer |
; ecx = size [x|y] |
; edx = coordinates [x|y] |
vesa20_putimage: |
pushad |
call [disable_mouse] |
sub esp, putimg.stack_data |
mov [putimg.source_bpp], 3 |
; test ebx, 0x80000000 |
; jz @f |
; inc [putimg.source_bpp] |
; @@: |
; and ebx, 0x7FFFFFFF |
; save pointer to image |
mov [putimg.pti], ebx |
; unpack the size |
mov eax, ecx |
and ecx, 0xFFFF |
shr eax, 16 |
mov [putimg.image_sx], eax |
mov [putimg.image_sy], ecx |
; unpack the coordinates |
mov eax, edx |
and edx, 0xFFFF |
shr eax, 16 |
mov [putimg.image_cx], eax |
mov [putimg.image_cy], edx |
; calculate absolute (i.e. screen) coordinates |
mov eax, [0x3010] |
mov ebx, [eax-twdw + WDATA.box.left] |
add ebx, [putimg.image_cx] |
mov [putimg.abs_cx], ebx |
mov ebx, [eax-twdw + WDATA.box.top] |
add ebx, [putimg.image_cy] |
mov [putimg.abs_cy], ebx |
; real_sx = MIN(wnd_sx-image_cx, image_sx); |
mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx |
sub ebx, [putimg.image_cx] |
ja @f |
add esp, putimg.stack_data |
popad |
ret |
@@: |
cmp ebx, [putimg.image_sx] |
jbe .end_x |
mov ebx, [putimg.image_sx] |
dec ebx |
.end_x: |
inc ebx |
mov [putimg.real_sx], ebx |
; init real_sy |
mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy |
sub ebx, [putimg.image_cy] |
ja @f |
add esp, putimg.stack_data |
popad |
ret |
@@: |
cmp ebx, [putimg.image_sy] |
jbe .end_y |
mov ebx, [putimg.image_sy] |
dec ebx |
.end_y: |
inc ebx |
mov [putimg.real_sy], ebx |
; line increment |
mov eax, [putimg.image_sx] |
sub eax, [putimg.real_sx] |
;; imul eax, [putimg.source_bpp] |
lea eax, [eax + eax * 2] |
mov [putimg.line_increment], eax |
; winmap new line increment |
mov eax, [ScreenWidth] |
inc eax |
sub eax, [putimg.real_sx] |
mov [putimg.winmap_newline], eax |
; screen new line increment |
mov eax, [BytesPerScanLine] |
mov ecx, [putimg.real_sx] |
movzx ebx, byte [ScreenBPP] |
shr ebx, 3 |
imul ecx, ebx |
sub eax, ecx |
mov [putimg.screen_newline], eax |
; pointer to image |
mov ecx, [putimg.pti] |
; pointer to screen |
mov edx, [putimg.abs_cy] |
imul edx, [BytesPerScanLine] |
mov eax, [putimg.abs_cx] |
movzx ebx, byte [ScreenBPP] |
shr ebx, 3 |
imul eax, ebx |
add edx, eax |
add edx, [LFBAddress] |
; pointer to pixel map |
mov eax, [putimg.abs_cy] |
imul eax, [ScreenWidth] |
add eax, [putimg.abs_cy] |
add eax, [putimg.abs_cx] |
add eax, WinMapAddress |
xchg eax, ebp |
; get process number |
mov ebx, [0x3000] |
cmp byte [ScreenBPP], 32 |
je put_image_end_32 |
;put_image_end_24: |
mov edi, [putimg.real_sy] |
align 4 |
.new_line: |
mov esi, [putimg.real_sx] |
; push ebp edx |
align 4 |
.new_x: |
cmp [ebp], bl |
jne .skip |
mov eax, [ecx] ; ecx = RRBBGGRR |
mov [edx], ax |
shr eax, 16 |
mov [edx+2], al |
.skip: |
add ecx, 3 ;[putimg.source_bpp] |
add edx, 3 |
inc ebp |
dec esi |
jnz .new_x |
; pop edx ebp |
add ecx, [putimg.line_increment] |
add edx, [putimg.screen_newline] ;[BytesPerScanLine] |
add ebp, [putimg.winmap_newline] ;[ScreenWidth] |
;inc ebp |
dec edi |
jnz .new_line |
.finish: |
add esp, putimg.stack_data |
popad |
ret |
put_image_end_32: |
mov edi, [putimg.real_sy] |
align 4 |
.new_line: |
mov esi, [putimg.real_sx] |
; push ebp edx |
align 4 |
.new_x: |
cmp [ebp], bl |
jne .skip |
mov eax, [ecx] ; ecx = RRBBGGRR |
mov [edx], eax |
.skip: |
add ecx, [putimg.source_bpp] |
add edx, 4 |
inc ebp |
dec esi |
jnz .new_x |
; pop edx ebp |
add ecx, [putimg.line_increment] |
add edx, [putimg.screen_newline] ;[BytesPerScanLine] |
add ebp, [putimg.winmap_newline] ;[ScreenWidth] |
;inc ebp |
dec edi |
jnz .new_line |
.finish: |
add esp, putimg.stack_data |
popad |
call VGA__putimage |
mov [EGA_counter],1 |
ret |
;************************************************* |
align 4 |
__sys_putpixel: |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;;; mov [novesachecksum], dword 0 |
pushad |
test edi,1 ; force ? |
jnz .forced |
; not forced: |
push ecx ; save 24th bit in case negative pixel wanted |
call checkpixel |
test ecx,ecx |
pop ecx |
jnz .exit |
.forced: |
cmp [ScreenWidth], eax |
jb .exit |
cmp [ScreenHeight], ebx |
jb .exit |
.ok: |
; check if negation |
test ecx,0x01000000 |
jz .noneg |
call __sys_getpixel |
not ecx |
mov [esp+32-8],ecx |
.noneg: |
; OK to set pixel |
call dword [0xe020] ; call the real put_pixel function |
.exit: |
popad |
ret |
align 4 |
Vesa20_putpixel24: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [eax+eax*2] ; edi = x*3 |
mov eax, [esp+32-8+4] |
add edi, [LFBAddress] |
add edi, ebx ; ebx = where to put pixel in memory |
mov [edi], ax |
shr eax, 16 |
mov [edi+2], al |
ret |
align 4 |
Vesa20_putpixel32: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) |
mov eax, [esp+32-8+4] ; eax = color |
add edi, [LFBAddress] ; ebx = where to put pixel in memory |
mov [edi], eax |
ret |
;************************************************* |
;align 4 |
calculate_edi: |
mov edi, ebx |
imul edi, [ScreenWidth] |
add edi, ebx |
add edi, eax |
ret |
;************************************************* |
; DRAWLINE |
align 4 |
__sys_draw_line: |
; inc [mouse_pause] |
call [disable_mouse] |
; draw a line |
; eax = HIWORD = x1 |
; LOWORD = x2 |
; ebx = HIWORD = y1 |
; LOWORD = y2 |
; ecx = color |
; edi = force ? |
pusha |
dl_x1 equ esp+20 |
dl_y1 equ esp+16 |
dl_x2 equ esp+12 |
dl_y2 equ esp+8 |
dl_dx equ esp+4 |
dl_dy equ esp+0 |
xor edx, edx ; clear edx |
xor esi, esi ; unpack arguments |
xor ebp, ebp |
mov si, ax ; esi = x2 |
mov bp, bx ; ebp = y2 |
shr eax, 16 ; eax = x1 |
shr ebx, 16 ; ebx = y1 |
push eax ; save x1 |
push ebx ; save y1 |
push esi ; save x2 |
push ebp ; save y2 |
; checking x-axis... |
sub esi, eax ; esi = x2-x1 |
push esi ; save y2-y1 |
jl .x2lx1 ; is x2 less than x1 ? |
jg .no_vline ; x1 > x2 ? |
mov edx, ebp ; else (if x1=x2) |
call vline |
push edx ; necessary to rightly restore stack frame at .exit |
jmp .exit |
.x2lx1: |
neg esi ; get esi absolute value |
.no_vline: |
; checking y-axis... |
sub ebp, ebx ; ebp = y2-y1 |
push ebp ; save y2-y1 |
jl .y2ly1 ; is y2 less than y1 ? |
jg .no_hline ; y1 > y2 ? |
mov edx, [dl_x2] ; else (if y1=y2) |
call hline |
jmp .exit |
.y2ly1: |
neg ebp ; get ebp absolute value |
.no_hline: |
cmp ebp, esi |
jle .x_rules ; |y2-y1| < |x2-x1| ? |
cmp [dl_y2], ebx ; make sure y1 is at the begining |
jge .no_reverse1 |
neg dword [dl_dx] |
mov edx, [dl_x2] |
mov [dl_x2], eax |
mov [dl_x1], edx |
mov edx, [dl_y2] |
mov [dl_y2], ebx |
mov [dl_y1], edx |
.no_reverse1: |
mov eax, [dl_dx] |
cdq ; extend eax sing to edx |
shl eax, 16 ; using 16bit fix-point maths |
idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1) |
mov edx, ebp ; edx = counter (number of pixels to draw) |
mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0 |
mov esi, eax ; esi = dx |
jmp .y_rules |
.x_rules: |
cmp [dl_x2], eax ; make sure x1 is at the begining |
jge .no_reverse2 |
neg dword [dl_dy] |
mov edx, [dl_x2] |
mov [dl_x2], eax |
mov [dl_x1], edx |
mov edx, [dl_y2] |
mov [dl_y2], ebx |
mov [dl_y1], edx |
.no_reverse2: |
xor edx, edx |
mov eax, [dl_dy] |
cdq ; extend eax sing to edx |
shl eax, 16 ; using 16bit fix-point maths |
idiv esi ; eax = ((y2-y1)*65536)/(x2-x1) |
mov edx, esi ; edx = counter (number of pixels to draw) |
mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0 |
mov ebp, eax ; ebp = dy |
.y_rules: |
mov eax, [dl_x1] |
mov ebx, [dl_y1] |
shl eax, 16 |
shl ebx, 16 |
align 4 |
.draw: |
push eax ebx |
shr eax, 16 |
shr ebx, 16 |
call [putpixel] |
pop ebx eax |
add ebx, ebp ; y = y+dy |
add eax, esi ; x = x+dx |
dec edx |
jnz .draw |
; force last drawn pixel to be at (x2,y2) |
mov eax, [dl_x2] |
mov ebx, [dl_y2] |
call [putpixel] |
.exit: |
add esp, 6*4 |
popa |
; dec [mouse_pause] |
call [draw_pointer] |
ret |
hline: |
; draw an horizontal line |
; eax = x1 |
; edx = x2 |
; ebx = y |
; ecx = color |
; edi = force ? |
push eax edx |
cmp edx, eax ; make sure x2 is above x1 |
jge @f |
xchg eax, edx |
align 4 |
@@: |
call [putpixel] |
inc eax |
cmp eax, edx |
jle @b |
pop edx eax |
ret |
vline: |
; draw a vertical line |
; eax = x |
; ebx = y1 |
; edx = y2 |
; ecx = color |
; edi = force ? |
push ebx edx |
cmp edx, ebx ; make sure y2 is above y1 |
jge @f |
xchg ebx, edx |
align 4 |
@@: |
call [putpixel] |
inc ebx |
cmp ebx, edx |
jle @b |
pop edx ebx |
ret |
;************************************************* |
virtual at esp |
drbar: |
.bar_sx dd ? |
.bar_sy dd ? |
.bar_cx dd ? |
.bar_cy dd ? |
.abs_cx dd ? |
.abs_cy dd ? |
.real_sx dd ? |
.real_sy dd ? |
.color dd ? |
.line_inc_scr dd ? |
.line_inc_map dd ? |
.stack_data = 4*11 |
end virtual |
align 4 |
; eax cx |
; ebx cy |
; ecx xe |
; edx ye |
; edi color |
vesa20_drawbar: |
pushad |
call [disable_mouse] |
sub esp, drbar.stack_data |
mov [drbar.color], edi |
sub edx, ebx |
jle .exit ;// mike.dld, 2005-01-29 |
sub ecx, eax |
jle .exit ;// mike.dld, 2005-01-29 |
mov [drbar.bar_sy], edx |
mov [drbar.bar_sx], ecx |
mov [drbar.bar_cx], eax |
mov [drbar.bar_cy], ebx |
mov edi, [0x3010] |
add eax, [edi-twdw + WDATA.box.left] ; win_cx |
add ebx, [edi-twdw + WDATA.box.top] ; win_cy |
mov [drbar.abs_cx], eax |
mov [drbar.abs_cy], ebx |
; real_sx = MIN(wnd_sx-bar_cx, bar_sx); |
mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx |
sub ebx, [drbar.bar_cx] |
ja @f |
.exit: ;// mike.dld, 2005-01-29 |
add esp, drbar.stack_data |
popad |
xor eax, eax |
inc eax |
ret |
@@: |
cmp ebx, [drbar.bar_sx] |
jbe .end_x |
mov ebx, [drbar.bar_sx] |
.end_x: |
mov [drbar.real_sx], ebx |
; real_sy = MIN(wnd_sy-bar_cy, bar_sy); |
mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy |
sub ebx, [drbar.bar_cy] |
ja @f |
add esp, drbar.stack_data |
popad |
xor eax, eax |
inc eax |
ret |
@@: |
cmp ebx, [drbar.bar_sy] |
jbe .end_y |
mov ebx, [drbar.bar_sy] |
.end_y: |
mov [drbar.real_sy], ebx |
; line_inc_map |
mov eax, [ScreenWidth] |
sub eax, [drbar.real_sx] |
inc eax |
mov [drbar.line_inc_map], eax |
; line_inc_scr |
mov eax, [drbar.real_sx] |
movzx ebx, byte [ScreenBPP] |
shr ebx, 3 |
imul eax, ebx |
neg eax |
add eax, [BytesPerScanLine] |
mov [drbar.line_inc_scr], eax |
; pointer to screen |
mov edx, [drbar.abs_cy] |
imul edx, [BytesPerScanLine] |
mov eax, [drbar.abs_cx] |
; movzx ebx, byte [ScreenBPP] |
; shr ebx, 3 |
imul eax, ebx |
add edx, eax |
add edx, [LFBAddress] |
; pointer to pixel map |
mov eax, [drbar.abs_cy] |
imul eax, [ScreenWidth] |
add eax, [drbar.abs_cy] |
add eax, [drbar.abs_cx] |
add eax, WinMapAddress |
xchg eax, ebp |
; get process number |
mov ebx, [0x3000] |
cmp byte [ScreenBPP], 24 |
jne draw_bar_end_32 |
draw_bar_end_24: |
mov eax, [drbar.color] ;; BBGGRR00 |
mov bh, al ;; bh = BB |
shr eax, 8 ;; eax = RRGG |
; eax - color high RRGG |
; bl - process num |
; bh - color low BB |
; ecx - temp |
; edx - pointer to screen |
; esi - counter |
; edi - counter |
mov esi, [drbar.real_sy] |
align 4 |
.new_y: |
mov edi, [drbar.real_sx] |
align 4 |
.new_x: |
cmp byte [ebp], bl |
jne .skip |
mov [edx], bh |
mov [edx + 1], ax |
.skip: |
; add pixel |
add edx, 3 |
inc ebp |
dec edi |
jnz .new_x |
; add line |
add edx, [drbar.line_inc_scr] |
add ebp, [drbar.line_inc_map] |
; <Ivan 15.10.04> drawing gradient bars |
test eax, 0x00800000 |
jz @f |
test bh, bh |
jz @f |
dec bh |
@@: |
; </Ivan 15.10.04> |
dec esi |
jnz .new_y |
add esp, drbar.stack_data |
popad |
xor eax, eax |
ret |
draw_bar_end_32: |
mov eax, [drbar.color] ;; BBGGRR00 |
mov esi, [drbar.real_sy] |
align 4 |
.new_y: |
mov edi, [drbar.real_sx] |
align 4 |
.new_x: |
cmp byte [ebp], bl |
jne .skip |
mov [edx], eax |
.skip: |
; add pixel |
add edx, 4 |
inc ebp |
dec edi |
jnz .new_x |
; add line |
add edx, [drbar.line_inc_scr] |
add ebp, [drbar.line_inc_map] |
; <Ivan 15.10.04> drawing gradient bars |
test eax, 0x80000000 |
jz @f |
test al, al |
jz @f |
dec al |
@@: |
; </Ivan 15.10.04> |
dec esi |
jnz .new_y |
add esp, drbar.stack_data |
popad |
call VGA_draw_bar |
xor eax, eax |
mov [EGA_counter],1 |
ret |
;voodoodbcplimit: |
; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer |
; pusha |
; xor edx,edx |
; mov eax,ebp |
; mov ebx,[ScreenWidth] ; Screen_X_size |
; inc ebx ; +1 |
; sub eax,WinMapAddress ; -AddrBuffer |
; div ebx ; |
; mov ebx,eax ; ebx:=Y |
; mov eax,edx ; eax:=X |
; call cplimit |
; test ecx,ecx |
; jne dbcpl12 |
; popa |
; clc |
; ret |
; dbcpl12: |
; popa |
; stc |
; ret |
;dbcplimit: |
; pusha |
; xor edx,edx |
; mov ebx,[ScreenWidth] |
; inc ebx |
; sub eax,WinMapAddress |
; div ebx |
; mov ebx,eax |
; mov eax,edx |
; call cplimit |
; test ecx,ecx |
; jne dbcpl1 |
; popa |
; clc |
; ret |
; dbcpl1: |
; popa |
; stc |
; ret |
;--------------vbe voodoo ------------------------------------------------ |
vesa20_drawbackground_tiled: |
call [disable_mouse] |
push ebp |
push eax |
push ebx |
push ecx |
push edx |
mov edx,dword [WinMapAddress-8] ; B |
add edx,dword [WinMapAddress-8] ; +B |
add edx,dword [WinMapAddress-8] ; +B |
push edx |
mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin) |
mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin) |
mov eax,[BytesPerScanLine] |
mul ebx |
xchg ebp, eax ; BytesPerScanLine*(Ywin+y) |
add ebp, eax ; +X |
add ebp, eax ; +X |
add ebp, eax ; +X |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp,eax ; +X |
@@: |
add ebp,[LFBAddress] ; +LFB |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
dp3: ; MAIN LOOP |
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1) |
; je ybgp |
; |
; jmp nbgp |
; |
; ybgp: |
jne nbgp |
push eax |
push ebx |
mov ecx,dword [WinMapAddress-8] ; B |
xor edx,edx ; edx:=0 |
div ecx ; Xstart/B |
; eax=Int(qn) edx:=Rem |
lea esi,[edx+edx*2] ; esi:=edx*3 |
mov ecx,dword [WinMapAddress-4] ; ecx:=H |
mov eax,[esp+0] ; eax:=Ystart |
xor edx,edx ; |
div ecx ; Ystart/H |
mov eax,edx ; eax:=Rem |
xor edx,edx ; |
mov ebx,[esp+8] ; ebx:=B*3 |
mul ebx ; |
add esi,eax ; |
mov eax,[esi+0x300000] |
and eax,0xffffff |
xchg edi, ebp |
stosw |
shr eax,16 |
stosb |
xchg ebp, edi ; ebp+=3 |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
inc ebp ; +1 |
@@: |
pop ebx |
pop eax |
jmp hook1 |
nbgp: |
add ebp,3 ; +3 |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
inc ebp ; +1 |
@@: |
hook1: |
inc edi ; ptrBuffer++ |
add esi,3 ; ptrImage+=3 |
inc eax |
cmp eax,[draw_data+32+RECT.right] ; X > xend? |
; jg nodp3 |
; jmp dp3 |
; |
; nodp3: |
jle dp3 |
mov ebp,[draw_data+32+RECT.left] |
inc ebx |
mov eax,[BytesPerScanLine] |
mul ebx |
xchg ebp, eax ; BytesPerScanLine*(Ywin+y) |
add ebp, eax ; +X |
add ebp, eax ; +X=X*2 |
add ebp, eax ; +X=X*3 |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp,eax ; +X=X*4 |
@@: |
add ebp,[LFBAddress] ; +LFB |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
cmp ebx,[draw_data+32+RECT.bottom] |
; jg dp4 |
; |
; jmp dp3 |
; |
; dp4: |
jle dp3 |
add esp,4 |
pop edx |
pop ecx |
pop ebx |
pop eax |
pop ebp |
mov [EGA_counter],1 |
call VGA_drawbackground |
ret |
; ---------- |
vesa20_drawbackground_stretch: |
call [disable_mouse] |
push ebp |
push eax |
push ebx |
push ecx |
push edx |
mov edx,dword [WinMapAddress-8] ; B |
add edx,dword [WinMapAddress-8] ; +B |
add edx,dword [WinMapAddress-8] ; +B |
push edx |
mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin) |
mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin) |
mov eax,[BytesPerScanLine] |
mul ebx |
xchg ebp, eax ; BytesPerScanLine*(Ywin+y) |
add ebp, eax ; +X |
add ebp, eax ; +X |
add ebp, eax ; +X |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp,eax ; +X |
@@: |
add ebp,[LFBAddress] ; +LFB |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
sdp3: ; MAIN LOOP |
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1) |
jne snbgp |
push eax |
push ebx |
mov eax,dword [WinMapAddress-8] |
imul eax, [esp+4] ;4 |
xor edx,edx |
mov ebx,[ScreenWidth] |
div ebx |
lea esi,[eax+eax*2] |
mov eax,dword [WinMapAddress-4] |
imul eax, [esp+0] ;0 |
xor edx,edx |
mov ebx,[ScreenHeight] |
div ebx |
imul eax, [esp+8] ;8 |
add esi,eax |
mov eax,[esi+0x300000] |
and eax,0xffffff |
xchg edi, ebp |
stosw |
shr eax,16 |
stosb |
xchg ebp, edi ; ebp+=3 |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
inc ebp ; +1 |
@@: |
pop ebx |
pop eax |
jmp shook1 |
snbgp: |
add ebp,3 ; +3 |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
inc ebp ; +1 |
@@: |
shook1: |
inc edi ; ptrBuffer++ |
add esi,3 ; ptrImage+=3 |
inc eax |
cmp eax,[draw_data+32+RECT.right] ; X > xend? |
jle sdp3 |
mov ebp,[draw_data+32+RECT.left] |
inc ebx |
mov eax,[BytesPerScanLine] |
mul ebx |
xchg ebp, eax ; BytesPerScanLine*(Ywin+y) |
add ebp, eax ; +X |
add ebp, eax ; +X=X*2 |
add ebp, eax ; +X=X*3 |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp,eax ; +X=X*4 |
@@: |
add ebp,[LFBAddress] ; +LFB |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
cmp ebx,[draw_data+32+RECT.bottom] |
jle sdp3 |
add esp,4 |
pop edx |
pop ecx |
pop ebx |
pop eax |
pop ebp |
mov [EGA_counter],1 |
call VGA_drawbackground |
ret |
/kernel/branches/gfx_kernel/video/vga.inc |
---|
0,0 → 1,446 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; VGA.INC ;; |
;; ;; |
;; 640x480 mode 0x12 VGA functions for MenuetOS ;; |
;; ;; |
;; Paul Butcher, paul.butcher@asa.co.uk ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
paletteVGA: |
;16 colour palette |
mov dx,0x3c8 |
mov al,0 |
out dx,al |
mov ecx,16 |
mov dx,0x3c9 |
xor eax,eax |
palvganew: |
mov al,0 |
test ah,4 |
jz palvgalbl1 |
add al,31 |
test ah,8 |
jz palvgalbl1 |
add al,32 |
palvgalbl1: |
out dx,al ; red 0,31 or 63 |
mov al,0 |
test ah,2 |
jz palvgalbl2 |
add al,31 |
test ah,8 |
jz palvgalbl2 |
add al,32 |
palvgalbl2: |
out dx,al ; blue 0,31 or 63 |
mov al,0 |
test ah,1 |
jz palvgalbl3 |
add al,31 |
test ah,8 |
jz palvgalbl3 |
add al,32 |
palvgalbl3: |
out dx,al ; green 0,31 or 63 |
add ah,1 |
loop palvganew |
; mov dx, 3ceh |
; mov ax, 0005h |
; out dx, ax |
ret |
palette320x200: |
mov edx,0x3c8 |
xor eax, eax |
out dx,al |
mov ecx,256 |
mov edx,0x3c9 |
xor eax,eax |
palnew: |
mov al,0 |
test ah,64 |
jz pallbl1 |
add al,21 |
pallbl1: |
test ah,128 |
jz pallbl2 |
add al,42 |
pallbl2: |
out dx,al |
mov al,0 |
test ah,8 |
jz pallbl3 |
add al,8 |
pallbl3: |
test ah,16 |
jz pallbl4 |
add al,15 |
pallbl4: |
test ah,32 |
jz pallbl5 |
add al,40 |
pallbl5: |
out dx,al |
mov al,0 |
test ah,1 |
jz pallbl6 |
add al,8 |
pallbl6: |
test ah,2 |
jz pallbl7 |
add al,15 |
pallbl7: |
test ah,4 |
jz pallbl8 |
add al,40 |
pallbl8: |
out dx,al |
add ah,1 |
loop palnew |
ret |
uglobal |
novesachecksum dd 0x0 |
EGA_counter db 0 |
VGA_drawing_screen db 0 |
VGA_8_pixels: |
rb 16 |
temp: |
.cx dd 0 |
endg |
checkVga_N13: |
cmp [0xfe0c],dword 0x13 |
jne @f |
; cnvl: |
pushad |
cmp [EGA_counter],1 |
je novesal |
mov ecx,[0xfb0a] |
cmp ecx,[novesachecksum] |
jne novesal |
popad |
@@: |
ret |
novesal: |
mov [novesachecksum],ecx |
mov ecx,0 |
movzx eax,word [0xfb0c] |
cmp eax,100 |
jge m13l3 |
mov eax,100 |
m13l3: |
cmp eax,480-100 |
jbe m13l4 |
mov eax,480-100 |
m13l4: |
sub eax,100 |
imul eax,640*4 |
add ecx,eax |
movzx eax,word [0xfb0a] |
cmp eax,160 |
jge m13l1 |
mov eax,160 |
m13l1: |
cmp eax,640-160 |
jbe m13l2 |
mov eax,640-160 |
m13l2: |
sub eax,160 |
shl eax,2 |
add ecx,eax |
mov esi,[0xfe80] |
add esi,ecx |
mov edi,0xa0000 |
mov edx,200 |
mov ecx,320 |
cld |
m13pix: |
lodsd |
cmp eax,0 |
je .save_pixel |
push eax |
mov ebx,eax |
and eax,(128+64+32) ; blue |
shr eax,5 |
and ebx,(128+64+32)*256 ; green |
shr ebx,8+2 |
add eax,ebx |
pop ebx |
and ebx,(128+64)*256*256 ; red |
shr ebx,8+8 |
add eax,ebx |
.save_pixel: |
stosb |
loop m13pix |
mov ecx,320 |
add esi,4*(640-320) |
dec edx |
jnz m13pix |
mov [EGA_counter],0 |
popad |
ret |
VGA_drawbackground: |
; draw all |
cmp [0xfe0c],dword 0x12 |
jne .end |
pushad |
mov esi,[0xfe80] |
mov edi,0xa0000 |
mov ebx,640/32 ; 640*480/(8*4) |
mov edx,480 |
@@: |
push ebx edx esi edi |
shl edx,9 |
lea edx,[edx+edx*4] |
add esi,edx |
shr edx,5 |
add edi,edx |
call VGA_draw_long_line |
pop edi esi edx ebx |
dec edx |
jnz @r |
call VGA_draw_long_line_1 |
popad |
.end: |
ret |
VGA_draw_long_line: |
mov dx,3ceh |
mov ax,0ff08h |
cli |
out dx, ax |
mov ax,0005h |
out dx, ax |
m12pix: |
call VGA_draw_32_pixels |
dec ebx |
jnz m12pix |
mov dx,3c4h |
mov ax,0ff02h |
out dx,ax |
mov dx,3ceh |
mov ax,0205h |
out dx,ax |
mov dx,3ceh |
mov al,08h |
out dx,al |
sti |
ret |
VGA_draw_32_pixels: |
xor eax,eax |
mov ebp,VGA_8_pixels |
mov [ebp],eax |
mov [ebp+4],eax |
mov [ebp+8],eax |
mov [ebp+12],eax |
mov ch,4 |
.main_loop: |
mov cl,8 |
.convert_pixels_to_VGA: |
lodsd ; eax = 24bit colour |
cmp eax,0 |
je .end |
rol eax,8 |
mov al,ch |
ror eax,8 |
mov ch,1 |
dec cl |
shl ch,cl |
cmp al,85 |
jbe .p13green |
or [ebp],ch |
cmp al,170 |
jbe .p13green |
or [ebp+12],ch |
.p13green: |
cmp ah,85 |
jbe .p13red |
or [ebp+4],ch |
cmp ah,170 |
jbe .p13red |
or [ebp+12],ch |
.p13red: |
shr eax,8 |
cmp ah,85 |
jbe .p13cont |
or [ebp+8],ch |
cmp ah,170 |
jbe .p13cont |
or [ebp+12],ch |
.p13cont: |
ror eax,8 |
mov ch,ah |
inc cl |
.end: |
dec cl |
jnz .convert_pixels_to_VGA |
inc ebp |
dec ch |
jnz .main_loop |
push esi |
sub ebp,4 |
mov esi,ebp |
mov dx, 3c4h |
mov ah, 1h |
@@: |
mov al, 02h |
out dx,ax |
xchg ax,bp |
lodsd |
mov [edi],eax |
xchg ax,bp |
shl ah, 1 |
cmp ah, 10h |
jnz @r |
add edi,4 |
pop esi |
ret |
VGA_putpixel: |
; eax = x |
; ebx = y |
mov ecx,eax |
mov eax, [esp+32-8+4] ; color |
shl ebx,9 |
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5 |
lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32) |
mov edi,edx |
add edi, [0xfe80] ; + LFB address |
mov [edi], eax ; write to LFB for Vesa2.0 |
shr edx,5 ; change BytesPerPixel to 1/8 |
mov edi,edx |
add edi, 0x0a0000 ; address of pixel in VGA area |
and ecx,0x07 ; bit no. (modulo 8) |
pushfd |
; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8) |
xor edx,edx |
cmp eax,0 |
je .p13cont |
cmp al,85 |
jbe .p13green |
or dl,0x01 |
cmp al,170 |
jbe .p13green |
or dl,0x08 |
.p13green: |
cmp ah,85 |
jbe .p13red |
or dl,0x02 |
cmp ah,170 |
jbe .p13red |
or dl,0x08 |
.p13red: |
shr eax,8 |
cmp ah,85 |
jbe .p13cont |
or dl,0x04 |
cmp ah,170 |
jbe .p13cont |
or dl,0x08 |
.p13cont: |
ror edx,8 |
inc cl |
xor eax,eax |
inc ah |
shr ax,cl |
mov dx,3cfh |
cli |
out dx,al |
mov al,[edi] ; dummy read |
rol edx,8 |
mov [edi],dl |
popfd |
;.end: |
ret |
VGA__putimage: |
; ecx = size [x|y] |
; edx = coordinates [x|y] |
cmp [0xfe0c],dword 0x12 |
jne @f |
pushad |
rol edx,16 |
movzx eax,dx |
rol edx,16 |
movzx ebx,dx |
movzx edx,cx |
rol ecx,16 |
movzx ecx,cx |
call VGA_draw_bar_1 |
popad |
@@: |
ret |
VGA_draw_bar: |
; eax cx |
; ebx cy |
; ecx xe |
; edx ye |
cmp [0xfe0c],dword 0x12 |
jne @f |
pushad |
sub ecx,eax |
sub edx,ebx |
and eax,0xffff |
and ebx,0xffff |
and ecx,0xffff |
and edx,0xffff |
call VGA_draw_bar_1 |
popad |
@@: |
ret |
VGA_draw_bar_1: |
mov [temp.cx],eax |
mov eax, [0x3010] |
add ebx, [eax-twdw + 4] |
mov eax, [eax-twdw + 0] |
add eax, [temp.cx] |
and eax,0xfff8 |
shl ebx,9 |
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5 |
lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32) |
mov esi,ebx |
add esi, [0xfe80] ; + LFB address |
shr ebx,5 ; change BytesPerPixel to 1/8 |
mov edi,ebx |
add edi, 0x0a0000 ; address of pixel in VGA area |
mov ebx,ecx |
shr ebx,5 |
inc ebx |
.main_loop: |
call VGA_draw_long_line_1 |
dec edx |
jnz .main_loop |
call VGA_draw_long_line_1 |
ret |
VGA_draw_long_line_1: |
push ebx edx esi edi |
shl edx,9 |
lea edx,[edx+edx*4] |
add esi,edx |
shr edx,5 |
add edi,edx |
call VGA_draw_long_line |
pop edi esi edx ebx |
ret |
/kernel/branches/gfx_kernel/vmode/clipping.asm |
---|
0,0 → 1,501 |
;----------------------------------------------------------------------------- |
;///// PART OF ATi RADEON 9000 DRIVER //////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; Copyright (c) 2004, mike.dld |
; Using BeOS driver - Copyright (c) 2002, Thomas Kurschel |
;----------------------------------------------------------------------------- |
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
; DEALINGS IN THE SOFTWARE. |
;----------------------------------------------------------------------------- |
include 'clipping.inc' |
struct RECT |
left dd ? |
top dd ? |
right dd ? |
bottom dd ? |
ends |
virtual at ebp |
r RECT |
end virtual |
virtual at edi |
r2 RECT |
end virtual |
SR = sizeof.RECT |
macro movl val,reg { |
mov reg,val |
} |
EQUAL_LEFT = 00000001b |
EQUAL_BOTTOM = 00000010b |
EQUAL_RIGHT = 00000100b |
EQUAL_TOP = 00001000b |
func calc_clipping_rects |
begin |
mov [cnt],0 |
movzx ebp,word[0x3000] |
shl ebp,5 |
cmp ebp,0x20 |
jne @f |
mov esi,viewport |
mov edi,rct |
mov ecx,sizeof.RECT/4 |
cld |
rep movsd |
jmp .lp1 |
@@: |
movsx eax,word[ebp+0x00] |
mov [rct.left],eax |
mov [rct.right],eax |
movsx eax,word[ebp+0x04] |
mov [rct.top],eax |
mov [rct.bottom],eax |
movzx eax,word[ebp+0x08] |
inc eax |
add [rct.right],eax |
movzx eax,word[ebp+0x0C] |
inc eax |
add [rct.bottom],eax |
.lp1: |
mov esi,viewport |
mov edi,tr |
mov ecx,sizeof.RECT/4 |
cld |
rep movsd |
mov ebp,rct |
call intersect_rect ; (ebp,tr)->(x1:edx,y1:eax,x2:ebx,y2:ecx)+CF |
jc .exit |
mov [rct.left],edx |
mov [rct.top],eax |
mov [rct.right],ebx |
mov [rct.bottom],ecx |
inc [cnt] |
comment ^ |
movsx eax,word[ebp+0x00] |
mov [rct.left],eax |
mov [rct.right],eax |
movsx eax,word[ebp+0x04] |
mov [rct.top],eax |
mov [rct.bottom],eax |
movsx eax,word[ebp+0x08] |
inc eax |
add [rct.right],eax |
movsx eax,word[ebp+0x0C] |
inc eax |
add [rct.bottom],eax |
^ |
movzx ecx,word[0x00003004] ; number of processes |
jif ecx,be,1,.exit |
; calculate clipping rectangles |
mov esi,1 |
; go forward through all windows |
.next_window: |
movzx edi,word[0x00003000] ; calling process number |
mov ax,[0x0000C000+esi*2] |
jif ax,be,[0x0000C000+edi*2],.end_window.2 |
mov ebp,[cnt] |
shl ebp,4 ; ebp *= SR |
jz .exit |
lea ebp,[rct+ebp-SR] |
push esi ;ecx esi |
shl esi,5 |
lodsd |
mov [tr.left],eax |
mov [tr.right],eax |
lodsd |
mov [tr.top],eax |
mov [tr.bottom],eax |
lodsd |
jif eax,z,eax,.end_window,test |
inc eax |
add [tr.right],eax |
lodsd |
jif eax,z,eax,.end_window,test |
inc eax |
add [tr.bottom],eax |
; go backward through all rectangles |
.next_rect: |
rc_top equ eax |
rc_right equ ebx |
rc_bottom equ ecx |
rc_left equ edx |
call intersect_rect ; (ebp,tr)->(x1:edx,y1:eax,x2:ebx,y2:ecx)+CF |
jc .is_finish |
xor edi,edi |
jif rc_top,ne,[r.top],@f |
or edi,EQUAL_TOP |
@@: jif rc_right,ne,[r.right],@f |
or edi,EQUAL_RIGHT |
@@: jif rc_bottom,ne,[r.bottom],@f |
or edi,EQUAL_BOTTOM |
@@: jif rc_left,ne,[r.left],@f |
or edi,EQUAL_LEFT |
@@: jmp [jtable_intersect+edi*4] |
.is_0000: |
call copy_current |
mov [r.left ],rc_right |
mov [r2.right -SR],rc_left |
mov [r2.left ],rc_left |
mov [r2.right ],rc_right |
mov [r2.bottom ],rc_top |
mov [r2.left +SR],rc_left |
mov [r2.right +SR],rc_right |
mov [r2.top +SR],rc_bottom |
movl [r.top ],esi |
mov [r2.top ],esi |
movl [r.bottom ],esi |
mov [r2.bottom+SR],esi |
add [cnt],2 |
jmp .is_finish |
.is_0001: |
call copy_current |
mov [r.top ],rc_bottom |
mov [r2.bottom-SR],rc_top |
mov [r2.left ],rc_right |
mov [r2.top ],rc_top |
mov [r2.bottom ],rc_bottom |
movl [r.right ],esi |
mov [r2.right ],esi |
inc [cnt] |
jmp .is_finish |
.is_0010: |
call copy_current |
mov [r.left ],rc_right |
mov [r2.right -SR],rc_left |
mov [r2.left ],rc_left |
mov [r2.right ],rc_right |
mov [r2.bottom ],rc_top |
movl [r.top ],esi |
mov [r2.top ],esi |
inc [cnt] |
jmp .is_finish |
.is_0011: |
call copy_current |
mov [r.bottom ],rc_top |
mov [r2.left -SR],rc_right |
mov [r2.top -SR],rc_top |
jmp .is_finish |
.is_0100: |
call copy_current |
mov [r.top ],rc_bottom |
mov [r2.bottom-SR],rc_top |
mov [r2.right ],rc_left |
mov [r2.top ],rc_top |
mov [r2.bottom ],rc_bottom |
movl [r.left ],esi |
mov [r2.left ],esi |
inc [cnt] |
jmp .is_finish |
.is_0101: |
call copy_current |
mov [r.top ],rc_bottom |
mov [r2.bottom-SR],rc_top |
jmp .is_finish |
.is_0110: |
call copy_current |
mov [r.bottom ],rc_top |
mov [r2.right -SR],rc_left |
mov [r2.top -SR],rc_top |
jmp .is_finish |
.is_0111: |
mov [r.bottom ],rc_top |
jmp .is_finish |
.is_1000: |
call copy_current |
mov [r.left ],rc_right |
mov [r2.right -SR],rc_left |
mov [r2.left ],rc_left |
mov [r2.right ],rc_right |
mov [r2.top ],rc_bottom |
movl [r.bottom ],esi |
mov [r2.bottom ],esi |
inc [cnt] |
jmp .is_finish |
.is_1001: |
call copy_current |
mov [r.top ],rc_bottom |
mov [r2.left -SR],rc_right |
mov [r2.bottom-SR],rc_bottom |
jmp .is_finish |
.is_1010: |
call copy_current |
mov [r.left ],rc_right |
mov [r2.right -SR],rc_left |
jmp .is_finish |
.is_1011: |
mov [r.left ],rc_right |
jmp .is_finish |
.is_1100: |
call copy_current |
mov [r.top ],rc_bottom |
mov [r2.right -SR],rc_left |
mov [r2.bottom-SR],rc_bottom |
jmp .is_finish |
.is_1101: |
mov [r.top ],rc_bottom |
jmp .is_finish |
.is_1110: |
mov [r.right ],rc_left |
jmp .is_finish |
.is_1111: |
call delete_current |
.is_finish: |
sub ebp,SR |
jif ebp,ae,rct,.next_rect |
.end_window: |
pop esi; ecx |
.end_window.2: |
inc esi |
jif esi,be,[0x00003004],.next_window |
; dec ecx |
; jnz .next_window |
; combine some rectangles if possible |
; with Result do begin |
; for i := cnt-1 downto 0 do if rct[i].Left >= 0 then |
; for j := cnt-1 downto 0 do if (j <> i) and (rct[j].Left >= 0) then |
; if (rct[i].Left = rct[j].Left) and (rct[i].Right = rct[j].Right) then begin |
; end else if (rct[i].Top = rct[j].Top) and (rct[i].Bottom = rct[j].Bottom) then begin |
; if (rct[i].Left = rct[j].Right) then begin |
; rct[i].Left := rct[j].Left; |
; rct[j].Left := -1; |
; end else if (rct[i].Right = rct[j].Left) then begin |
; rct[i].Right := rct[j].Right; |
; rct[j].Left := -1; |
; end; |
; end; |
; for i := cnt-1 downto 0 do if rct[i].Left < 0 then begin |
; for j := i to cnt-2 do |
; rct[j] := rct[j+1]; |
; dec(cnt); |
; end; |
; end; |
.combine_rects: |
mov esi,[cnt] |
shl esi,4 |
add esi,rct |
lea ebp,[esi-SR] |
push ebp |
.next_rect1: |
sub esi,SR |
jif esi,b,rct,.exit.combine |
jif [esi+RECT.left],e,-1,.next_rect1 |
push ebp |
.next_rect2: |
jif ebp,e,esi,.next_rect2.ok |
jif [ebp+RECT.left],e,-1,.next_rect2.ok |
mov eax,[ebp+RECT.left] |
mov ebx,[ebp+RECT.right] |
mov ecx,[ebp+RECT.top] |
mov edx,[ebp+RECT.bottom] |
jif eax,ne,[esi+RECT.left],.not_left_right |
jif ebx,ne,[esi+RECT.right],.not_left_right |
jif edx,ne,[esi+RECT.top],@f |
mov [esi+RECT.top],ecx |
jmp .next_rect2.mark |
@@: jif ecx,ne,[esi+RECT.bottom],.next_rect2.ok |
mov [esi+RECT.bottom],edx |
jmp .next_rect2.mark |
.not_left_right: |
jif ecx,ne,[esi+RECT.top],.next_rect2.ok |
jif edx,ne,[esi+RECT.bottom],.next_rect2.ok |
jif ebx,ne,[esi+RECT.left],@f |
mov [esi+RECT.left],eax |
jmp .next_rect2.mark |
@@: jif eax,ne,[esi+RECT.right],.next_rect2.ok |
mov [esi+RECT.right],ebx |
.next_rect2.mark: |
or [ebp+RECT.left],-1 |
.next_rect2.ok: |
sub ebp,SR |
jif ebp,ae,rct,.next_rect2 |
pop ebp |
jmp .next_rect1 |
.exit.combine: |
pop ebp |
.next_rect3: |
jif [ebp+RECT.left],ne,-1,@f |
call delete_current |
@@: sub ebp,SR |
jif ebp,ae,rct,.next_rect3 |
; remove unnecessary rectangles |
; for i := Result.cnt-1 downto 0 do with Result do |
; if not IntersectRect(rc,rct[i],r2) then begin |
; for j := i to cnt-2 do |
; rct[j] := rct[j+1]; |
; dec(cnt); |
; end; |
.exit: |
mov esi,rct |
mov ecx,[cnt] |
ret |
delete_current: |
push ecx |
lea esi,[ebp+SR] ; esi = ebp+SR |
mov edi,ebp ; edi = ebp |
mov ecx,[cnt] ; ecx = cnt |
shl ecx,4 ; ecx *= SR |
add ecx,rct-SR ; ecx += rct-SR |
sub ecx,ebp ; ecx -= ebp |
cld |
rep movsb |
dec [cnt] |
pop ecx |
ret |
copy_current: |
push ecx |
mov edi,[cnt] |
shl edi,4 |
lea edi,[rct+edi] |
mov esi,ebp |
mov ecx,4 |
cld |
rep movsd |
pop ecx |
inc [cnt] |
ret |
intersect_rect: ; ebp,tr |
mov rc_top,[tr.top] |
jif rc_top,ge,[r.bottom],.exit |
mov rc_right,[tr.right] |
jif rc_right,le,[r.left],.exit |
mov rc_bottom,[tr.bottom] |
jif rc_bottom,le,[r.top],.exit |
mov rc_left,[tr.left] |
jif rc_left,ge,[r.right],.exit |
jif rc_top,ge,[r.top],@f |
mov rc_top,[r.top] |
@@: jif rc_right,le,[r.right],@f |
mov rc_right,[r.right] |
@@: jif rc_bottom,le,[r.bottom],@f |
mov rc_bottom,[r.bottom] |
@@: jif rc_left,ge,[r.left],@f |
mov rc_left,[r.left] |
@@: clc |
ret |
.exit: |
stc |
ret |
endf |
func FC |
begin |
.x00: |
.x01: |
.x02: |
.x04: |
.x05: |
.x06: |
.x08: |
.x09: |
.x0A: |
.x10: |
.x11: |
.x12: |
.x14: |
.x15: |
.x16: |
.x18: |
.x19: |
.x1A: |
.x20: |
.x21: |
.x22: |
.x24: |
.x25: |
.x26: |
.x28: |
.x29: |
.x2A: |
.x40: |
.x41: |
.x42: |
.x44: |
.x45: |
.x46: |
.x48: |
.x49: |
.x4A: |
.x50: |
.x51: |
.x52: |
.x54: |
.x55: |
.x56: |
.x58: |
.x59: |
.x5A: |
.x60: |
.x61: |
.x62: |
.x64: |
.x65: |
.x66: |
.x68: |
.x69: |
.x6A: |
.x80: |
.x81: |
.x82: |
.x84: |
.x85: |
.x86: |
.x88: |
.x89: |
.x8A: |
.x90: |
.x91: |
.x92: |
.x94: |
.x95: |
.x96: |
.x98: |
.x99: |
.x9A: |
.xA0: |
.xA1: |
.xA2: |
.xA4: |
.xA5: |
.xA6: |
.xA8: |
.xA9: |
.xAA: |
ret |
.xXX: |
ret |
endf |
;----------------------------------------------------------------------------- |
;///// END /////////////////////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/clipping.inc |
---|
0,0 → 1,25 |
align 4 |
jtable_intersect dd \ |
calc_clipping_rects.is_0000,calc_clipping_rects.is_0001,calc_clipping_rects.is_0010,calc_clipping_rects.is_0011,\ |
calc_clipping_rects.is_0100,calc_clipping_rects.is_0101,calc_clipping_rects.is_0110,calc_clipping_rects.is_0111,\ |
calc_clipping_rects.is_1000,calc_clipping_rects.is_1001,calc_clipping_rects.is_1010,calc_clipping_rects.is_1011,\ |
calc_clipping_rects.is_1100,calc_clipping_rects.is_1101,calc_clipping_rects.is_1110,calc_clipping_rects.is_1111 |
;jtable_fastclip dd \ |
; FC.x00,FC.x01,FC.x02,FC.xXX,FC.x04,FC.x05,FC.x06,FC.xXX,FC.x08,FC.x09,FC.x0A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.x10,FC.x11,FC.x12,FC.xXX,FC.x14,FC.x15,FC.x16,FC.xXX,FC.x18,FC.x19,FC.x1A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.x20,FC.x21,FC.x22,FC.xXX,FC.x24,FC.x25,FC.x26,FC.xXX,FC.x28,FC.x29,FC.x2A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.x40,FC.x41,FC.x42,FC.xXX,FC.x44,FC.x45,FC.x46,FC.xXX,FC.x48,FC.x49,FC.x4A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.x50,FC.x51,FC.x52,FC.xXX,FC.x54,FC.x55,FC.x56,FC.xXX,FC.x58,FC.x59,FC.x5A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.x60,FC.x61,FC.x62,FC.xXX,FC.x64,FC.x65,FC.x66,FC.xXX,FC.x68,FC.x69,FC.x6A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.x80,FC.x81,FC.x82,FC.xXX,FC.x84,FC.x85,FC.x86,FC.xXX,FC.x88,FC.x89,FC.x8A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.x90,FC.x91,FC.x92,FC.xXX,FC.x94,FC.x95,FC.x96,FC.xXX,FC.x98,FC.x99,FC.x9A,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX,\ |
; FC.xA0,FC.xA1,FC.xA2,FC.xXX,FC.xA4,FC.xA5,FC.xA6,FC.xXX,FC.xA8,FC.xA9,FC.xAA,FC.xXX,FC.xXX,FC.xXX,FC.xXX,FC.xXX;,\ |
; FC.xB0,FC.xB1,FC.xB2,FC.xB3,FC.xB4,FC.xB5,FC.xB6,FC.xB7,FC.xB8,FC.xB9,FC.xBA,FC.xBB,FC.xBC,FC.xBD,FC.xBE,FC.xBF,\ |
; FC.xC0,FC.xC1,FC.xC2,FC.xC3,FC.xC4,FC.xC5,FC.xC6,FC.xC7,FC.xC8,FC.xC9,FC.xCA,FC.xCB,FC.xCC,FC.xCD,FC.xCE,FC.xCF,\ |
; FC.xD0,FC.xD1,FC.xD2,FC.xD3,FC.xD4,FC.xD5,FC.xD6,FC.xD7,FC.xD8,FC.xD9,FC.xDA,FC.xDB,FC.xDC,FC.xDD,FC.xDE,FC.xDF,\ |
; FC.xE0,FC.xE1,FC.xE2,FC.xE3,FC.xE4,FC.xE5,FC.xE6,FC.xE7,FC.xE8,FC.xE9,FC.xEA,FC.xEB,FC.xEC,FC.xED,FC.xEE,FC.xEF,\ |
; FC.xF0,FC.xF1,FC.xF2,FC.xF3,FC.xF4,FC.xF5,FC.xF6,FC.xF7,FC.xF8,FC.xF9,FC.xFA,FC.xFB,FC.xFC,FC.xFD,FC.xFE,FC.xFF |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/makefile |
---|
0,0 → 1,12 |
FASM=fasm |
FENV=fasminc=/usr/fasm/include |
KSRC=vmode.asm |
KOUT=vmode.mdr |
en: $(KSRC) |
$(FENV) $(FASM) $(KSRC) $(KOUT) |
ru: $(KSRC) |
$(FENV) $(FASM) $(KSRC) $(KOUT) |
clean: |
rm -f $(KOUT) |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/norm_04.inc |
---|
0,0 → 1,1017 |
func color_24_to_4_bits |
begin |
push edx |
mov dl,0 |
cmp al,85 ; blue |
jbe .p13green |
or dl,0x01 |
cmp al,170 |
jbe .p13green |
or dl,0x08 |
.p13green: |
shr eax,8 |
cmp al,85 ; green |
jbe .p13red |
or dl,0x02 |
cmp al,170 |
jbe .p13red |
or dl,0x08 |
.p13red: |
cmp ah,85 ; red |
jbe .p13cont |
or dl,0x04 |
cmp ah,170 |
jbe .p13cont |
or dl,0x08 |
.p13cont: |
mov eax,edx |
pop edx |
ret |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_rect.04 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax - x start |
; ebx - y start |
; ecx - x end |
; edx - y end |
; edi - color |
;----------------------------------------------------------------------------- |
;- eax(ebx) [x start]*65536 + [x size] |
;- ebx(ecx) [y start]*65536 + [y size] |
;- ecx(edx) color 0x00RRGGBB |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
jif eax,e,ecx,.exit |
jif ebx,e,edx,.exit |
call get_cursor_rect |
push eax |
mov eax,edi |
call color_24_to_4_bits |
mov edi,eax |
pop eax |
mov ebp,[0x3010] |
movsx esi,word[ebp-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[ebp-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[ebp-0x3000+0] |
; add ebx,[ebp-0x3000+4] |
; add ecx,[ebp-0x3000+0] |
; add edx,[ebp-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,le,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,le,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: sub edx,ebx |
push edx edi ebx eax |
mov edi,ebx |
shl edi,6 |
shl ebx,4 |
add edi,ebx |
shr eax,3 |
add edi,eax |
add edi,0x000A0000 |
pop eax ebx |
mov ebx,eax |
mov esi,ecx |
sub esi,eax |
mov dx,0x03CE |
;edi = Offset in VMem |
;esi = Length |
;ebx = x |
; dx = Graphix Controller |
mov cl,bl ; Get StartBit |
and ecx,07h |
mov eax,esi |
add eax,ecx |
cmp eax,8 ; Is x+Length<One Byte |
jb .D_One |
mov ax,0xff08 ; 11111111b | BitMask Register |
shr ah,cl ; BitMask |
out dx,ax ; Write BitMask |
push ecx |
mov ah,[esp+4] |
mov ecx,[esp+4+4] |
push edi |
.D_LL: ; Draw Left of Box |
mov al,[edi] |
mov [edi],ah |
add edi,80 ; edi:=edi+80 |
dec ecx |
jnz .D_LL |
pop edi |
inc edi |
pop ecx |
mov ax,0xFF08 ; BitMask Register |
out dx,ax ; Write BitMask |
mov eax,esi |
mov ch,8 |
sub ch,cl |
movzx ecx,ch |
sub eax,ecx |
shr eax,3 ; Length div 8 |
push edi ebx |
mov ebx,[esp+8+4] |
mov edx,eax |
mov al,[esp+8] |
.D_LC: |
mov ecx,edx |
rep stosb |
add edi,80 |
sub edi,edx |
dec ebx |
jnz .D_LC |
pop ebx edi |
add edi,edx |
mov ecx,ebx ; ecx:=x+Length |
add ecx,esi |
and ecx,07h ; ecx and 07 |
mov ah,0ffh |
shr ah,cl ; BitMask |
jz .D_End |
not ah |
mov al,8 ; BitMask Register |
mov dx,03ceh ; Graphics Controller |
out dx,ax ; Write BitMask |
mov ecx,[esp+4] |
mov al,[esp] |
.D_LR: |
mov ah,[edi] |
mov [edi],al |
add edi,80 |
dec ecx |
jnz .D_LR |
jmp .D_End |
.D_One: |
mov ah,0ffh |
shr ah,cl ; Left BitMask |
add ebx,esi |
dec ebx |
and ebx,07h |
mov ecx,7 |
sub ecx,ebx |
mov bl,0ffh |
shl bl,cl ; Right BitMask |
and ah,bl ; Full BitMask |
mov al,8 ; BitMask Register |
out dx,ax ; Write BitMask |
mov ecx,[esp+4] |
mov al,[esp] |
.D_L: |
mov dl,[edi] ; Fill Latches |
mov [edi],al ; Write Pixel |
add edi,80 |
dec ecx |
jnz .D_L |
.D_End: |
pop edi |
add esp,4 |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_line.04 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) [x start] shl 16 + [x end] |
; ebx(ecx) [y start] shl 16 + [y end] |
; ecx(edx) colour 0x00RRGGBB |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
push 0 |
pushad |
cli |
test ecx,0x01000000 |
jnz .exit |
call get_cursor_rect |
mov eax,ecx |
call color_24_to_4_bits |
; mov [esp+4*8],ecx |
mov [esp+4*8],al |
movsx eax,word[esp+4*7] ; x end |
cmp ax,[esp+4*7+2] ; x start |
je dl.vert_line |
movsx eax,word[esp+4*4] ; y end |
cmp ax,[esp+4*4+2] ; y start |
je dl.horz_line |
.exit: |
sti |
popad |
add esp,4 |
retn |
dl.vert_line: |
push eax |
mov cl,al |
and cl,7 |
mov ax,0x8008 |
shr ah,cl |
mov dx,0x03CE |
out dx,ax |
pop eax |
mov ecx,[esp+4*8] |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
dec edx |
.draw: |
@@: call is_intersect_vln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: push ebx eax |
mov ebp,ebx |
shl ebp,6 |
shl ebx,4 |
add ebp,ebx |
shr eax,3 |
add ebp,eax |
add ebp,0x000A0000 |
pop eax ebx |
@@: mov ch,[ebp] |
mov [ebp],cl |
add ebp,80 |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
add esp,4 |
retn |
.forced: |
jif eax,l,[viewport.left],.exit |
jif eax,ge,[viewport.right],.exit |
movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
jif ebx,e,edx,.exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.top],.exit |
jif ebx,ge,[viewport.bottom],.exit |
jif ebx,ge,[viewport.top],@f |
mov ebx,[viewport.top] |
@@: jif edx,l,[viewport.bottom],@f |
mov edx,[viewport.bottom] |
dec edx |
@@: mov edi,1 |
jmp .draw |
dl.horz_line: |
cld |
mov ecx,[esp+4*8] |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.top],.skip |
jif eax,ge,[rr.bottom],.skip |
jif edx,l,[rr.left],.skip |
jif ebx,ge,[rr.right],.skip |
jif ebx,ge,[rr.left],@f |
mov ebx,[rr.left] |
@@: jif edx,l,[rr.right],@f |
mov edx,[rr.right] |
dec edx |
.draw: |
@@: call is_intersect_hln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: push edi ebx eax |
mov edi,eax |
shl edi,6 |
shl eax,4 |
add edi,eax |
shr ebx,3 |
add edi,ebx |
add edi,0x000A0000 |
pop eax ebx |
push eax ebx edx esi ecx |
mov esi,edx |
sub esi,ebx |
inc esi |
mov dx,0x03CE |
;edi = Offset in VMem |
;esi = Length |
;ebx = x |
; dx = Graphix Controller |
mov cl,bl ; Get StartBit |
and ecx,07h |
mov eax,esi |
add eax,ecx |
cmp eax,8 ; Is x+Length<One Byte |
jb .D_One |
mov ax,0xFF08 ; 11111111b | BitMask Register |
shr ah,cl ; BitMask |
out dx,ax ; Write BitMask |
mov al,[edi] |
mov eax,[esp] |
mov [edi],al |
inc edi |
mov ax,0xFF08 ; BitMask | BitMask Register |
out dx,ax ; Write BitMask |
mov eax,esi |
mov ch,8 |
sub ch,cl |
mov cl,ch |
xor ch,ch |
sub eax,ecx |
shr eax,3 ; Length div 8 |
mov ecx,eax |
mov eax,[esp] |
rep stosb |
mov ecx,ebx ; ecx:=x+Length |
add ecx,esi |
and ecx,07h ; ecx and 07 |
mov ah,0ffh |
shr ah,cl ; BitMask |
jz .D_End |
not ah |
mov al,8 ; BitMask Register |
out dx,ax ; Write BitMask |
mov cl,[edi] |
mov eax,[esp] |
mov [edi],al |
jmp .D_End |
.D_One: |
mov ax,0xff08 ; | BitMask Register |
shr ah,cl ; Left BitMask |
add ebx,esi |
dec ebx |
and ebx,07h |
mov ecx,7 |
sub ecx,ebx |
mov bl,0ffh |
shl bl,cl ; Right BitMask |
and ah,bl ; Full BitMask |
out dx,ax ; Write BitMask |
mov dl,[edi] ; Fill Latches |
mov eax,[esp] |
mov [edi],al ; Write Pixel |
.D_End: |
pop ecx esi edx ebx eax edi |
; mov ebp,[bytes_per_scanline] |
; imul ebp,eax |
; lea ebp,[ebp+ebx*4] |
; add ebp,[lfb_address] |
; @@: test ecx,0x01000000 |
; jz .dr |
; mov ecx,[ebp] |
; not ecx |
; or ecx,0x01000000 |
; .dr: mov [ebp],ecx |
; add ebp,4 |
; inc ebx |
; cmp ebx,edx |
; jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
add esp,4 |
retn |
.forced: |
jif eax,l,[viewport.top],.exit |
jif eax,ge,[viewport.bottom],.exit |
movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.left],.exit |
jif ebx,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.left],@f |
mov ebx,[viewport.left] |
@@: jif edx,l,[viewport.right],@f |
mov edx,[viewport.right] |
dec edx |
@@: mov edi,1 |
jmp .draw |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_pixel.04 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
; mov edx,[bytes_per_scanline] |
; imul edx,ebx |
; lea edx,[edx+eax*4] |
; add edx,[lfb_address] |
; test ecx,0x01000000 |
; jz @f |
; mov ecx,[edx] |
; not ecx |
@@: test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif ebx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
call get_cursor_rect |
call is_intersect_pt |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put:;mov [edx],ecx |
; mov ax,SegA000 {Calculate Offset} |
; mov es,ax |
; mov bx,[y] |
mov edi,ebx |
shl edi,6 ; 80*y |
shl ebx,4 |
add edi,ebx |
push ecx |
mov cl,al |
shr eax,3 ; /8 |
add edi,eax ; 80*y + (x/8) |
and cl,7 ; Get Bit that Changes |
mov ax,0x8008 |
shr ah,cl |
mov dx,0x03CE |
out dx,ax |
add edi,0x000A0000 |
call color_24_to_4_bits |
mov ah,[edi] ; dummy read |
mov [edi],al |
.exit: |
sti |
popad |
retn |
.skip: |
add esi,SR |
dec edi |
jnz @b |
jmp .exit |
.forced: |
jif eax,l,[viewport.left],.exit |
jif ebx,l,[viewport.top],.exit |
jif eax,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.bottom],.exit |
; mov ax,SegA000 {Calculate Offset} |
; mov es,ax |
; mov bx,[y] |
mov edi,ebx |
shl edi,6 ; 80*y |
shl ebx,4 |
add edi,ebx |
push ecx |
mov cl,al |
shr eax,3 ; /8 |
add edi,eax ; 80*y + (x/8) |
and cl,7 ; Get Bit that Changes |
mov ax,0x8008 |
shr ah,cl |
mov dx,0x03CE |
out dx,ax |
add edi,0x000A0000 |
pop eax |
call color_24_to_4_bits |
mov ah,[edi] ; dummy read |
mov [edi],al |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_get_pixel.04 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
;----------------------------------------------------------------------------- |
clr_table dd \ |
0x00000000,0x00000080,0x00008000,0x00008080,\ |
0x00800000,0x00800080,0x00808000,0x00808080,\ |
0x00CCCCCC,0x000000FF,0x0000FF00,0x0000FFFF,\ |
0x00FF0000,0x00FF00FF,0x00FFFF00,0x00FFFFFF |
begin |
pushad |
cli |
mov edi,ebx |
shl edi,6 ; 80*y |
shl ebx,4 |
add edi,ebx |
mov cl,al |
shr eax,3 ; /8 |
add edi,eax ; 80*y + (x/8) |
add edi,0x000A0000 |
and ecx,7 |
neg ecx |
add cl,7 |
mov dx,0x03CE |
xor bl,bl |
mov ah,3 |
@1: |
mov al,4 |
out dx,al |
inc dx |
mov al,ah |
out dx,al |
dec dx |
mov al,[edi] |
shr al,cl |
and al,1 |
xchg cl,ah |
shl al,cl |
xchg cl,ah |
or bl,al |
dec ah |
jns @1 |
and ebx,0x0000000F |
mov eax,[ebx*4+clr_table] |
mov [esp+4*6],eax |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_image.04 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) pointer to image in memory - RRGGBBRRGGBB.. |
; ebx(ecx) image size [x]*65536+[y] |
; ecx(edx) image position in window [x]*65536+[y] |
; ret: eax 0 succesful, 1 overlapped |
;----------------------------------------------------------------------------- |
begin |
mov eax,ebx |
mov ebx,ecx |
mov ecx,edx |
.direct: |
pushad |
cli |
jif ebx,z,0x0000FFFF,.exit,test |
jif ebx,z,0xFFFF0000,.exit,test |
cld |
call get_cursor_rect |
mov ebp,eax |
movsx eax,word[esp+4*6+2] |
movsx ebx,word[esp+4*6] |
movsx ecx,word[esp+4*4+2] |
movsx edx,word[esp+4*4] |
lea edi,[ecx*3] |
push edi |
add ecx,eax |
add edx,ebx |
mov edi,[0x00003010] |
movsx esi,word[edi-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[edi-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[esi-0x3000+0] |
; add ebx,[esi-0x3000+4] |
; add ecx,[esi-0x3000+0] |
; add edx,[esi-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
cld |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: |
mov esi,ebx |
sub esi,[esp+4*4] |
imul esi,[esp+4*8] |
mov edi,eax |
sub edi,[esp+4*7] |
lea edi,[edi*3] |
add esi,edi |
add esi,ebp |
mov edi,ebx |
mov ebp,ebx |
shl edi,6 ; 80*y |
shl ebp,4 |
add edi,ebp |
add edi,0x000A0000 |
.xxx: push eax edx esi edi ebx eax |
or ebp,-1 |
mov edx,0x03CE |
@@: mov eax,[esp] |
push ecx edi |
mov cl,al |
shr eax,3 ; /8 |
add edi,eax ; 80*y + (x/8) |
mov eax,0x8008 |
and cl,7 ; Get Bit that Changes |
shr ah,cl |
out dx,ax |
lodsd |
dec esi |
and eax,0x00FFFFFF |
cmp eax,ebp |
jne .ppp |
mov cl,bl |
jmp .ppp.2 |
.ppp: |
mov ebp,eax |
call color_24_to_4_bits |
mov bl,al |
.ppp.2: |
mov al,[edi] ; dummy read |
mov [edi],cl |
pop edi ecx |
inc dword[esp] |
cmp [esp],ecx |
jl @b |
pop eax ebx edi esi edx eax |
inc ebx |
add esi,[esp+4*8] |
add edi,80 |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
add esp,4 |
sti |
popad |
xor eax,eax |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_bg.04 ;///////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
begin |
pushad |
cmp byte[0x460000-12],1 |
je .tiled |
mov eax,[viewport.left] |
mov ebx,[viewport.top] |
mov ecx,[viewport.right] |
mov edx,[viewport.bottom] |
mov edi,[0x00300000] |
cli |
jif eax,e,ecx,.exit |
jif ebx,e,edx,.exit |
call get_cursor_rect |
push eax |
mov eax,edi |
call color_24_to_4_bits |
mov edi,eax |
pop eax |
mov esi,[CLIP_RECTS+4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,le,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,le,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: sub edx,ebx |
push edx edi ebx eax |
mov edi,ebx |
shl edi,6 |
shl ebx,4 |
add edi,ebx |
shr eax,3 |
add edi,eax |
add edi,0x000A0000 |
pop eax ebx |
mov ebx,eax |
mov esi,ecx |
sub esi,eax |
mov dx,0x03CE |
;edi = Offset in VMem |
;esi = Length |
;ebx = x |
; dx = Graphix Controller |
mov cl,bl ; Get StartBit |
and ecx,07h |
mov eax,esi |
add eax,ecx |
cmp eax,8 ; Is x+Length<One Byte |
jb .D_One |
mov ax,0xff08 ; 11111111b | BitMask Register |
shr ah,cl ; BitMask |
out dx,ax ; Write BitMask |
push ecx |
mov ah,[esp+4] |
mov ecx,[esp+4+4] |
push edi |
.D_LL: ; Draw Left of Box |
mov al,[edi] |
mov [edi],ah |
add edi,80 ; edi:=edi+80 |
dec ecx |
jnz .D_LL |
pop edi |
inc edi |
pop ecx |
mov ax,0xFF08 ; BitMask Register |
out dx,ax ; Write BitMask |
mov eax,esi |
mov ch,8 |
sub ch,cl |
movzx ecx,ch |
sub eax,ecx |
shr eax,3 ; Length div 8 |
push edi ebx |
mov ebx,[esp+8+4] |
mov edx,eax |
mov al,[esp+8] |
.D_LC: |
mov ecx,edx |
rep stosb |
add edi,80 |
sub edi,edx |
dec ebx |
jnz .D_LC |
pop ebx edi |
add edi,edx |
mov ecx,ebx ; ecx:=x+Length |
add ecx,esi |
and ecx,07h ; ecx and 07 |
mov ah,0ffh |
shr ah,cl ; BitMask |
jz .D_End |
not ah |
mov al,8 ; BitMask Register |
mov dx,03ceh ; Graphics Controller |
out dx,ax ; Write BitMask |
mov ecx,[esp+4] |
mov al,[esp] |
.D_LR: |
mov ah,[edi] |
mov [edi],al |
add edi,80 |
dec ecx |
jnz .D_LR |
jmp .D_End |
.D_One: |
mov ah,0ffh |
shr ah,cl ; Left BitMask |
add ebx,esi |
dec ebx |
and ebx,07h |
mov ecx,7 |
sub ecx,ebx |
mov bl,0ffh |
shl bl,cl ; Right BitMask |
and ah,bl ; Full BitMask |
mov al,8 ; BitMask Register |
out dx,ax ; Write BitMask |
mov ecx,[esp+4] |
mov al,[esp] |
.D_L: |
mov dl,[edi] ; Fill Latches |
mov [edi],al ; Write Pixel |
add edi,80 |
dec ecx |
jnz .D_L |
.D_End: |
pop edi |
add esp,4 |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
.tiled: |
mov eax,bg_address |
mov ebx,[bg_width-2] |
mov bx,word[bg_height] |
xor ecx,ecx |
xor edx,edx |
.lp1: push eax |
call vm_mike_put_image.04.direct |
pop eax |
add edx,[bg_width] |
cmp edx,[screen_width] |
jae @f |
shl edx,16 |
add ecx,edx |
shr edx,16 |
jmp .lp1 |
@@: and ecx,0x0000FFFF |
xor edx,edx |
add ecx,[bg_height] |
cmp ecx,[screen_height] |
jb .lp1 |
popad |
retn |
endf |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/norm_08.inc |
---|
0,0 → 1,747 |
;----------------------------------------------------------------------------- |
func vm_mike_draw_rect.08 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax - x start |
; ebx - y start |
; ecx - x end |
; edx - y end |
; edi - color |
;----------------------------------------------------------------------------- |
;- eax(ebx) [x start]*65536 + [x size] |
;- ebx(ecx) [y start]*65536 + [y size] |
;- ecx(edx) color 0x00RRGGBB |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
jif eax,e,ecx,.exit |
jif ebx,e,edx,.exit |
call get_cursor_rect |
mov ebp,[0x3010] |
movsx esi,word[ebp-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[ebp-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[ebp-0x3000+0] |
; add ebx,[ebp-0x3000+4] |
; add ecx,[ebp-0x3000+0] |
; add edx,[ebp-0x3000+4] |
push ecx |
mov ecx,edi |
call color_24_to_8_bits |
mov edi,ecx |
pop ecx |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
add ebp,eax |
add ebp,[lfb_address] |
.xxx: push eax ebp |
xchg eax,edi |
@@: push ebp |
call [set_bank] |
mov [ebp],al |
pop ebp |
; mov [ebp],di |
inc ebp |
inc edi |
cmp edi,ecx |
jl @b |
xchg eax,edi |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_line.08 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) [x start] shl 16 + [x end] |
; ebx(ecx) [y start] shl 16 + [y end] |
; ecx(edx) colour 0x00RRGGBB |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
call get_cursor_rect |
mov eax,ecx |
call color_24_to_8_bits |
and eax,0x01000000 |
or ecx,eax |
movsx eax,word[esp+4*7] ; x end |
cmp ax,[esp+4*7+2] ; x start |
je dl.08.vert_line |
movsx eax,word[esp+4*4] ; y end |
cmp ax,[esp+4*4+2] ; y start |
je dl.08.horz_line |
sti |
popad |
retn |
dl.08.vert_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
dec edx |
.draw: |
@@: call is_intersect_vln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
add ebp,eax |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
movzx ecx,byte[ebp] |
mov ecx,dword[palette_8_256+ecx*3] |
not ecx |
call color_24_to_8_bits |
or ecx,0x01000000 |
.dr: mov [ebp],cl |
pop ebp |
; test ecx,0x01000000 |
; jz .dr |
; mov cx,[ebp] |
; not cx |
; .dr: mov [ebp],cx |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.left],.exit |
jif eax,ge,[viewport.right],.exit |
movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
jif ebx,e,edx,.exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.top],.exit |
jif ebx,ge,[viewport.bottom],.exit |
jif ebx,ge,[viewport.top],@f |
mov ebx,[viewport.top] |
@@: jif edx,l,[viewport.bottom],@f |
mov edx,[viewport.bottom] |
dec edx |
@@: mov edi,1 |
jmp .draw |
dl.08.horz_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.top],.skip |
jif eax,ge,[rr.bottom],.skip |
jif edx,l,[rr.left],.skip |
jif ebx,ge,[rr.right],.skip |
jif ebx,ge,[rr.left],@f |
mov ebx,[rr.left] |
@@: jif edx,l,[rr.right],@f |
mov edx,[rr.right] |
dec edx |
.draw: |
@@: call is_intersect_hln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,eax |
add ebp,ebx |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
movzx ecx,byte[ebp] |
mov ecx,dword[palette_8_256+ecx*3] |
not ecx |
call color_24_to_8_bits |
or ecx,0x01000000 |
.dr: mov [ebp],cl |
pop ebp |
; test ecx,0x01000000 |
; jz .dr |
; mov cx,[ebp] |
; not cx |
; .dr: mov [ebp],cx |
inc ebp |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.top],.exit |
jif eax,ge,[viewport.bottom],.exit |
movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.left],.exit |
jif ebx,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.left],@f |
mov ebx,[viewport.left] |
@@: jif edx,l,[viewport.right],@f |
mov edx,[viewport.right] |
dec edx |
@@: mov edi,1 |
jmp .draw |
endf |
func color_24_to_8_bits |
begin |
push ecx |
cmp byte[esp+2],0 ; red=0 ? |
pop ecx |
jne .lp1 |
cmp ch,0 ; green=0 ? |
jne @f |
shr cl,2 |
add cl,192 |
ret |
@@: cmp cl,0 ; blue=0 ? |
jne .lp1 |
shr cx,8+2 |
add cl,128 |
ret |
.lp1: cmp cx,0 ; green=0 && blue=0 ? |
jne @f |
shr ecx,16+2 |
and cl,0x3F |
add cl,64 |
ret |
@@: and ecx,0x00FFFFFF |
shr ecx,6 |
shl cx,6 |
shr ecx,6 |
shl cl,6 |
shr ecx,6 |
ret |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_pixel.08 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
mov edx,[bytes_per_scanline] |
imul edx,ebx |
add edx,eax |
add edx,[lfb_address] |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif ebx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
call get_cursor_rect |
call is_intersect_pt |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: push edx |
call [set_bank] |
pop edx |
test ecx,0x01000000 |
jz .lp1 |
not byte[ebp] |
jmp .exit |
.lp1: call color_24_to_8_bits |
mov [ebp],cl |
.exit: |
sti |
popad |
retn |
.skip: |
add esi,SR |
dec edi |
jnz @b |
jmp .exit |
.forced: |
jif eax,l,[viewport.left],.exit |
jif ebx,l,[viewport.top],.exit |
jif eax,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.bottom],.exit |
push edx |
call [set_bank] |
pop edx |
test ecx,0x01000000 |
jz @f |
movzx eax,byte[ebp] |
mov ecx,dword[palette_8_256+eax*3] |
not ecx |
call color_24_to_8_bits |
mov byte[ebp],cl |
;not byte[ebp] |
jmp .exit |
@@: call color_24_to_8_bits |
mov [ebp],cl |
jmp .exit |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_get_pixel.08 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
imul ebx,[bytes_per_scanline] |
add eax,ebx |
add eax,[lfb_address] |
push eax |
call [set_bank] |
pop eax |
movzx eax,byte[ebp] |
mov eax,dword[palette_8_256+eax*3] |
and eax,0x00FFFFFF |
mov [esp+4*6],eax |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_image.08 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) pointer to image in memory - RRGGBBRRGGBB.. |
; ebx(ecx) image size [x]*65536+[y] |
; ecx(edx) image position in window [x]*65536+[y] |
; ret: eax 0 succesful, 1 overlapped |
;----------------------------------------------------------------------------- |
begin |
mov eax,ebx |
mov ebx,ecx |
mov ecx,edx |
.direct: |
pushad |
cli |
jif ebx,z,0x0000FFFF,.exit,test |
jif ebx,z,0xFFFF0000,.exit,test |
call get_cursor_rect |
mov ebp,eax |
movsx eax,word[esp+4*6+2] |
movsx ebx,word[esp+4*6] |
movsx ecx,word[esp+4*4+2] |
movsx edx,word[esp+4*4] |
lea edi,[ecx*3] |
push edi |
add ecx,eax |
add edx,ebx |
mov edi,[0x00003010] |
movsx esi,word[edi-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[edi-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[esi-0x3000+0] |
; add ebx,[esi-0x3000+4] |
; add ecx,[esi-0x3000+0] |
; add edx,[esi-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
cld |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov esi,ebx |
sub esi,[esp+4*4] |
imul esi,[esp+4*8] |
mov edi,eax |
sub edi,[esp+4*7] |
lea edi,[edi*3] |
add esi,edi |
add esi,ebp |
mov edi,[bytes_per_scanline] |
imul edi,ebx |
add edi,eax |
add edi,[lfb_address] |
.xxx: push eax esi edi eax |
@@: lodsd |
xchg eax,ecx |
call color_24_to_8_bits |
xchg eax,ecx |
push ebp edi |
call [set_bank] |
mov [ebp],al |
pop edi ebp |
inc edi |
dec esi |
inc dword[esp] |
cmp [esp],ecx |
jl @b |
pop eax edi esi eax |
add esi,[esp+4*8] |
add edi,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
add esp,4 |
sti |
popad |
xor eax,eax |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_bg.08 ;///////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
begin |
pushad |
mov eax,[viewport.left] |
mov ebx,[viewport.top] |
mov ecx,[viewport.right] |
mov edx,[viewport.bottom] |
cli |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
mov esi,[CLIP_RECTS+4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: pushad |
; jif eax,ge,[rr.left],@f |
; mov eax,[rr.left] |
; @@: jif ebx,ge,[rr.top],@f |
; mov ebx,[rr.top] |
; @@: jif ecx,l,[rr.right],@f |
; mov ecx,[rr.right] |
; @@: jif edx,l,[rr.bottom],@f |
; mov edx,[rr.bottom] |
; @@: |
mov eax,[rr.left] |
mov ebx,[rr.top] |
mov ecx,[rr.right] |
mov edx,[rr.bottom] |
dec ecx |
dec edx |
mov edi,0x007F7F7F |
call vm_mike_draw_rect.08 |
xor edi,edi |
pushad |
shl eax,16 |
mov ax,cx |
push bx |
shl ebx,16 |
pop bx |
mov ecx,0x00CCCCCC |
call vm_mike_draw_line.08 |
add ebx,0x00010001 |
call vm_mike_draw_line.08 |
popad |
pushad |
shl ebx,16 |
mov bx,dx |
push ax |
shl eax,16 |
pop ax |
mov ecx,0x00CCCCCC |
call vm_mike_draw_line.08 |
add eax,0x00010001 |
call vm_mike_draw_line.08 |
popad |
pushad |
shl eax,16 |
mov ax,cx |
mov ebx,edx |
shl ebx,16 |
mov bx,dx |
mov ecx,0x00333333 |
call vm_mike_draw_line.08 |
sub ebx,0x00010001 |
add eax,0x00010000 |
call vm_mike_draw_line.08 |
popad |
pushad |
mov eax,ecx |
shl eax,16 |
mov ax,cx |
shl ebx,16 |
mov bx,dx |
mov ecx,0x00333333 |
call vm_mike_draw_line.08 |
sub eax,0x00010001 |
add ebx,0x00010000 |
call vm_mike_draw_line.08 |
popad |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
macro sdfsdSAFSDFG { |
pushad |
cmp byte[bg_type],BGT_TILE |
je .tiled |
mov eax,[bg_width] |
cmp eax,[screen_width] |
jne @f |
mov eax,[bg_height] |
cmp eax,[screen_height] |
je .tiled |
@@: |
imul eax,[bg_width],3 |
mov [bg_bytes_per_scanline],eax |
mov eax,[viewport.left] |
mov ebx,[viewport.top] |
mov ecx,[viewport.right] |
mov edx,[viewport.bottom] |
cmp [bg_width],1 |
jne @f |
cmp [bg_height],1 |
je .color |
@@: |
cli |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
mov esi,[CLIP_RECTS+4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
add ebp,eax |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
mov [ebp],di |
pop ebp |
; mov [ebp],di |
inc ebp |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
.tiled: |
mov eax,bg_address |
mov ebx,[bg_width-2] |
mov bx,word[bg_height] |
xor ecx,ecx |
.lp1: push eax |
call vm_mike_put_image.08.direct |
pop eax |
rol ecx,16 |
add cx,word[bg_width] |
cmp cx,word[screen_width] |
jae @f |
rol ecx,16 |
jmp .lp1 |
@@: shr ecx,16 |
add ecx,[bg_height] |
cmp ecx,[screen_height] |
jb .lp1 |
popad |
retn |
.color: |
mov edi,[bg_address] |
and edi,0x00FFFFFF |
call vm_mike_draw_rect.08 |
popad |
retn |
} |
endf |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/norm_15.inc |
---|
0,0 → 1,651 |
;----------------------------------------------------------------------------- |
func vm_mike_draw_rect.15 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax - x start |
; ebx - y start |
; ecx - x end |
; edx - y end |
; edi - color |
;----------------------------------------------------------------------------- |
;- eax(ebx) [x start]*65536 + [x size] |
;- ebx(ecx) [y start]*65536 + [y size] |
;- ecx(edx) color 0x00RRGGBB |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
jif eax,e,ecx,.exit |
jif ebx,e,edx,.exit |
call get_cursor_rect |
mov ebp,[0x3010] |
movsx esi,word[ebp-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[ebp-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[ebp-0x3000+0] |
; add ebx,[ebp-0x3000+4] |
; add ecx,[ebp-0x3000+0] |
; add edx,[ebp-0x3000+4] |
push eax |
mov eax,edi |
shr eax,3 |
shl ax,3 |
shr eax,3 |
shl al,3 |
shr eax,3 |
mov di,ax |
pop eax |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*2] |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
mov [ebp],di |
pop ebp |
; mov [ebp],di |
add ebp,2 |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_line.15 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) [x start] shl 16 + [x end] |
; ebx(ecx) [y start] shl 16 + [y end] |
; ecx(edx) colour 0x00RRGGBB |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
call get_cursor_rect |
mov eax,ecx |
shr ecx,3 |
shl cx,3 |
shr ecx,3 |
shl cl,3 |
shr ecx,3 |
and eax,0x01000000 |
or ecx,eax |
movsx eax,word[esp+4*7] ; x end |
cmp ax,[esp+4*7+2] ; x start |
je dl.15.vert_line |
movsx eax,word[esp+4*4] ; y end |
cmp ax,[esp+4*4+2] ; y start |
je dl.15.horz_line |
sti |
popad |
retn |
dl.15.vert_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
dec edx |
.draw: |
@@: call is_intersect_vln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*2] |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
mov cx,[ebp] |
not cx |
.dr: mov [ebp],cx |
pop ebp |
; test ecx,0x01000000 |
; jz .dr |
; mov cx,[ebp] |
; not cx |
; .dr: mov [ebp],cx |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.left],.exit |
jif eax,ge,[viewport.right],.exit |
movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
jif ebx,e,edx,.exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.top],.exit |
jif ebx,ge,[viewport.bottom],.exit |
jif ebx,ge,[viewport.top],@f |
mov ebx,[viewport.top] |
@@: jif edx,l,[viewport.bottom],@f |
mov edx,[viewport.bottom] |
dec edx |
@@: mov edi,1 |
jmp .draw |
dl.15.horz_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.top],.skip |
jif eax,ge,[rr.bottom],.skip |
jif edx,l,[rr.left],.skip |
jif ebx,ge,[rr.right],.skip |
jif ebx,ge,[rr.left],@f |
mov ebx,[rr.left] |
@@: jif edx,l,[rr.right],@f |
mov edx,[rr.right] |
dec edx |
.draw: |
@@: call is_intersect_hln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,eax |
lea ebp,[ebp+ebx*2] |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
mov cx,[ebp] |
not cx |
.dr: mov [ebp],cx |
pop ebp |
; test ecx,0x01000000 |
; jz .dr |
; mov cx,[ebp] |
; not cx |
; .dr: mov [ebp],cx |
add ebp,2 |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.top],.exit |
jif eax,ge,[viewport.bottom],.exit |
movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.left],.exit |
jif ebx,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.left],@f |
mov ebx,[viewport.left] |
@@: jif edx,l,[viewport.right],@f |
mov edx,[viewport.right] |
dec edx |
@@: mov edi,1 |
jmp .draw |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_pixel.15 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
mov edx,[bytes_per_scanline] |
imul edx,ebx |
lea edx,[edx+eax*2] |
add edx,[lfb_address] |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif ebx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
call get_cursor_rect |
call is_intersect_pt |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: push edx |
call [set_bank] |
pop edx |
test ecx,0x01000000 |
jz .lp1 |
not word[ebp] |
jmp .exit |
.lp1: shr ecx,3 |
shl cx,3 |
shr ecx,3 |
shl cl,3 |
shr ecx,3 |
mov [ebp],cx |
.exit: |
sti |
popad |
retn |
.skip: |
add esi,SR |
dec edi |
jnz @b |
jmp .exit |
.forced: |
jif eax,l,[viewport.left],.exit |
jif ebx,l,[viewport.top],.exit |
jif eax,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.bottom],.exit |
push edx |
call [set_bank] |
pop edx |
test ecx,0x01000000 |
jz @f |
not word[ebp] |
jmp .exit |
@@: shr ecx,3 |
shl cx,3 |
shr ecx,3 |
shl cl,3 |
shr ecx,3 |
mov [ebp],cx |
jmp .exit |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_get_pixel.15 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
imul ebx,[bytes_per_scanline] |
shl eax,1 |
add eax,ebx |
add eax,[lfb_address] |
push eax |
call [set_bank] |
pop eax |
movzx eax,word[ebp] |
shl eax,3 |
shr al,3 |
shl eax,3 |
shr ax,3 |
shl eax,3 |
and eax,0x00FFFFFF |
mov [esp+4*6],eax |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_image.15 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) pointer to image in memory - RRGGBBRRGGBB.. |
; ebx(ecx) image size [x]*65536+[y] |
; ecx(edx) image position in window [x]*65536+[y] |
; ret: eax 0 succesful, 1 overlapped |
;----------------------------------------------------------------------------- |
begin |
mov eax,ebx |
mov ebx,ecx |
mov ecx,edx |
.direct: |
pushad |
cli |
jif ebx,z,0x0000FFFF,.exit,test |
jif ebx,z,0xFFFF0000,.exit,test |
call get_cursor_rect |
mov ebp,eax |
movsx eax,word[esp+4*6+2] |
movsx ebx,word[esp+4*6] |
movsx ecx,word[esp+4*4+2] |
movsx edx,word[esp+4*4] |
lea edi,[ecx*3] |
push edi |
add ecx,eax |
add edx,ebx |
mov edi,[0x00003010] |
movsx esi,word[edi-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[edi-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[esi-0x3000+0] |
; add ebx,[esi-0x3000+4] |
; add ecx,[esi-0x3000+0] |
; add edx,[esi-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
cld |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov esi,ebx |
sub esi,[esp+4*4] |
imul esi,[esp+4*8] |
mov edi,eax |
sub edi,[esp+4*7] |
lea edi,[edi*3] |
add esi,edi |
add esi,ebp |
mov edi,[bytes_per_scanline] |
imul edi,ebx |
lea edi,[edi+eax*2] |
add edi,[lfb_address] |
.xxx: push eax esi edi eax |
@@: lodsd |
shr eax,3 |
shl ax,3 |
shr eax,3 |
shl al,3 |
shr eax,3 |
push ebp edi |
call [set_bank] |
mov [ebp],ax |
pop edi ebp |
add edi,2 |
dec esi |
inc dword[esp] |
cmp [esp],ecx |
jl @b |
pop eax edi esi eax |
add esi,[esp+4*8] |
add edi,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
add esp,4 |
sti |
popad |
xor eax,eax |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_bg.15 ;///////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
begin |
pushad |
cmp byte[bg_type],BGT_TILE |
je .tiled |
mov eax,[bg_width] |
cmp eax,[screen_width] |
jne @f |
mov eax,[bg_height] |
cmp eax,[screen_height] |
je .tiled |
@@: |
imul eax,[bg_width],3 |
mov [bg_bytes_per_scanline],eax |
mov eax,[viewport.left] |
mov ebx,[viewport.top] |
mov ecx,[viewport.right] |
mov edx,[viewport.bottom] |
cmp [bg_width],1 |
jne @f |
cmp [bg_height],1 |
je .color |
@@: |
cli |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
mov esi,[CLIP_RECTS+4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: ;call is_intersect_rc |
;jc .put |
;cmp [mouse_invisible],0 |
;jne .put |
;call [SF.draw_mouse_under] |
;mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*2] |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
push eax edx |
mul [bg_width] |
div [screen_width] |
lea edi,[eax*3] |
mov eax,ebx |
mul [bg_height] |
div [screen_height] |
mul [bg_bytes_per_scanline] |
add edi,eax |
add edi,bg_address |
mov eax,[edi] |
shr eax,3 |
shl ax,3 |
shr eax,3 |
shl al,3 |
shr eax,3 |
mov [ebp],ax |
pop edx eax |
pop ebp |
inc ebp |
inc ebp |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
.tiled: |
mov eax,bg_address |
mov ebx,[bg_width-2] |
mov bx,word[bg_height] |
xor ecx,ecx |
.lp1: push eax |
call vm_mike_put_image.15.direct |
pop eax |
rol ecx,16 |
add cx,word[bg_width] |
cmp cx,word[screen_width] |
jae @f |
rol ecx,16 |
jmp .lp1 |
@@: shr ecx,16 |
add ecx,[bg_height] |
cmp ecx,[screen_height] |
jb .lp1 |
popad |
retn |
.color: |
mov edi,[bg_address] |
and edi,0x00FFFFFF |
call vm_mike_draw_rect.15 |
popad |
retn |
endf |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/norm_16.inc |
---|
0,0 → 1,646 |
;----------------------------------------------------------------------------- |
func vm_mike_draw_rect.16 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax - x start |
; ebx - y start |
; ecx - x end |
; edx - y end |
; edi - color |
;----------------------------------------------------------------------------- |
;- eax(ebx) [x start]*65536 + [x size] |
;- ebx(ecx) [y start]*65536 + [y size] |
;- ecx(edx) color 0x00RRGGBB |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
jif eax,e,ecx,.exit |
jif ebx,e,edx,.exit |
call get_cursor_rect |
mov ebp,[0x3010] |
movsx esi,word[ebp-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[ebp-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[ebp-0x3000+0] |
; add ebx,[ebp-0x3000+4] |
; add ecx,[ebp-0x3000+0] |
; add edx,[ebp-0x3000+4] |
push eax |
mov eax,edi |
shr eax,3 |
shl ax,3 |
shr eax,2 |
shl al,2 |
shr eax,3 |
mov di,ax |
pop eax |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*2] |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
mov [ebp],di |
pop ebp |
; mov [ebp],di |
add ebp,2 |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_line.16 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) [x start] shl 16 + [x end] |
; ebx(ecx) [y start] shl 16 + [y end] |
; ecx(edx) colour 0x00RRGGBB |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
call get_cursor_rect |
mov eax,ecx |
shr ecx,3 |
shl cx,3 |
shr ecx,2 |
shl cl,2 |
shr ecx,3 |
and eax,0x01000000 |
or ecx,eax |
movsx eax,word[esp+4*7] ; x end |
cmp ax,[esp+4*7+2] ; x start |
je dl.16.vert_line |
movsx eax,word[esp+4*4] ; y end |
cmp ax,[esp+4*4+2] ; y start |
je dl.16.horz_line |
sti |
popad |
retn |
dl.16.vert_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
dec edx |
.draw: |
@@: call is_intersect_vln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*2] |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
mov cx,[ebp] |
not cx |
.dr: mov [ebp],cx |
pop ebp |
; mov [ebp],cx |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.left],.exit |
jif eax,ge,[viewport.right],.exit |
movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
jif ebx,e,edx,.exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.top],.exit |
jif ebx,ge,[viewport.bottom],.exit |
jif ebx,ge,[viewport.top],@f |
mov ebx,[viewport.top] |
@@: jif edx,l,[viewport.bottom],@f |
mov edx,[viewport.bottom] |
dec edx |
@@: mov edi,1 |
jmp .draw |
dl.16.horz_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.top],.skip |
jif eax,ge,[rr.bottom],.skip |
jif edx,l,[rr.left],.skip |
jif ebx,ge,[rr.right],.skip |
jif ebx,ge,[rr.left],@f |
mov ebx,[rr.left] |
@@: jif edx,l,[rr.right],@f |
mov edx,[rr.right] |
dec edx |
.draw: |
@@: call is_intersect_hln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,eax |
lea ebp,[ebp+ebx*2] |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
mov cx,[ebp] |
not cx |
.dr: mov [ebp],cx |
pop ebp |
; mov [ebp],cx |
add ebp,2 |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.top],.exit |
jif eax,ge,[viewport.bottom],.exit |
movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.left],.exit |
jif ebx,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.left],@f |
mov ebx,[viewport.left] |
@@: jif edx,l,[viewport.right],@f |
mov edx,[viewport.right] |
dec edx |
@@: mov edi,1 |
jmp .draw |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_pixel.16 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
mov edx,[bytes_per_scanline] |
imul edx,ebx |
lea edx,[edx+eax*2] |
add edx,[lfb_address] |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif ebx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
call get_cursor_rect |
call is_intersect_pt |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: push edx |
call [set_bank] |
pop edx |
test ecx,0x01000000 |
jz .lp1 |
not word[ebp] |
jmp .exit |
.lp1: shr ecx,3 |
shl cx,3 |
shr ecx,2 |
shl cl,2 |
shr ecx,3 |
mov [ebp],cx |
.exit: |
sti |
popad |
retn |
.skip: |
add esi,SR |
dec edi |
jnz @b |
jmp .exit |
.forced: |
jif eax,l,[viewport.left],.exit |
jif ebx,l,[viewport.top],.exit |
jif eax,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.bottom],.exit |
test ecx,0x01000000 |
jz @f |
push edx |
call [set_bank] |
pop edx |
not word[ebp] |
jmp .exit |
@@: shr ecx,3 |
shl cx,3 |
shr ecx,2 |
shl cl,2 |
shr ecx,3 |
push edx |
call [set_bank] |
pop edx |
mov [ebp],cx |
jmp .exit |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_get_pixel.16 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
imul ebx,[bytes_per_scanline] |
shl eax,1 |
add eax,ebx |
add eax,[lfb_address] |
push eax |
call [set_bank] |
pop eax |
movzx eax,word[ebp] |
shl eax,3 |
shr al,2 |
shl eax,2 |
shr ax,3 |
shl eax,3 |
and eax,0x00FFFFFF |
mov [esp+4*6],eax |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_image.16 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) pointer to image in memory - RRGGBBRRGGBB.. |
; ebx(ecx) image size [x]*65536+[y] |
; ecx(edx) image position in window [x]*65536+[y] |
; ret: eax 0 succesful, 1 overlapped |
;----------------------------------------------------------------------------- |
begin |
mov eax,ebx |
mov ebx,ecx |
mov ecx,edx |
.direct: |
pushad |
cli |
jif ebx,z,0x0000FFFF,.exit,test |
jif ebx,z,0xFFFF0000,.exit,test |
call get_cursor_rect |
mov ebp,eax |
movsx eax,word[esp+4*6+2] |
movsx ebx,word[esp+4*6] |
movsx ecx,word[esp+4*4+2] |
movsx edx,word[esp+4*4] |
lea edi,[ecx*3] |
push edi |
add ecx,eax |
add edx,ebx |
mov edi,[0x00003010] |
movsx esi,word[edi-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[edi-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[esi-0x3000+0] |
; add ebx,[esi-0x3000+4] |
; add ecx,[esi-0x3000+0] |
; add edx,[esi-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
cld |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov esi,ebx |
sub esi,[esp+4*4] |
imul esi,[esp+4*8] |
mov edi,eax |
sub edi,[esp+4*7] |
lea edi,[edi*3] |
add esi,edi |
add esi,ebp |
mov edi,[bytes_per_scanline] |
imul edi,ebx |
lea edi,[edi+eax*2] |
add edi,[lfb_address] |
.xxx: push eax esi edi eax |
@@: lodsd |
shr eax,3 |
shl ax,3 |
shr eax,2 |
shl al,2 |
shr eax,3 |
push ebp edi |
call [set_bank] |
mov [ebp],ax |
pop edi ebp |
add edi,2 |
dec esi |
inc dword[esp] |
cmp [esp],ecx |
jl @b |
pop eax edi esi eax |
add esi,[esp+4*8] |
add edi,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
add esp,4 |
sti |
popad |
xor eax,eax |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_bg.16 ;///////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
begin |
pushad |
cmp byte[bg_type],BGT_TILE |
je .tiled |
mov eax,[bg_width] |
cmp eax,[screen_width] |
jne @f |
mov eax,[bg_height] |
cmp eax,[screen_height] |
je .tiled |
@@: |
imul eax,[bg_width],3 |
mov [bg_bytes_per_scanline],eax |
mov eax,[viewport.left] |
mov ebx,[viewport.top] |
mov ecx,[viewport.right] |
mov edx,[viewport.bottom] |
cmp [bg_width],1 |
jne @f |
cmp [bg_height],1 |
je .color |
@@: |
cli |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
mov esi,[CLIP_RECTS+4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: ;call is_intersect_rc |
;jc .put |
;cmp [mouse_invisible],0 |
;jne .put |
;call [SF.draw_mouse_under] |
;mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*2] |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
push eax edx |
mul [bg_width] |
div [screen_width] |
lea edi,[eax*3] |
mov eax,ebx |
mul [bg_height] |
div [screen_height] |
mul [bg_bytes_per_scanline] |
add edi,eax |
add edi,bg_address |
mov eax,[edi] |
shr eax,3 |
shl ax,3 |
shr eax,2 |
shl al,2 |
shr eax,3 |
mov [ebp],ax |
pop edx eax |
pop ebp |
inc ebp |
inc ebp |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
.tiled: |
mov eax,bg_address |
mov ebx,[bg_width-2] |
mov bx,word[bg_height] |
xor ecx,ecx |
.lp1: push eax |
call vm_mike_put_image.16.direct |
pop eax |
rol ecx,16 |
add cx,word[bg_width] |
cmp cx,word[screen_width] |
jae @f |
rol ecx,16 |
jmp .lp1 |
@@: shr ecx,16 |
add ecx,[bg_height] |
cmp ecx,[screen_height] |
jb .lp1 |
popad |
retn |
.color: |
mov edi,[bg_address] |
and edi,0x00FFFFFF |
call vm_mike_draw_rect.16 |
popad |
retn |
endf |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/norm_24.inc |
---|
0,0 → 1,602 |
;----------------------------------------------------------------------------- |
func vm_mike_draw_rect.24 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax - x start |
; ebx - y start |
; ecx - x end |
; edx - y end |
; edi - color |
;----------------------------------------------------------------------------- |
;- eax(ebx) [x start]*65536 + [x size] |
;- ebx(ecx) [y start]*65536 + [y size] |
;- ecx(edx) color 0x00RRGGBB |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
jif eax,e,ecx,.exit |
jif ebx,e,edx,.exit |
call get_cursor_rect |
mov ebp,[0x3010] |
movsx esi,word[ebp-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[ebp-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[ebp-0x3000+0] |
; add ebx,[ebp-0x3000+4] |
; add ecx,[ebp-0x3000+0] |
; add edx,[ebp-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
push eax |
lea eax,[eax*3] |
add ebp,eax |
pop eax |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push eax |
mov eax,edi |
mov [ebp],ax |
shr eax,16 |
mov [ebp+2],al |
pop eax |
add ebp,3 |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_line.24 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) [x start] shl 16 + [x end] |
; ebx(ecx) [y start] shl 16 + [y end] |
; ecx(edx) colour 0x00RRGGBB |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
call get_cursor_rect |
movsx eax,word[esp+4*7] ; x end |
cmp ax,[esp+4*7+2] ; x start |
je dl.24.vert_line |
movsx eax,word[esp+4*4] ; y end |
cmp ax,[esp+4*4+2] ; y start |
je dl.24.horz_line |
sti |
popad |
retn |
dl.24.vert_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
dec edx |
.draw: |
@@: call is_intersect_vln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
push eax |
lea eax,[eax*3] |
add ebp,eax |
pop eax |
add ebp,[lfb_address] |
@@: test ecx,0x01000000 |
jz .dr |
mov ecx,[ebp] |
not ecx |
or ecx,0x01000000 |
.dr: mov [ebp],cx |
ror ecx,8 |
mov [ebp+2],ch |
rol ecx,8 |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.left],.exit |
jif eax,ge,[viewport.right],.exit |
movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
jif ebx,e,edx,.exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.top],.exit |
jif ebx,ge,[viewport.bottom],.exit |
jif ebx,ge,[viewport.top],@f |
mov ebx,[viewport.top] |
@@: jif edx,l,[viewport.bottom],@f |
mov edx,[viewport.bottom] |
dec edx |
@@: mov edi,1 |
jmp .draw |
dl.24.horz_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.top],.skip |
jif eax,ge,[rr.bottom],.skip |
jif edx,l,[rr.left],.skip |
jif ebx,ge,[rr.right],.skip |
jif ebx,ge,[rr.left],@f |
mov ebx,[rr.left] |
@@: jif edx,l,[rr.right],@f |
mov edx,[rr.right] |
dec edx |
.draw: |
@@: call is_intersect_hln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,eax |
push eax |
lea eax,[ebx*3] |
add ebp,eax |
pop eax |
add ebp,[lfb_address] |
@@: test ecx,0x01000000 |
jz .dr |
mov ecx,[ebp] |
not ecx |
or ecx,0x01000000 |
.dr: mov [ebp],cx |
ror ecx,8 |
mov [ebp+2],ch |
rol ecx,8 |
add ebp,3 |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.top],.exit |
jif eax,ge,[viewport.bottom],.exit |
movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.left],.exit |
jif ebx,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.left],@f |
mov ebx,[viewport.left] |
@@: jif edx,l,[viewport.right],@f |
mov edx,[viewport.right] |
dec edx |
@@: mov edi,1 |
jmp .draw |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_pixel.24 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
mov edx,[bytes_per_scanline] |
imul edx,ebx |
add edx,eax ; lea esi,[eax*3] |
lea edx,[edx+eax*2] ; add edx,esi |
add edx,[lfb_address] |
test ecx,0x01000000 |
jz @f |
mov ecx,[edx] |
not ecx |
@@: test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif ebx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
call get_cursor_rect |
call is_intersect_pt |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov [edx],cx |
shr ecx,16 |
mov [edx+2],cl |
.exit: |
sti |
popad |
retn |
.skip: |
add esi,SR |
dec edi |
jnz @b |
jmp .exit |
.forced: |
jif eax,l,[viewport.left],.exit |
jif ebx,l,[viewport.top],.exit |
jif eax,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.bottom],.exit |
mov [edx],cx |
shr ecx,16 |
mov [edx+2],cl |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_get_pixel.24 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
imul ebx,[bytes_per_scanline] |
lea eax,[eax*3] |
add eax,ebx |
add eax,[lfb_address] |
mov eax,[eax] |
and eax,0x00FFFFFF |
mov [esp+4*6],eax |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_image.24 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) pointer to image in memory - RRGGBBRRGGBB.. |
; ebx(ecx) image size [x]*65536+[y] |
; ecx(edx) image position in window [x]*65536+[y] |
; ret: eax 0 succesful, 1 overlapped |
;----------------------------------------------------------------------------- |
begin |
mov eax,ebx |
mov ebx,ecx |
mov ecx,edx |
.direct: |
pushad |
cli |
jif ebx,z,0x0000FFFF,.exit,test |
jif ebx,z,0xFFFF0000,.exit,test |
call get_cursor_rect |
mov ebp,eax |
movsx eax,word[esp+4*6+2] |
movsx ebx,word[esp+4*6] |
movsx ecx,word[esp+4*4+2] |
movsx edx,word[esp+4*4] |
lea edi,[ecx*3] |
push edi |
add ecx,eax |
add edx,ebx |
mov edi,[0x00003010] |
movsx esi,word[edi-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[edi-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[edi-0x3000+0] |
; add ebx,[edi-0x3000+4] |
; add ecx,[edi-0x3000+0] |
; add edx,[edi-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
cld |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov esi,ebx |
sub esi,[esp+4*4] |
imul esi,[esp+4*8] |
mov edi,eax |
sub edi,[esp+4*7] |
lea edi,[edi*3] |
add esi,edi |
add esi,ebp |
mov edi,[bytes_per_scanline] |
imul edi,ebx |
push eax |
lea eax,[eax*3] |
add edi,eax |
pop eax |
add edi,[lfb_address] |
.xxx: push eax esi edi eax |
@@: ;movsd |
;dec esi |
;dec edi |
movsw |
movsb |
inc dword[esp] |
cmp [esp],ecx |
jl @b |
pop eax edi esi eax |
add esi,[esp+4*8] |
add edi,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
add esp,4 |
sti |
popad |
xor eax,eax |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_bg.24 ;///////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
begin |
pushad |
cmp byte[bg_type],BGT_TILE |
je .tiled |
mov eax,[bg_width] |
cmp eax,[screen_width] |
jne @f |
mov eax,[bg_height] |
cmp eax,[screen_height] |
je .tiled |
@@: |
imul eax,[bg_width],3 |
mov [bg_bytes_per_scanline],eax |
mov eax,[viewport.left] |
mov ebx,[viewport.top] |
mov ecx,[viewport.right] |
mov edx,[viewport.bottom] |
cmp [bg_width],1 |
jne @f |
cmp [bg_height],1 |
je .color |
@@: |
cli |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
mov esi,[CLIP_RECTS+4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: ;call is_intersect_rc |
;jc .put |
;cmp [mouse_invisible],0 |
;jne .put |
;call [SF.draw_mouse_under] |
;mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
push eax |
lea eax,[eax*3] |
add ebp,eax |
pop eax |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
push eax edx |
mul [bg_width] |
div [screen_width] |
lea edi,[eax*3] |
mov eax,ebx |
mul [bg_height] |
div [screen_height] |
mul [bg_bytes_per_scanline] |
add edi,eax |
add edi,bg_address |
mov eax,[edi] |
mov [ebp],eax |
pop edx eax |
pop ebp |
add ebp,3 |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
.tiled: |
mov eax,bg_address |
mov ebx,[bg_width-2] |
mov bx,word[bg_height] |
xor ecx,ecx |
.lp1: push eax |
call vm_mike_put_image.24.direct |
pop eax |
rol ecx,16 |
add cx,word[bg_width] |
cmp cx,word[screen_width] |
jae @f |
rol ecx,16 |
jmp .lp1 |
@@: shr ecx,16 |
add ecx,[bg_height] |
cmp ecx,[screen_height] |
jb .lp1 |
popad |
retn |
.color: |
mov edi,[bg_address] |
and edi,0x00FFFFFF |
call vm_mike_draw_rect.24 |
popad |
retn |
endf |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/norm_32.inc |
---|
0,0 → 1,617 |
;----------------------------------------------------------------------------- |
func vm_mike_draw_rect.32 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax - x start |
; ebx - y start |
; ecx - x end |
; edx - y end |
; edi - color |
;----------------------------------------------------------------------------- |
;- eax(ebx) [x start]*65536 + [x size] |
;- ebx(ecx) [y start]*65536 + [y size] |
;- ecx(edx) color 0x00RRGGBB |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
jif eax,e,ecx,.exit |
jif ebx,e,edx,.exit |
call get_cursor_rect |
mov ebp,[0x3010] |
movsx esi,word[ebp-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[ebp-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[ebp-0x3000+0] |
; add ebx,[ebp-0x3000+4] |
; add ecx,[ebp-0x3000+0] |
; add edx,[ebp-0x3000+4] |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*4] |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
mov [ebp],edi |
pop ebp |
; mov [ebp],edi |
add ebp,4 |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_line.32 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) [x start] shl 16 + [x end] |
; ebx(ecx) [y start] shl 16 + [y end] |
; ecx(edx) colour 0x00RRGGBB |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
call get_cursor_rect |
movsx eax,word[esp+4*7] ; x end |
cmp ax,[esp+4*7+2] ; x start |
je dl.32.vert_line |
movsx eax,word[esp+4*4] ; y end |
cmp ax,[esp+4*4+2] ; y start |
je dl.32.horz_line |
sti |
popad |
retn |
dl.32.vert_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
dec edx |
.draw: |
@@: call is_intersect_vln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*4] |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
mov ecx,[ebp] |
not ecx |
or ecx,0x01000000 |
.dr: mov [ebp],ecx |
pop ebp |
; test ecx,0x01000000 |
; jz .dr |
; mov ecx,[ebp] |
; not ecx |
; or ecx,0x01000000 |
; .dr: mov [ebp],ecx |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.left],.exit |
jif eax,ge,[viewport.right],.exit |
movsx ebx,word[esp+4*4+2] ; y start |
movsx edx,word[esp+4*4] ; y end |
jif ebx,e,edx,.exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.top],.exit |
jif ebx,ge,[viewport.bottom],.exit |
jif ebx,ge,[viewport.top],@f |
mov ebx,[viewport.top] |
@@: jif edx,l,[viewport.bottom],@f |
mov edx,[viewport.bottom] |
dec edx |
@@: mov edi,1 |
jmp .draw |
dl.32.horz_line: |
test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
.nx: movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif eax,l,[rr.top],.skip |
jif eax,ge,[rr.bottom],.skip |
jif edx,l,[rr.left],.skip |
jif ebx,ge,[rr.right],.skip |
jif ebx,ge,[rr.left],@f |
mov ebx,[rr.left] |
@@: jif edx,l,[rr.right],@f |
mov edx,[rr.right] |
dec edx |
.draw: |
@@: call is_intersect_hln |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,eax |
lea ebp,[ebp+ebx*4] |
add ebp,[lfb_address] |
@@: push ebp |
call [set_bank] |
test ecx,0x01000000 |
jz .dr |
mov ecx,[ebp] |
not ecx |
or ecx,0x01000000 |
.dr: mov [ebp],ecx |
pop ebp |
; test ecx,0x01000000 |
; jz .dr |
; mov ecx,[ebp] |
; not ecx |
; or ecx,0x01000000 |
; .dr: mov [ebp],ecx |
add ebp,4 |
inc ebx |
cmp ebx,edx |
jle @b |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
sti |
popad |
retn |
.forced: |
jif eax,l,[viewport.top],.exit |
jif eax,ge,[viewport.bottom],.exit |
movsx ebx,word[esp+4*7+2] ; x start |
movsx edx,word[esp+4*7] ; x end |
cmp ebx,edx |
je .exit |
jl @f |
xchg ebx,edx |
@@: jif edx,l,[viewport.left],.exit |
jif ebx,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.left],@f |
mov ebx,[viewport.left] |
@@: jif edx,l,[viewport.right],@f |
mov edx,[viewport.right] |
dec edx |
@@: mov edi,1 |
jmp .draw |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_pixel.32 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
; ecx = ?? RR GG BB ; 0x01000000 negation |
; edi = 0x00000001 force |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
mov edx,[bytes_per_scanline] |
imul edx,ebx |
lea edx,[edx+eax*4] |
add edx,[lfb_address] |
; test ecx,0x01000000 |
; jz @f |
; mov ecx,[edx] |
; not ecx |
@@: test edi,1 |
jnz .forced |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
@@: jif eax,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif ebx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
call get_cursor_rect |
call is_intersect_pt |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: push edx |
call [set_bank] |
pop edx |
test ecx,0x01000000 |
jz .lp1 |
not dword[ebp] |
jmp .exit |
.lp1: mov [ebp],ecx |
.exit: |
sti |
popad |
retn |
.skip: |
add esi,SR |
dec edi |
jnz @b |
jmp .exit |
.forced: |
jif eax,l,[viewport.left],.exit |
jif ebx,l,[viewport.top],.exit |
jif eax,ge,[viewport.right],.exit |
jif ebx,ge,[viewport.bottom],.exit |
push edx |
call [set_bank] |
pop edx |
test ecx,0x01000000 |
jz .lp2 |
not dword[ebp] |
jmp .exit |
.lp2: mov [ebp],ecx |
jmp .exit |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_get_pixel.32 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax = x coordinate |
; ebx = y coordinate |
;----------------------------------------------------------------------------- |
begin |
pushad |
cli |
imul ebx,[bytes_per_scanline] |
shl eax,2 |
add eax,ebx |
add eax,[lfb_address] |
push eax |
call [set_bank] |
pop eax |
mov eax,[ebp] |
and eax,0x00FFFFFF |
mov [esp+4*6],eax |
sti |
popad |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_put_image.32 ;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; eax(ebx) pointer to image in memory - RRGGBBRRGGBB.. |
; ebx(ecx) image size [x]*65536+[y] |
; ecx(edx) image position in window [x]*65536+[y] |
; ret: eax 0 succesful, 1 overlapped |
;----------------------------------------------------------------------------- |
begin |
mov eax,ebx |
mov ebx,ecx |
mov ecx,edx |
.direct: |
pushad |
cli |
jif ebx,z,0x0000FFFF,.exit,test |
jif ebx,z,0xFFFF0000,.exit,test |
call get_cursor_rect |
mov ebp,eax |
movsx eax,word[esp+4*6+2] |
movsx ebx,word[esp+4*6] |
movsx ecx,word[esp+4*4+2] |
movsx edx,word[esp+4*4] |
lea edi,[ecx*3] |
push edi |
add ecx,eax |
add edx,ebx |
mov edi,[0x00003010] |
movsx esi,word[edi-0x3000+0] |
add eax,esi |
add ecx,esi |
movsx esi,word[edi-0x3000+4] |
add ebx,esi |
add edx,esi |
; add eax,[esi-0x3000+0] |
; add ebx,[esi-0x3000+4] |
; add ecx,[esi-0x3000+0] |
; add edx,[esi-0x3000+4] |
; cmp eax,640 |
; jb @f |
; SHFLOW '%x %x %x %x',eax,ebx,ecx,edx |
; @@: |
mov esi,[0x00003000] |
mov esi,[CLIP_RECTS+esi*4] |
mov edi,[esi] |
or edi,edi |
jz .exit |
add esi,4 |
cld |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: call is_intersect_rc |
jc .put |
cmp [mouse_invisible],0 |
jne .put |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
.put: mov esi,ebx |
sub esi,[esp+4*4] |
imul esi,[esp+4*8] |
mov edi,eax |
sub edi,[esp+4*7] |
lea edi,[edi*3] |
add esi,edi |
add esi,ebp |
mov edi,[bytes_per_scanline] |
imul edi,ebx |
lea edi,[edi+eax*4] |
add edi,[lfb_address] |
.xxx: push eax esi edi eax |
@@: lodsd |
push ebp edi |
call [set_bank] |
mov [ebp],eax |
pop edi ebp |
add edi,4 |
dec esi |
inc dword[esp] |
cmp [esp],ecx |
jl @b |
pop eax edi esi eax |
add esi,[esp+4*8] |
add edi,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec edi |
jnz .nx |
.exit: |
add esp,4 |
sti |
popad |
xor eax,eax |
retn |
endf |
;----------------------------------------------------------------------------- |
func vm_mike_draw_bg.32 ;///////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
begin |
pushad |
cmp byte[bg_type],BGT_TILE |
je .tiled |
mov eax,[bg_width] |
cmp eax,[screen_width] |
jne @f |
mov eax,[bg_height] |
cmp eax,[screen_height] |
je .tiled |
@@: |
imul eax,[bg_width],3 |
mov [bg_bytes_per_scanline],eax |
mov eax,[viewport.left] |
mov ebx,[viewport.top] |
mov ecx,[viewport.right] |
mov edx,[viewport.bottom] |
cmp [bg_width],1 |
jne @f |
cmp [bg_height],1 |
je .color |
@@: |
cli |
call [SF.draw_mouse_under] |
mov [mouse_invisible],1 |
mov esi,[CLIP_RECTS+4] |
mov ebp,[esi] |
or ebp,ebp |
jz .exit |
add esi,4 |
.nx: jif ecx,l,[rr.left],.skip |
jif eax,ge,[rr.right],.skip |
jif edx,l,[rr.top],.skip |
jif ebx,ge,[rr.bottom],.skip |
pushad |
jif eax,ge,[rr.left],@f |
mov eax,[rr.left] |
@@: jif ebx,ge,[rr.top],@f |
mov ebx,[rr.top] |
@@: jif ecx,l,[rr.right],@f |
mov ecx,[rr.right] |
@@: jif edx,l,[rr.bottom],@f |
mov edx,[rr.bottom] |
@@: ;call is_intersect_rc |
;jc .put |
;cmp [mouse_invisible],0 |
;jne .put |
;call [SF.draw_mouse_under] |
;mov [mouse_invisible],1 |
.put: mov ebp,[bytes_per_scanline] |
imul ebp,ebx |
lea ebp,[ebp+eax*4] |
add ebp,[lfb_address] |
.xxx: push eax ebp |
@@: push ebp |
call [set_bank] |
push eax edx |
mul [bg_width] |
div [screen_width] |
lea edi,[eax*3] |
mov eax,ebx |
mul [bg_height] |
div [screen_height] |
mul [bg_bytes_per_scanline] |
add edi,eax |
add edi,bg_address |
mov eax,[edi] |
mov [ebp],eax |
pop edx eax |
pop ebp |
add ebp,4 |
inc eax |
cmp eax,ecx |
jl @b |
pop ebp eax |
add ebp,[bytes_per_scanline] |
inc ebx |
cmp ebx,edx |
jl .xxx |
popad |
.skip: |
add esi,SR |
dec ebp |
jnz .nx |
.exit: |
sti |
popad |
retn |
.tiled: |
mov eax,bg_address |
mov ebx,[bg_width-2] |
mov bx,word[bg_height] |
xor ecx,ecx |
.lp1: push eax |
call vm_mike_put_image.32.direct |
pop eax |
rol ecx,16 |
add cx,word[bg_width] |
cmp cx,word[screen_width] |
jae @f |
rol ecx,16 |
jmp .lp1 |
@@: shr ecx,16 |
add ecx,[bg_height] |
cmp ecx,[screen_height] |
jb .lp1 |
popad |
retn |
.color: |
mov edi,[bg_address] |
and edi,0x00FFFFFF |
call vm_mike_draw_rect.32 |
popad |
retn |
endf |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/normal.asm |
---|
0,0 → 1,643 |
;----------------------------------------------------------------------------- |
;///// PART OF ATi RADEON 9000 DRIVER //////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; Copyright (c) 2004, mike.dld |
; Using BeOS driver - Copyright (c) 2002, Thomas Kurschel |
;----------------------------------------------------------------------------- |
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
; DEALINGS IN THE SOFTWARE. |
;----------------------------------------------------------------------------- |
DRIVER_CODE_START: |
;----------------------------------------------------------------------------- |
include 'normal.inc' |
include 'clipping.asm' |
;----------------------------------------------------------------------------- |
struct graph_funcs |
draw_line dd ? |
disable_mouse dd ? |
draw_pointer dd ? |
draw_mouse_under dd ? |
drawbar dd ? |
putpixel dd ? |
getpixel dd ? |
sys_putimage dd ? |
drawbackground dd ? |
calculatescreen dd ? |
setscreen dd ? |
ends |
SF graph_funcs |
call_cnt dd 0 |
viewport RECT |
set_bank dd set_bank1 |
setbnk dd set_bank0,set_bank1,set_s3_bank,set_bank3 |
virtual at esi |
rr RECT |
end virtual |
virtual at 0x00010008 |
GF graph_funcs |
end virtual |
;----------------------------------------------------------------------------- |
CLIP_RECTS = 0x00720000 ; 0x00780000 |
bg_address = 0x300000 |
;label bg_bytes_per_scanline dword at 0x600000-16;0x460000-16 |
;label bg_type dword at 0x600000-12;0x460000-12 |
;label bg_width dword at 0x600000-8;0x460000-8 |
;label bg_height dword at 0x600000-4;0x460000-4 |
label bg_bytes_per_scanline dword at 0x460000-16 |
label bg_type dword at 0x460000-12 |
label bg_width dword at 0x460000-8 |
label bg_height dword at 0x460000-4 |
label lfb_address dword at 0x0000FE80 |
label mouse_invisible dword at 0x0000F204 |
label screen_width dword at 0x0000FE00 |
label screen_height dword at 0x0000FE04 |
label bytes_per_scanline dword at 0x0000FE08 |
BGT_TILE = 1 |
BGT_STRETCH = 2 |
;----------------------------------------------------------------------------- |
CRTC_INDX equ 3D4h |
func vm_mike_init |
begin |
; jif dword[mdrvm],e,0,.exit |
mov eax,[0x00010004] |
jif eax,e,'ENUE',.exit |
jif [call_cnt],a,0,.exit.2 |
add eax, 0x00010000 |
mov [systlb],eax |
; SHFLOW 'System funcs table offset: 0x%x',eax |
;-------------------------------------- |
mov esi,0x00010008 |
mov edi,SF |
mov ecx,sizeof.graph_funcs/4 |
cld |
rep movsd |
; push dword[0x00003000] |
; mov dword[0x00003000],1 |
; call [SF.disable_mouse] |
; pop dword[0x00003000] |
mov [viewport.left],0 |
mov [viewport.top],0 |
m2m [viewport.right],[0x0000FE00] |
m2m [viewport.bottom],[0x0000FE04] |
movzx eax,byte[0xE035] |
cmp byte[0xE034],'2' |
jb @f |
mov al,0 |
@@: mov eax,[setbnk+eax*4] |
mov [set_bank],eax |
mov al,[0xFBF1] |
cmp al,32 |
jne @f |
; SHFLOW 'Driver initialized in 32-bit mode' |
mov [GF.draw_line],vm_mike_draw_line.32 |
;; mov [GF.disable_mouse],vm_mike_disable_mouse.32 |
;; mov [GF.draw_pointer],vm_mike_draw_pointer.32 |
mov [GF.drawbar],vm_mike_draw_rect.32 |
mov [GF.putpixel],vm_mike_put_pixel.32 |
mov [GF.getpixel],vm_mike_get_pixel.32 |
mov [GF.sys_putimage],vm_mike_put_image.32 |
mov [GF.drawbackground],vm_mike_draw_bg.32 |
jmp .exit.2 |
@@: cmp al,24 |
jne @f |
; SHFLOW 'Driver initialized in 24-bit mode' |
mov [GF.draw_line],vm_mike_draw_line.24 |
; mov [GF.disable_mouse],vm_mike_disable_mouse.24 |
; mov [GF.draw_pointer],vm_mike_draw_pointer.24 |
mov [GF.drawbar],vm_mike_draw_rect.24 |
mov [GF.putpixel],vm_mike_put_pixel.24 |
mov [GF.getpixel],vm_mike_get_pixel.24 |
mov [GF.sys_putimage],vm_mike_put_image.24 |
mov [GF.drawbackground],vm_mike_draw_bg.24 |
jmp .exit.2 |
@@: cmp al,16 |
jne @f |
; SHFLOW 'Driver initialized in 16-bit mode' |
mov [GF.draw_line],vm_mike_draw_line.16 |
; mov [GF.disable_mouse],vm_mike_disable_mouse.16 |
; mov [GF.draw_pointer],vm_mike_draw_pointer.16 |
mov [GF.drawbar],vm_mike_draw_rect.16 |
mov [GF.putpixel],vm_mike_put_pixel.16 |
mov [GF.getpixel],vm_mike_get_pixel.16 |
mov [GF.sys_putimage],vm_mike_put_image.16 |
mov [GF.drawbackground],vm_mike_draw_bg.16 |
jmp .exit.2 |
@@: cmp al,15 |
jne @f |
; SHFLOW 'Driver initialized in 15-bit mode' |
mov [GF.draw_line],vm_mike_draw_line.15 |
; mov [GF.disable_mouse],vm_mike_disable_mouse.15 |
; mov [GF.draw_pointer],vm_mike_draw_pointer.15 |
mov [GF.drawbar],vm_mike_draw_rect.15 |
mov [GF.putpixel],vm_mike_put_pixel.15 |
mov [GF.getpixel],vm_mike_get_pixel.15 |
mov [GF.sys_putimage],vm_mike_put_image.15 |
mov [GF.drawbackground],vm_mike_draw_bg.15 |
jmp .exit.2 |
@@: cmp al,8 |
jne @f |
; SHFLOW 'Driver initialized in 8-bit mode' |
call setup_palette_8 |
mov [GF.draw_line],vm_mike_draw_line.08 |
; mov [GF.disable_mouse],vm_mike_disable_mouse.08 |
; mov [GF.draw_pointer],vm_mike_draw_pointer.08 |
mov [GF.drawbar],vm_mike_draw_rect.08 |
mov [GF.putpixel],vm_mike_put_pixel.08 |
mov [GF.getpixel],vm_mike_get_pixel.08 |
mov [GF.sys_putimage],vm_mike_put_image.08 |
mov [GF.drawbackground],vm_mike_draw_bg.08 |
jmp .exit.2 |
@@: cmp al,4 |
jne .exit |
; SHFLOW 'Driver initialized in 4-bit mode' |
mov [GF.draw_line],vm_mike_draw_line.04 |
; mov [GF.disable_mouse],vm_mike_disable_mouse.04 |
; mov [GF.draw_pointer],vm_mike_draw_pointer.04 |
mov [GF.drawbar],vm_mike_draw_rect.04 |
mov [GF.putpixel],vm_mike_put_pixel.04 |
mov [GF.getpixel],vm_mike_get_pixel.04 |
mov [GF.sys_putimage],vm_mike_put_image.04 |
mov [GF.drawbackground],vm_mike_draw_bg.04 |
;-------------------------------------- |
.exit.2: |
mov [GF.calculatescreen],vm_mike_calculatescreen |
mov [GF.setscreen],vm_mike_setscreen |
inc [call_cnt] |
xor eax,eax |
.exit.3: |
retn |
.exit: |
xor eax,eax |
dec eax |
retn |
endf |
func vm_mike_calculatescreen |
begin |
; call [SF.calculatescreen] |
.direct: |
pushad |
cli |
movzx ecx,word[0x00003004] ; number of processes |
lea edi,[CLIP_RECTS+ecx*4+4] |
push dword[0x00003000] |
xor eax,eax |
.next_window: |
inc eax |
push ecx ebx eax edi |
mov [0x00003000],ax |
call calc_clipping_rects |
pop edi eax ebx |
mov [CLIP_RECTS+eax*4],edi |
mov [edi],ecx |
add edi,4 |
shl ecx,2 |
rep movsd |
pop ecx |
loop .next_window |
pop dword[0x00003000] |
sti |
popad |
ret |
endf |
func vm_mike_setscreen |
begin |
; call [SF.setscreen] |
call vm_mike_calculatescreen.direct |
ret |
endf |
func vm_mike_uninit |
begin |
; jif dword[mdrvm],e,0,.exit |
jif [call_cnt],nz,,.exit.2,dec |
mov esi,SF |
mov edi,GF |
mov ecx,sizeof.graph_funcs/4 |
rep movsd |
.exit.2: |
xor eax,eax |
retn |
.exit: |
xor eax,eax |
dec eax |
retn |
endf |
;----------------------------------------------------------------------------- |
include 'norm_04.inc' |
include 'norm_08.inc' |
include 'norm_15.inc' |
include 'norm_16.inc' |
include 'norm_24.inc' |
include 'norm_32.inc' |
;----------------------------------------------------------------------------- |
func is_intersect_rc |
begin |
jif ecx,l,[tr.left],.exit |
jif edx,l,[tr.top],.exit |
jif ebx,ge,[tr.bottom],.exit |
jif eax,ge,[tr.right],.exit |
clc |
ret |
.exit: |
stc |
ret |
endf |
func is_intersect_hln |
begin |
jif edx,l,[tr.left],.exit |
jif eax,l,[tr.top],.exit |
jif eax,ge,[tr.bottom],.exit |
jif ebx,ge,[tr.right],.exit |
clc |
ret |
.exit: |
stc |
ret |
endf |
func is_intersect_vln |
begin |
jif eax,l,[tr.left],.exit |
jif edx,l,[tr.top],.exit |
jif ebx,ge,[tr.bottom],.exit |
jif eax,ge,[tr.right],.exit |
clc |
ret |
.exit: |
stc |
ret |
endf |
func is_intersect_pt |
begin |
jif eax,l,[tr.left],.exit |
jif ebx,l,[tr.top],.exit |
jif ebx,ge,[tr.bottom],.exit |
jif eax,ge,[tr.right],.exit |
clc |
ret |
.exit: |
stc |
ret |
endf |
func get_cursor_rect |
begin |
push eax |
movsx eax,word[0x0000FB0A] |
mov [tr.left],eax |
add eax,31 |
mov [tr.right],eax |
movsx eax,word[0x0000FB0C] |
mov [tr.top],eax |
add eax,31 |
mov [tr.bottom],eax |
pop eax |
ret |
endf |
;----------------------------------------------------------------------------- |
gamma_4_0 = 0x00 |
gamma_4_1 = 0x1F |
gamma_4_2 = 0x2F |
gamma_4_3 = 0x3F |
align 16 |
palette_8_64 rb 256*3 |
palette_8_256 rb 256*3 |
rept 4 red:0 |
{ |
\rept 4 green:0 |
\{ |
\\rept 4 blue:0 |
\\{ |
index = ((red shl 4) or (green shl 2) or blue)*3 |
store gamma_4_ #red at palette_8_64+index+0 |
store gamma_4_ \#green at palette_8_64+index+1 |
store gamma_4_\\#blue at palette_8_64+index+2 |
store gamma_4_ #red *4+red at palette_8_256+index+0 |
store gamma_4_ \#green*4+green at palette_8_256+index+1 |
store gamma_4_\\#blue *4+blue at palette_8_256+index+2 |
\\} |
\} |
} |
;rept 64 clr1:0 |
;{ |
; index = clr1*3+64*3 |
; clr2 = clr*4+(clr shr 4) |
; store clr1 at palette_8_64 +index |
; store clr2 at palette_8_256+index |
; index = index + 64*3 + 1 |
; store clr1 at palette_8_64 +index |
; store clr2 at palette_8_256+index |
; index = index + 64*3 + 1 |
; store clr1 at palette_8_64 +index |
; store clr2 at palette_8_256+index |
;} |
func setup_palette_8 |
begin |
mov edx,0x03C8 |
xor al,al |
out dx,al |
mov ecx,256*3 |
mov edx,0x03C9 |
mov esi,palette_8_64 |
cld |
rep outsb |
ret |
endf |
;----------------------------------------------------------------------------- |
func set_bank0 |
begin |
mov ebp,[esp+4*1] |
ret |
endf |
; i810/i815 |
; by Protopopius |
func set_bank1 |
begin |
cli |
push eax edx |
mov eax,[esp+4*3] |
mov ebp,eax |
shr eax,16 |
sub al,0x0A |
cmp al,[0xfff2] |
je .exit |
mov [0xfff2],al |
mov dx,3CEh |
mov ah,al ; Save value for later use |
mov al,10h ; Index GR10 (Address Mapping) |
out dx,al ; Select GR10 |
inc dl |
mov al,3 ; Set bits 0 and 1 (Enable linear page mapping) |
out dx,al ; Write value |
dec dl |
mov al,11h ; Index GR11 (Page Selector) |
out dx,al ; Select GR11 |
inc dl |
mov al,ah ; Write address |
out dx,al ; Write the value |
.exit: |
and ebp,0x0000FFFF |
add ebp,0x000A0000 |
pop edx eax |
sti |
ret |
endf |
; S3 |
; by kmeaw |
func set_bank2 |
begin |
cli |
push eax edx ecx |
mov eax,[esp+4*4] |
mov ebp,eax |
shr eax,16 |
sub al,0x0A |
cmp al,[0xfff2] |
je .exit |
mov [0xfff2],al |
mov cl,al |
mov dx,0x3D4 |
mov al,0x38 |
out dx,al |
inc dx |
mov al,0x48 |
out dx,al |
dec dx |
mov al,0x31 |
out dx,al |
inc dx |
in al,dx |
dec dx |
mov ah,al |
mov al,0x31 |
out dx,ax |
mov al,ah |
or al,9 |
inc dx |
out dx,al |
dec dx |
mov al,0x35 |
out dx,al |
inc dx |
in al,dx |
dec dx |
and al,0xF0 |
mov ch,cl |
and ch,0x0F |
or ch,al |
mov al,0x35 |
out dx,al |
inc dx |
mov al,ch |
out dx,ax |
dec dx |
mov al,0x51 |
out dx,al |
inc dx |
in al,dx |
dec dx |
and al,0xF3 |
shr cl,2 |
and cl,0x0C |
or cl,al |
mov al,0x51 |
out dx,al |
inc dx |
mov al,cl |
out dx,al |
dec dx |
mov al,0x38 |
out dx,al |
inc dx |
xor al,al |
out dx,al |
.exit: |
and ebp,0x0000FFFF |
add ebp,0x000A0000 |
pop ecx edx eax |
sti |
ret |
endf |
; from http://my.execpc.com/CE/AC/geezer/os/slfb.asm |
func set_s3_bank |
begin |
cli |
push eax edx |
mov eax,[esp+4*3] |
mov ebp,eax |
shr eax,16 |
sub al,0x0A |
cmp al,[0xfff2] |
je .exit |
mov [0xfff2],al |
mov ah,al |
; grrrr...mode-set locked the S3 registers, so unlock them again |
; xxx - do this after mode-set |
mov dx,CRTC_INDX |
mov al,38h |
out dx,al |
inc edx |
mov al,48h |
out dx,al |
dec edx |
mov al,39h |
out dx,al |
inc edx |
mov al,0A5h |
out dx,al |
; now: do the bank-switch |
mov dx,CRTC_INDX |
mov al,35h |
out dx,al |
inc edx |
in al,dx |
and al,0F0h |
or al,ah |
out dx,al |
.exit: |
and ebp,0x0000FFFF |
add ebp,0x000A0000 |
pop edx eax |
sti |
ret |
endf |
func set_bank3 |
begin |
cli |
push eax edx |
mov eax,[esp+4*3] |
mov ebp,eax |
shr eax,16 |
sub al,0x0A |
cmp al,[0xfff2] |
je .exit |
mov [0xfff2],al |
mov ah,al |
mov dx,0x03D4 |
mov al,0x39 |
out dx,al |
inc dl |
mov al,0xA5 |
out dx,al |
dec dl |
mov al,6Ah |
out dx,al |
inc dl |
mov al,ah |
out dx,al |
dec dl |
mov al,0x39 |
out dx,al |
inc dl |
mov al,0x5A |
out dx,al |
dec dl |
.exit: |
and ebp,0x0000FFFF |
add ebp,0x000A0000 |
pop edx eax |
sti |
ret |
endf |
;----------------------------------------------------------------------------- |
DRIVER_CODE_END: |
diff10 'driver code size',DRIVER_CODE_START,DRIVER_CODE_END |
;----------------------------------------------------------------------------- |
;///// END /////////////////////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/normal.inc |
---|
0,0 → 1,375 |
;----------------------------------------------------------------------------- |
;///// PART OF ATi RADEON 9000 DRIVER //////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; Copyright (c) 2004, mike.dld |
; Using BeOS driver - Copyright (c) 2002, Thomas Kurschel |
;----------------------------------------------------------------------------- |
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
; DEALINGS IN THE SOFTWARE. |
;----------------------------------------------------------------------------- |
macro __include_debug_strings dummy,[_id,_fmt,_len] { |
common |
local c1,a1,a2 |
forward |
_id rb _len+1 |
db 0 |
a1 = 0 |
a2 = 0 |
if ~ _len eq |
repeat _len-1 |
virtual at 0 |
db _fmt,13,10,0,0 |
load c1 word from %+a2-1 |
end virtual |
if (c1='%s')|(c1='%x')|(c1='%d') |
store byte 0 at _id+%+a1-1 |
a2 = a2 + 1 |
else if (c1='\n') |
store word $0A0D at _id+%+a1-1 |
a1 = a1 + 1 |
a2 = a2 + 1 |
else |
store word c1 at _id+%+a1-1 |
end if |
end repeat |
end if |
common |
} |
macro include_debug_strings { __include_debug_strings __debug_strings } |
SHINFO0 fix SHINFO |
macro SHINFO _num,_format,[_arg] { |
common |
SHFLOW _format,_arg |
} |
macro SHFLOW _format,[_arg] { |
common |
if __DEBUG__ = 1 |
local ..f1,f2,a1,a2,c1,c2,..lbl |
_debug_str_ fix __debug_str_ # a1 |
a1 = 0 |
c2 = 0 |
f2 = 0 |
repeat ..lbl-..f1-1 |
virtual at 0 |
db _format,13,10,0 |
load c1 word from %-1 |
end virtual |
if c1 = '%s' |
virtual at 0 |
db _format,13,10,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS _debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
a2 = 0 |
forward |
if a2 = a1 |
DEBUGS _arg |
end if |
a2 = a2+1 |
common |
a1 = a1+1 |
else if c1 = '%x' |
virtual at 0 |
db _format,13,10,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS _debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
a2 = 0 |
forward |
if a2 = a1 |
DEBUGH _arg |
end if |
a2 = a2+1 |
common |
a1 = a1+1 |
else if c1 = '%d' |
virtual at 0 |
db _format,13,10,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS _debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
a2 = 0 |
forward |
if a2 = a1 |
DEBUGD _arg |
end if |
a2 = a2+1 |
common |
a1 = a1+1 |
end if |
end repeat |
virtual at 0 |
db _format,13,10,0 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS _debug_str_+f2-c2 |
end if |
virtual at 0 |
..f1 db _format,13,10,0 |
..lbl: |
__debug_strings fix __debug_strings,_debug_str_,_format,..lbl-..f1-1-c2 |
end virtual |
end if |
pushad |
mov edi,sys_delay |
mov eax,1 |
call sys_int |
popad |
} |
;----------------------------------------------------------------------------- |
macro jif _op1,_cond,_op2,_label,_op { |
if _op eq |
cmp _op1,_op2 |
else |
if _op2 eq |
_op _op1 |
else |
_op _op1,_op2 |
end if |
end if |
j#_cond _label |
} |
macro m2m op1,op2 { |
pushd op2 |
popd op1 |
} |
macro BITFIELD _bfnum,_size,[_name,_nbits] { |
common |
local _shift,_mask |
_shift = 0 |
.bit_field#_bfnum rb _size |
if B_HOST eq HOST_BENDIAN |
forward |
_mask = 0 |
repeat _nbits |
_mask = (_mask shl 1) or 1 |
end repeat |
_name = _mask shl _shift |
_name#_shift = _shift |
_shift = _shift + _nbits |
common |
else |
forward |
_mask = 0 |
repeat _nbits |
_mask = (_mask shl 1) or 1 |
end repeat |
_name = _mask shl (_size-_shift-_nbits) |
_name#_shift = _size-_shift-_nbits |
_shift = _shift + _nbits |
common |
end if |
} |
;----------------------------------------------------------------------------- |
sys_delay = 5*4 |
sys_pci = 62*4 |
sys_debug_board = 63*4 |
;----------------------------------------------------------------------------- |
func sys_int |
begin |
pushad |
push eax |
add edi,[systlb] |
call dword[edi] |
pop eax |
popad |
ret |
endf |
func debug_outstr |
begin |
mov eax,1 |
.l1: |
mov bl,[edx] |
test bl,bl |
jz .l2 |
mov edi,sys_debug_board |
call sys_int |
inc edx |
jmp .l1 |
.l2: |
ret |
endf |
macro DEBUGS [_str] { |
common |
pushf |
pushad |
local ..str,..label,..is_str |
..is_str = 0 |
forward |
if _str eqtype '' |
..is_str = 1 |
end if |
common |
if ..is_str = 1 |
jmp ..label |
..str db _str,0 |
..label: |
mov edx,..str |
call debug_outstr |
else |
mov edx,_str |
call debug_outstr |
end if |
popad |
popf |
} |
macro DEBUGF [_str] { |
common |
DEBUGS _str,13,10 |
} |
func debug_outchar |
begin |
pushad |
mov bl,al |
mov eax,1 |
mov edi,sys_debug_board |
call sys_int |
popad |
ret |
endf |
func debug_outdec |
begin |
mov ecx,10 |
push -'0' |
.l1: |
xor edx,edx |
div ecx |
push edx |
test eax,eax |
jnz .l1 |
.l2: |
pop eax |
add al,'0' |
jz .l3 |
call debug_outchar |
jmp .l2 |
.l3: |
ret |
endf |
macro DEBUGD _dec { |
pushf |
pushad |
if _dec eqtype eax |
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp> |
mov eax,_dec |
else if _dec in <ax,bx,cx,dx,si,di,bp,sp,al,ah,bl,bh,cl,ch,dl,dh> |
movzx eax,_dec |
end if |
else |
if (_dec eqtype word[])|(_dec eqtype byte[]) |
movzx eax,_dec |
else |
mov eax,_dec |
end if |
end if |
call debug_outdec |
popad |
popf |
} |
func debug_outhex |
__hexdigits db '0123456789ABCDEF' |
begin |
mov edx,8 |
.l1: |
rol eax,4 |
push eax |
and eax,0x0000000F |
mov al,[__hexdigits+eax] |
call debug_outchar |
pop eax |
dec edx |
jnz .l1 |
ret |
endf |
macro DEBUGH _hex { |
pushf |
pushad |
if ~_hex eq eax |
mov eax,_hex |
end if |
call debug_outhex |
popad |
popf |
} |
macro diff16 title,l1,l2 |
{ |
local s,d |
s = l2-l1 |
display title,': 0x' |
repeat 8 |
d = '0' + s shr ((8-%) shl 2) and $0F |
if d > '9' |
d = d + 'A'-'9'-1 |
end if |
display d |
end repeat |
display 13,10 |
} |
macro diff10 title,l1,l2 |
{ |
local s,d,z,m |
s = l2-l1 |
z = 0 |
m = 1000000000 |
display title,': ' |
repeat 10 |
d = '0' + s / m |
s = s - (s/m)*m |
m = m / 10 |
if d <> '0' |
z = 1 |
end if |
if z <> 0 |
display d |
end if |
end repeat |
display 13,10 |
} |
;----------------------------------------------------------------------------- |
;///// END /////////////////////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/struct.inc |
---|
0,0 → 1,180 |
; Macroinstructions for defining data structures |
macro struct name |
{ fields@struct equ name |
match child parent, name \{ fields@struct equ child,fields@\#parent \} |
sub@struct equ |
struc db [val] \{ \common fields@struct equ fields@struct,.,db,<val> \} |
struc dw [val] \{ \common fields@struct equ fields@struct,.,dw,<val> \} |
struc du [val] \{ \common fields@struct equ fields@struct,.,du,<val> \} |
struc dd [val] \{ \common fields@struct equ fields@struct,.,dd,<val> \} |
struc dp [val] \{ \common fields@struct equ fields@struct,.,dp,<val> \} |
struc dq [val] \{ \common fields@struct equ fields@struct,.,dq,<val> \} |
struc dt [val] \{ \common fields@struct equ fields@struct,.,dt,<val> \} |
struc rb count \{ fields@struct equ fields@struct,.,db,count dup (?) \} |
struc rw count \{ fields@struct equ fields@struct,.,dw,count dup (?) \} |
struc rd count \{ fields@struct equ fields@struct,.,dd,count dup (?) \} |
struc rp count \{ fields@struct equ fields@struct,.,dp,count dup (?) \} |
struc rq count \{ fields@struct equ fields@struct,.,dq,count dup (?) \} |
struc rt count \{ fields@struct equ fields@struct,.,dt,count dup (?) \} |
macro db [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,db,<val> \} |
macro dw [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dw,<val> \} |
macro du [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,du,<val> \} |
macro dd [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dd,<val> \} |
macro dp [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dp,<val> \} |
macro dq [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dq,<val> \} |
macro dt [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dt,<val> \} |
macro rb count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,db,count dup (?) \} |
macro rw count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dw,count dup (?) \} |
macro rd count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dd,count dup (?) \} |
macro rp count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dp,count dup (?) \} |
macro rq count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dq,count dup (?) \} |
macro rt count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dt,count dup (?) \} |
macro union \{ fields@struct equ fields@struct,,union,< |
sub@struct equ union \} |
macro struct \{ fields@struct equ fields@struct,,substruct,< |
sub@struct equ substruct \} |
virtual at 0 } |
macro ends |
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt |
restruc rb,rw,rd,rp,rq,rt |
purge db,dw,du,dd,dp,dq,dt |
purge rb,rw,rd,rp,rq,rt |
purge union,struct |
match name=,fields,fields@struct \\{ fields@struct equ |
make@struct name,fields |
fields@\\#name equ fields \\} |
end virtual \} |
match any, sub@struct \{ fields@struct equ fields@struct> \} |
restore sub@struct } |
macro make@struct name,[field,type,def] |
{ common |
if $ |
display 'Error: definition of ',`name,' contains illegal instructions.',0Dh,0Ah |
err |
end if |
local define |
define equ name |
forward |
local sub |
match , field \{ make@substruct type,name,sub def |
define equ define,.,sub, \} |
match any, field \{ define equ define,.#field,type,<def> \} |
common |
match fields, define \{ define@struct fields \} } |
macro define@struct name,[field,type,def] |
{ common |
local list |
list equ |
forward |
if ~ field eq . |
name#field type def |
sizeof.#name#field = $ - name#field |
else |
rb sizeof.#type |
end if |
local value |
match any, list \{ list equ list, \} |
list equ list <value> |
common |
sizeof.#name = $ |
restruc name |
match values, list \{ |
struc name value \\{ |
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\} |
match , fields@struct \\\{ label . |
forward |
match , value \\\\{ field type def \\\\} |
match any, value \\\\{ field type value |
if ~ field eq . |
rb sizeof.#name#field - ($-field) |
end if \\\\} |
common \\\} \\} \} } |
macro enable@substruct |
{ macro make@substruct substruct,parent,name,[field,type,def] |
\{ \common |
\local define |
define equ parent,name |
\forward |
\local sub |
match , field \\{ match any, type \\\{ enable@substruct |
make@substruct type,name,sub def |
purge make@substruct |
define equ define,.,sub, \\\} \\} |
match any, field \\{ define equ define,.\#field,type,<def> \\} |
\common |
match fields, define \\{ define@\#substruct fields \\} \} } |
enable@substruct |
macro define@union parent,name,[field,type,def] |
{ common |
virtual at 0 |
forward |
if ~ field eq . |
virtual at 0 |
parent#field type def |
sizeof.#parent#field = $ - parent#field |
end virtual |
if sizeof.#parent#field > $ |
rb sizeof.#parent#field - $ |
end if |
else if sizeof.#type > $ |
rb sizeof.#type - $ |
end if |
common |
sizeof.#name = $ |
end virtual |
struc name [value] \{ \common |
label .\#name |
last@union equ |
forward |
match any, last@union \\{ virtual at .\#name |
field type def |
end virtual \\} |
match , last@union \\{ match , value \\\{ field type def \\\} |
match any, value \\\{ field type value \\\} \\} |
last@union equ field |
common rb sizeof.#name - ($ - .\#name) \} } |
macro define@substruct parent,name,[field,type,def] |
{ common |
virtual at 0 |
forward |
if ~ field eq . |
parent#field type def |
sizeof.#parent#field = $ - parent#field |
else |
rb sizeof.#type |
end if |
local value |
common |
sizeof.#name = $ |
end virtual |
struc name value \{ |
label .\#name |
forward |
match , value \\{ field type def \\} |
match any, value \\{ field type value |
if ~ field eq . |
rb sizeof.#parent#field - ($-field) |
end if \\} |
common \} } |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/vmode.asm |
---|
0,0 → 1,814 |
; |
; MenuetOS Driver (vmode.mdr) |
; Target: Vertical Refresh Rate programming and videomode changing |
; |
; Author: Trans <<<<<13>>>>> |
; Date: 20.07.2003 |
; |
; Version: 1.0 |
; OS: MenuetOS |
; Compiler: FASM |
; |
use32 |
__DEBUG__ = 1 |
;macro align value { rb (value-1) - ($ + value-1) mod value } |
macro func name { |
if used name |
align 4 |
name@of@func equ name |
; _numb `name,name |
} |
macro begin { |
align 4 |
name@of@func: |
} |
endf fix end if |
macro return _val { |
if ~_val eq eax |
mov eax,_val |
end if |
ret |
} |
macro comment symb { ;s |
if 0=1 |
} |
^ fix end if |
include 'struct.inc' |
B_HOST fix HOST_BENDIAN ; HOST_LENDIAN |
;----------------------------------------------------------------------------- |
org 0x760000 |
headerstart=$ |
mdid db 'MDAZ' ; 4 byte id |
mdhver dd 0x00 ; header version |
mdcode dd MDSTART ; start of code |
mdver dd 0x00000001 ; driver version (subversion*65536+version) |
mdname db 'Trans VideoDriver' ; 32 bytes of full driver name |
times (32-($-mdname)) db ' ' ; |
headerlen=$-headerstart |
times (256-headerlen) db 0 ; reserved area for future |
MDSTART: ; start of driver code ( base_adr+256 bytes) |
; ebx(=ecx in program): |
; 1 - Get DriverInfo and Driver Initial Set |
; 2 - Get Current Video Mode With Vertical Refresh Rate |
; 3 - Change Video Mode |
; 4 - Return at Start System Video Mode |
; 5 - Change vertical and horizontal size of visible screen area |
; 6 - Change Vert/Hor position visible area on screen (not complete yet) |
; |
; MAXF - ... |
MAXF=7 |
;-------Main Manager------------- |
pushad |
cmp ebx,1 |
jb mdvm_00 |
cmp ebx,MAXF |
ja mdvm_00 |
call dword [mdvm_func_table+ebx*4] |
mov [esp+28],eax |
mov [esp+24],ecx |
mov [esp+20],edx |
mov [esp+16],ebx |
popad |
retn |
mdvm_00: |
popad |
xor eax,eax |
dec eax |
retn |
; ------Drivers Functions---------- |
; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set |
; |
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application |
; OUT: |
; |
func vm_info_init |
begin |
push ecx |
cmp [mdrvm],dword 0 |
jnz .vmii_00 |
call vm_safe_reg |
call vm_get_initial_videomode |
mov eax,[initvm] |
mov [currvm],eax |
; call vm_search_sys_func_table |
call vm_get_cur_vert_rate |
mov [initrr],eax |
call vm_calc_pixelclock |
call vm_calc_refrate |
inc [mdrvm] |
.vmii_00: |
pop ecx |
call vm_transfer_drv_info |
mov ebx,dword [refrate] |
mov eax,dword [mdid] ;dword [systlb] |
retn |
endf |
; EBX=2 (in applications ECX=2)- Get Current Video Mode |
; |
; OUT: eax = X_screen*65536+Y_screen |
; ebx = current vertical rate |
; ecx = current video mode (number) |
func vm_get_cur_mode |
begin |
cmp [mdrvm],dword 0 |
jz .vmgcm_00 |
call vm_get_cur_vert_rate |
mov eax,[0FE00h] |
mov ebx,[0FE04h] |
shl eax,16 |
add eax,ebx |
add eax,00010001h |
mov ebx,[refrate] |
mov ecx,[currvm] |
retn |
.vmgcm_00: |
xor eax,eax |
dec eax |
retn |
endf |
; EBX=3 (in applications ECX=3)- Change Video Mode |
; |
; IN: ecx = VertRate*65536+VideoMode |
; OUT: eax = 0 if no error |
; |
func vm_set_video_mode |
begin |
cmp [mdrvm],dword 0 |
jz .vmsvm_00 |
call vm_set_selected_mode |
; xor eax,eax |
retn |
.vmsvm_00: |
xor eax,eax |
dec eax |
retn |
endf |
; EBX=4 (in applications ECX=4)- Return at Start System Video Mode |
; |
; IN: |
; OUT: eax = = 0 if no error |
; |
func vm_restore_init_video_mode |
begin |
cmp [mdrvm],dword 0 |
jz .vmrivm_00 |
call vm_restore_reg |
xor eax,eax |
retn |
.vmrivm_00: |
xor eax,eax |
dec eax |
retn |
endf |
; EBX=5 (in applications ECX=5)- Change vertical and horizontal size |
; of visible screen area |
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position |
; = 2/3 - -/+ vertical size on 1 position (8 pixels) |
; ^-^----- not complete yet |
; OUT: eax = = 0 if no error |
; |
func vm_change_screen_size |
begin |
cmp [mdrvm],dword 0 |
jz .vmcss_00 |
cmp cl,1 |
ja .vmcss_01 |
mov eax,ecx |
call vm_inc_dec_width |
xor eax,eax |
retn |
.vmcss_01: |
and ecx,01h |
mov eax,ecx |
; call vm_inc_dec_high ; not complete yet |
xor eax,eax |
retn |
.vmcss_00: |
xor eax,eax |
dec eax |
retn |
endf |
; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen |
; |
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point |
; = 2/3 - -/+ vertical position on 1 pixel |
; ^-^----- not complete yet |
; OUT: eax = 0 if no error |
; |
func vm_change_position_screen |
begin |
cmp [mdrvm],dword 0 |
jz .vmcps_00 |
; ... |
xor eax,eax |
retn |
.vmcps_00: |
xor eax,eax |
dec eax |
retn |
endf |
;-----Drivers Subfunctions--------- |
; |
; Searching i40 system functions pointer table in kernel area location |
; |
func vm_search_sys_func_table |
begin |
push eax ; eax - current value |
push ecx ; ecx - will be counter of equevalent value |
push edx ; edx - last value |
push esi ; esi - current address |
xor ecx,ecx |
mov esi,010000h ; Start address of kernel location |
lodsd |
mov edx,eax |
cld |
.vmssft_00: |
cmp esi,30000h |
ja .vmssft_03 |
inc ecx |
lodsd |
cmp edx,eax |
mov edx,eax |
je .vmssft_00 |
cmp ecx,128 |
ja .vmssft_02 |
.vmssft_01: |
xor ecx,ecx |
jmp .vmssft_00 |
.vmssft_02: |
cmp edx,0 |
je .vmssft_01 |
sub esi,256*4-1 |
mov [systlb],esi |
xor ecx,ecx |
.vmssft_03_0: |
inc ecx |
lodsd |
cmp edx,eax |
mov edx,eax |
jne .vmssft_03_0 |
mov esi,dword [systlb] |
cmp cx,60 |
jae .vmssft_03 |
add esi,256*4-4 |
lodsb |
mov edx,eax |
jmp .vmssft_01 |
.vmssft_03: |
mov [systlb],esi |
pop esi |
pop edx |
pop ecx |
pop eax |
retn |
endf |
; IN: |
; OUT: eax= vertical rate in Hz |
func vm_get_cur_vert_rate |
begin |
push edx |
push ebx |
xor eax,eax |
mov edx,eax |
mov ebx,eax |
mov dx,03DAh |
.vmgcvt_00: |
in al,dx |
test al,8 |
jz .vmgcvt_00 |
.vmgcvt_01: |
in al,dx |
test al,8 |
jnz .vmgcvt_01 |
mov ebx,edx |
rdtsc |
mov edx,ebx |
mov ebx,eax |
.vmgcvt_02: |
in al,dx |
test al,8 |
jz .vmgcvt_02 |
.vmgcvt_03: |
in al,dx |
test al,8 |
jnz .vmgcvt_03 |
rdtsc |
sub eax,ebx |
mov ebx,eax |
mov eax,[0F600h] |
xor edx,edx |
div ebx |
inc eax |
mov [refrate],eax |
pop ebx |
pop edx |
retn |
endf |
func vm_calc_pixelclock |
begin |
push ebx |
push edx |
xor eax,eax |
mov al,[_00] |
add ax,5 |
shl eax,3 |
xor ebx,ebx |
mov bl,[_06] |
mov bh,[_07] |
and bh,00100001b |
btr bx,13 |
jnc .vmcpc_00 |
or bh,2 |
.vmcpc_00: |
xor edx,edx |
mul ebx |
xor edx,edx |
mul [initrr] |
mov [pclock],eax |
pop edx |
pop ebx |
retn |
endf |
; |
; Safe of initial CRTC state |
; |
func vm_safe_reg |
begin |
push edx |
push ebx |
push ecx |
push edi |
cli |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh |
out dx,al ; Clear protection bit |
dec dx |
xor ecx,ecx |
mov cl,19h |
xor bl,bl |
mov edi,CRTCreg |
.vmsr_00: |
mov al,bl |
out dx,al |
inc dx |
in al,dx |
dec dx |
stosb |
inc bl |
loop .vmsr_00 |
sti |
pop edi |
pop ecx |
pop ebx |
pop edx |
retn |
endf |
; |
; Restore of initial CRTC state |
; |
func vm_restore_reg |
begin |
push eax |
push ebx |
push edx |
push esi |
mov eax,[oldX] |
mov [0FE00h],eax |
mov eax,[oldY] |
mov [0FE04h],eax |
mov dx,03dah |
.vmrr_00: |
in al,dx |
test al,8 |
jnz .vmrr_00 |
.vmrr_01: |
in al,dx |
test al,8 |
jnz .vmrr_01 |
cli |
mov dx,03c4h |
mov ax,0101h |
out dx,ax |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh ; Clear Protection bit |
out dx,al |
dec dx |
xor ecx,ecx |
mov cl,19h |
mov esi,CRTCreg |
xor bl,bl |
.vmrr_02: |
lodsb |
mov ah,al |
mov al,bl |
out dx,ax |
inc bl |
loop .vmrr_02 |
sti |
; call ref_screen |
pop esi |
pop edx |
pop ecx |
pop eax |
retn |
endf |
; Calculate of possible vertical refrash rate |
; (light version of function) |
func vm_calc_refrate |
begin |
push ebx |
push ecx |
push edx |
push edi |
push esi |
mov eax,[pclock] |
xor edx,edx |
mov edi,_m1 |
mov ebx,eax |
mov ecx,(1696*1065) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(1344*804) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(1056*636) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(800*524) |
div ecx |
xor edx,edx |
stosw |
mov edi,_m1 |
mov esi,edi |
mov ecx,5*4 |
.vmcrr_00: |
lodsw |
cmp ax,55 |
jb .vmcrr_01 |
stosw |
loop .vmcrr_00 |
pop esi |
pop edi |
pop edx |
pop ecx |
pop ebx |
retn |
.vmcrr_01: |
xor ax,ax |
stosw |
loop .vmcrr_00 |
pop esi |
pop edi |
pop edx |
pop ecx |
pop ebx |
retn |
endf |
func vm_get_initial_videomode |
begin |
push eax |
mov eax,dword [0FE00h] |
mov [oldX],eax |
mov eax,dword [0FE04h] |
mov [oldY],eax |
mov eax,dword [0FE0Ch] ; initial video mode |
and ax,01FFh |
mov dword [initvm],eax |
pop eax |
retn |
endf |
; IN: eax = 0/1 - -/+ 1 position of width |
func vm_inc_dec_width |
begin |
push ebx |
push edx |
mov ebx,eax |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh ; Clear Protection bit |
out dx,al |
dec dx |
xor al,al |
out dx,al |
inc dx |
in al,dx |
dec al |
cmp bl,0 |
jnz .vmidr_00 |
inc al |
inc al |
.vmidr_00: |
out dx,al |
pop edx |
pop ebx |
retn |
endf |
; |
; Copy driver info to application area |
; |
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application |
; OUT: |
func vm_transfer_drv_info |
begin |
push ecx |
push edi |
push esi |
mov eax,ecx |
xor ecx,ecx |
mov cl,32/4 |
mov esi,mdname |
mov edi,drvname |
rep movsd |
mov ecx,eax |
mov eax,[mdver] |
mov [drvver],eax |
mov edi,[3010h] |
mov edi,[edi+10h] |
add edi,ecx |
mov esi,drvinfo |
xor ecx,ecx |
mov cx,512 |
rep movsb |
pop esi |
pop edi |
pop ecx |
retn |
endf |
; |
; Set selected video mode |
; (light version) |
; |
; IN: ecx = VertRate*65536+VideoMode |
; |
func vm_set_selected_mode |
begin |
push edx |
push ecx |
push esi |
ror ecx,16 |
cmp cx,00h |
je .vmssm_03 |
rol ecx,16 |
mov eax,ecx |
shl eax,16 |
shr eax,16 |
mov [currvm],eax |
cmp cx,112h |
jne .vmssm_00 |
mov esi,mode0 |
mov ecx,639 |
mov edx,479 |
jmp .vmssm_st00 |
.vmssm_00: |
cmp cx,115h |
jne .vmssm_01 |
mov esi,mode1 |
mov ecx,799 |
mov edx,599 |
jmp .vmssm_st00 |
.vmssm_01: |
cmp cx,118h |
jne .vmssm_02 |
mov esi,mode2 |
mov ecx,1023 |
mov edx,767 |
jmp .vmssm_st00 |
.vmssm_02: |
cmp cx,11Bh |
jne .vmssm_03 |
mov esi,mode2 |
mov ecx,1279 |
mov edx,1023 |
jmp .vmssm_st00 |
.vmssm_03: |
xor eax,eax |
dec eax |
pop esi |
pop ecx |
pop edx |
retn |
.vmssm_st00: |
mov [0FE00h],ecx |
mov [0FE04h],edx |
cli |
mov dx,03c4h |
lodsw |
out dx,ax |
mov dx,03d4h |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh |
out dx,al |
dec dx |
mov ecx,13 |
.vmssm_st01: |
lodsw |
out dx,ax |
loop .vmssm_st01 |
sti |
xor eax,eax |
pop esi |
pop ecx |
pop edx |
retn |
endf |
;-[ mike.dld ]- begin --------------- |
include 'normal.asm' |
;-[ mike.dld ]- end ----------------- |
;------------DATA AREA--------------- |
align 4 |
mdvm_func_table: |
dd MDSTART |
dd vm_info_init, vm_get_cur_mode |
dd vm_set_video_mode, vm_restore_init_video_mode |
dd vm_change_screen_size ;vm_change_position_screen |
;-[ mike.dld ]- begin --------------- |
dd vm_mike_init |
; dd vm_mike_cursor_pos |
dd vm_mike_uninit |
;-[ mike.dld ]- end ----------------- |
;1280x1024 - 11Bh |
mode3: |
dw 0101h |
dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h |
dw 0110h,8411h,0ff12h,0ff15h,2916h |
;1024x768 - 118h |
mode2: |
dw 0101h |
dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h |
dw 0310h,8911h,0ff12h,0ff15h,2516h |
;800x600 - 115h |
mode1: |
dw 0101h |
dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h |
dw 5910h,8d11h,5712h,5715h,7316h |
;640x480 - 112h, 12h |
mode0: |
dw 0101h |
dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h |
dw 0ea10h,8c11h,0df12h,0df15h,0c16h |
; 640x400 |
;mymode0: |
; dw 0101h |
;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h |
; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h |
; 640x800 |
;mymode1: |
; dw 0101h |
; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h |
; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h |
align 4 |
;-[ mike.dld ]- begin --------------- |
;oldX dd ? |
;oldY dd ? |
;initvm dd ? |
currvm dd 0 |
refrate dd 0 |
initrr dd 0 |
systlb dd 0 |
;pclock dd ? |
mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init |
;-[ mike.dld ]- end ----------------- |
drvinfo: |
drvname: times 32 db ' ' |
drvver dd 0 |
times (32-($-drvver))/4 dd 0 |
drvmode dw 011Bh,0118h,0115h,0112h |
times (64-($-drvmode))/2 dw 00h |
_m1 dw 0,0,0,0,0 |
_m2 dw 0,0,0,0,0 |
_m3 dw 0,0,0,0,0 |
_m4 dw 0,0,0,0,0 |
_m5 dw 0,0,0,0,0 |
times (512-($-drvinfo)) db 0 |
drvinfoend: |
;-[ mike.dld ]- begin --------------- |
align 4 |
include_debug_strings |
;-[ mike.dld ]- end ----------------- |
DRVM_END: |
align 4 |
;-[ mike.dld ]- begin --------------- |
oldX dd ? |
oldY dd ? |
initvm dd ? |
pclock dd ? |
;-[ mike.dld ]- end ----------------- |
CRTCreg: |
_00 db ? |
_01 db ? |
_02 db ? |
_03 db ? |
_04 db ? |
_05 db ? |
_06 db ? |
_07 db ? |
_08 db ? |
_09 db ? |
_0a db ? |
_0b db ? |
_0c db ? |
_0d db ? |
_0e db ? |
_0f db ? |
_10 db ? |
_11 db ? |
_12 db ? |
_13 db ? |
_14 db ? |
_15 db ? |
_16 db ? |
_17 db ? |
_18 db ? |
_19 db ? |
;-[ mike.dld ]- begin --------------- |
align 4 |
x_res fix 0x0000FE00 ; dd ? |
y_res fix 0x0000FE04 ; dd ? |
cnt dd ? |
align 16 |
tr RECT |
rct RECT |
;rb 40*sizeof.RECT |
;-[ mike.dld ]- end ----------------- |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmode/vmode.txt |
---|
0,0 → 1,53 |
Video Mode Driver ver.1.0 for MenuetOS |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
This driver provide of hardware operation of all VGA-compatible videocard |
P.S. |
It may be added to SYSFUNCS.TXT |
21 = SETUP FOR DEVICES |
ebx = 13 - videodriver enable |
ecx = 1 - Get DriverInfo and Driver Initial Set |
edx = offset to 512-bytes area for DriverInfo |
RETURN: eax = -1 - errors or driver not installed in system |
eax = 'MDAZ' - driver ID => set information in info area |
Info Structure: |
+0 - Full driver name (ASCII string ) |
+32 - Driver version (dword) |
+36 - Reserved |
+64 - List of support videomodes |
(max 32 positions) (word) |
+128 - List of Support vertical rate |
to each present mode (word): |
+0 - 1st ver.rate for mode0 |
+2 - 2st ver.rate for mode0 |
+4 - 3st ver.rate for mode0 |
+8 - 4st ver.rate for mode0 |
+10 - 5st ver.rate for mode0 |
+12 - 1st ver.rate for mode1 |
+14 - 2st ver.rate for mode1 |
+16 - 3st ver.rate for mode1 |
+18 - 4st ver.rate for mode1 |
+20 - 5st ver.rate for mode1 |
ecx = 2 - Get Current Video Mode With Vertical Refresh Rate |
RETURN: eax = -1 - errors |
eax = X_screen*65536+Y_screen |
ebx = current vertical rate |
ecx = current video mode (number) [see infostruct] |
ecx = 3 - Change Video Mode |
edx = VertRate*65536+VideoMode [see infostruct] |
RETURN: eax = -1 - errors |
eax = 0 - set new videomode |
ecx = 4 - Return at Start System Video Mode |
RETURN: eax = -1 - errors |
eax = 0 - set initial videomode |
ecx = 5 - Change vertical and horizontal size of visible screen area |
edx = 0/1 - -/+ horizontal size on 1 position |
= 2/3 - -/+ vertical size on 1 position (8 pixels) (not complete yet) |
RETURN: eax = -1 - errors |
eax = 0 - succesfull |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/kernel/branches/gfx_kernel/vmodeint.inc |
---|
0,0 → 1,47 |
; |
; Call of videomode driver's functions |
; |
; (Add in System function 21 (and/or 26) as a subfunction 13) |
; |
; Author: Trans |
; Date: 19.07.2003 |
; |
; Include in MeOS kernel and compile with FASM |
; |
uglobal |
old_screen_width dd ? |
old_screen_height dd ? |
endg |
cmp eax,13 ; CALL VIDEOMODE DRIVER FUNCTIONS |
jne .no_vmode_drv_access |
pushd [0x0000fe00] [0x0000fe04] |
popd [old_screen_height] [old_screen_width] |
or eax,-1 ; If driver is absent then eax does not change |
call 0x760100 ; Entry point of video driver |
mov [esp+36],eax |
mov [esp+24],ebx |
mov [esp+32],ecx |
; mov [esp+28],edx |
mov eax,[old_screen_width] |
mov ebx,[old_screen_height] |
sub eax,[0x0000fe00] |
jnz @f |
sub ebx,[0x0000fe04] |
jz .resolution_wasnt_changed |
jmp .lp1 |
@@: sub ebx,[0x0000fe04] |
.lp1: sub [screen_workarea.right],eax |
sub [screen_workarea.bottom],ebx |
call repos_windows |
mov eax, 0 |
mov ebx, 0 |
mov ecx, [0xfe00] |
mov edx, [0xfe04] |
call [calculatescreen] |
.resolution_wasnt_changed: |
ret |
.no_vmode_drv_access: |
/kernel/branches/gfx_kernel/vmodeld.inc |
---|
0,0 → 1,27 |
; |
; Load of videomode driver in memory |
; |
; (driver is located at 0x760000-0x768000 - 32kb) // if this area not occuped anything |
; |
; Author: Trans |
; Date: 19.07.2003 |
; |
; Include in MeOS kernel and compile with FASM |
; |
;vmode db 'VMODE MDR' ; MDR - Menuet Driver |
; must be located after fonts filenames in kernel.asm |
; LOAD VIDEOMODE DRIVER |
; If vmode.mdr file not found |
or eax,-1 ; Driver ID = -1 (not present in system) |
mov [0x760000],eax ; |
mov [0x760100],byte 0xC3 ; Instruction RETN - driver loop |
mov eax,vmode ; File name of driver |
mov esi,12 |
mov ebx,0 |
mov ecx,26000 |
mov edx,0x760000 ; Memory position of driver |
call fileread |