Added gfx_kernel branch

git-svn-id: svn://kolibrios.org@129 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Mihail Semenyako (mike.dld)
2006-08-14 21:38:03 +00:00
parent 19bd066c8c
commit e3172037f7
107 changed files with 63857 additions and 0 deletions
@@ -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
+261
View File
@@ -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
+73
View File
@@ -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
@@ -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
File diff suppressed because it is too large Load Diff
@@ -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
@@ -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
+133
View File
@@ -0,0 +1,133 @@
;======================================================================
;
; BOOT DATA
;
;======================================================================
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
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
+133
View File
@@ -0,0 +1,133 @@
;======================================================================
;
; BOOT DATA
;
;======================================================================
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
space_msg: line_space
verstr:
; line_space
; version string
db 186,32
repeat 78
load a byte from version+%-1
if a = 13
break
end if
db a
end repeat
repeat 78 - ($-verstr)
db ' '
end repeat
db 32,186
line_half
d80x25_top_num = 4
d80x25_bottom:
db 186,' 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
File diff suppressed because it is too large Load Diff
@@ -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
@@ -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
@@ -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:
+92
View File
@@ -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
@@ -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
+4
View File
@@ -0,0 +1,4 @@
@erase lang.inc
@echo lang fix en >lang.inc
@fasm kernel.asm kernel.mnt
@pause
+4
View File
@@ -0,0 +1,4 @@
@erase lang.inc
@echo lang fix ru >lang.inc
@fasm kernel.asm kernel.mnt
@pause
@@ -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
@@ -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
+499
View File
@@ -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
+469
View File
@@ -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
@@ -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
File diff suppressed because it is too large Load Diff
+220
View File
@@ -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
+191
View File
@@ -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
+111
View File
@@ -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
File diff suppressed because it is too large Load Diff
+151
View File
@@ -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
@@ -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:
@@ -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
@@ -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:
@@ -0,0 +1,4 @@
include 'dev_fd.inc'
include 'dev_hdcd.inc'
include 'sear_par.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
@@ -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
@@ -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
.............
.............
+518
View File
@@ -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)