Cyjon OS

0
akasei napisał(a):

Implementacja tego GUI, http://forum.osdev.org/download/file.php?id=2787&mode=view
może mi przysporzyć nie lada problemu.

Jedyna trudność to ten efekt cienia pod oknem, ale możesz go na razie nie robić.

2
Azarien napisał(a):
akasei napisał(a):

Implementacja tego GUI, http://forum.osdev.org/download/file.php?id=2787&mode=view
może mi przysporzyć nie lada problemu.

Jedyna trudność to ten efekt cienia pod oknem, ale możesz go na razie nie robić.

Tak, cienie (jak i przeźroczystość) to spore obciążenie dla procka.

Przyjąłem taki prosty motyw, szukam teraz znaku X do zamknięcia aplikacji.

title

0

@Akasei Zastanawiam się nad poziomem skomplikowania, który będzie bardzo, bardzo szybko rósł. GUI to przecież o wiele bardziej złożona maszyneria niż tryb tekstowy. Podziwiam Twoją wiedzę w zakresie ASM, naprawdę. Niemniej zastanawiam się czy zdarzy się taki moment, że poziom skomplikowania kodu i mechanizmów, które to wszystko obsługują na tak niskim poziomie, będzie wart swojej ceny.

Ciekawe czy zdarzy się chwila kiedy pętla bugów, czyli dajmy na to załatanie czegoś spowoduje x kolejnych bugów, zmusi Cię do przejścia na coś wyższego poziomu :)

0

@grzesiek51114: Istnieje szansa, że zablokuje się na
elemencie typu textarea...

@jpacanowski jak będe w domu rzucę kodem do zarządzania oknami, bardzo prosty.

0

@jpacanowski: Brak tu jeszcze zarządzania elementami interfejsu.

;===============================================================================
; wejście:
;	rcx - identyfikator specyfikacji okna
window_show:
	; zachowaj oryginalne rejestry
	push	rax
	push	rbx
	push	rcx
	push	rdx
	push	rsi
	push	rdi

	; oblicz adres elementu na liście
	mov	rax,	STRUCTURE_X_WINDOW.SIZE
	mul	rcx

	; zamień adres na bezwzględny
	mov	rsi,	qword [list_x_windows]
	add	rsi,	rax

	; kontynuuj
	jmp	.ready

.element:
	; zachowaj oryginalne rejestry
	push	rax
	push	rbx
	push	rcx
	push	rdx
	push	rsi
	push	rdi

.ready:
	; oblicz pozycję Y okna
	mov	rax,	qword [rsi + STRUCTURE_X_WINDOW.y]
	mul	qword [static_x_scanline_width]
	push	rax

	; oblicz pozycję X okna
	mov	rax,	qword [rsi + STRUCTURE_X_WINDOW.x]
	mul	qword [static_x_pixel_size]
	add	qword [rsp],	rax

	; zamień adres na bezwzględny
	pop	rdi
	add	rdi,	qword [static_x_cache_address]

	; szerokość okna
	mov	rbx,	qword [rsi + STRUCTURE_X_WINDOW.width]

	; oblicz szerokość okna w Bajtach
	mov	rax,	rbx
	mul	qword [static_x_pixel_size]

	; wysokość okna
	mov	rdx,	qword [rsi + STRUCTURE_X_WINDOW.height]

	; ustaw wskaźnik na przestrzeń stanu okna
	mov	rsi,	qword [rsi + STRUCTURE_X_WINDOW.address]

.loop:
	; kopiuj
	mov	rcx,	rbx
	rep	movsd

	; przesuń wskaźnik na następną linię okna
	add	rdi,	qword [static_x_scanline_width]
	sub	rdi,	rax

	; pozostały inne linie okna?
	dec	rdx
	jnz	.loop

	; przywróć oryginalne rejestry
	pop	rdi
	pop	rsi
	pop	rdx
	pop	rcx
	pop	rbx
	pop	rax

	; powrót z procedury
	ret

;===============================================================================
; wejście:
;	rsi - wskaźnik do specyfikacji okna
window_create:
	; zachowaj oryginalne rejestry
	push	rax
	push	rcx
	push	rdx
	push	rdi

	; wylicz rozmiar okna w Bajtach
	mov	rax,	qword [rsi + STRUCTURE_X_WINDOW.width]
	mul	qword [rsi + STRUCTURE_X_WINDOW.height]
	mul	qword [static_x_pixel_size]

	; zapamiętaj rozmiar w Bajtach
	mov	qword [rsi + STRUCTURE_X_WINDOW.size],	rax

	; przelicz na ilość stron
	mov	rcx,	STATIC_MEMORY_PAGE_SIZE
	xor	rdx,	rdx
	div	rcx

	; brak reszty? (rzadkość)
	cmp	rdx,	STATIC_EMPTY
	je	.no_modulo

	; ilość stron zwiększona
	inc	rax

.no_modulo:
	; zarezerwuj odpowiednią ilość pamięci do przechowywania stanu okna
	call	memory_find
	jc	.error_no_memory

	; zapamiętaj adres przestrzeni stanu okna
	mov	qword [rsi + STRUCTURE_X_WINDOW.address],	rdi

	; utwórz "ciało" okna (nagłówek, elementy nagłówka (minimalizuj, zamknij itp.), kolot tła okna)
	call	window_body

	; koniec
	jmp	.end

.error_no_memory:
	; flaga, błąd
	stc

.end:
	; przywróć oryginalne rejestry
	pop	rdi
	pop	rdx
	pop	rcx
	pop	rax

	; powrót z procedury
	ret

;===============================================================================
; wejście:
;	rsi - wskaźnik do specyfikacji okna
;	rdi - wskaźnik do przestrzeni stanu okna
window_body:
	; zachowaj oryginalne rejestry
	push	rax
	push	rcx
	push	rdx
	push	rdi
	push	r8

	; kolor ramki okna
	mov	eax,	STATIC_X_WINDOW_BACKGROUND_COLOR

	; szerokość okna
	mov	rbx,	qword [rsi + STRUCTURE_X_WINDOW.width]

	; wysokość nagówka
	mov	rdx,	qword [rsi + STRUCTURE_X_WINDOW.height]

.body:
	; szerokość okna
	mov	rcx,	rbx

	; koloruj okno
	rep	stosd

	; reszta linii?
	dec	rdx
	jnz	.body

	; przywróć oryginalne rejestry
	pop	r8
	pop	rdi
	pop	rdx
	pop	rcx
	pop	rax

	; powrót z procedury
	ret

;===============================================================================
window_drag:
	; sprawdź status lewego klawisza myszki
	bt	word [variable_x_mouse_status],	STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB
	jnc	.end

	; sprawdź status lewego klawisza ALT
	cmp	byte [semaphore_x_key_alt_left],	STATIC_FALSE
	je	.end

	; znajdź właściwości okna, które znajduje się pod pozycją kursora
	call	window_find
	jc	.end	; brak specyficznego okna pod wskaźnikiem kursora

	; czy okno znajduje się a końcu listy?
	cmp	bl,	STATIC_TRUE
	je	.on_top

	; zachowaj wskaźnik do właściwości okna
	push	rsi

	; przesuń okno (element) z listy na koniec (na wierzch)
	call	window_insert

	; zachowaj nową specyfikację, przywróć starą, usuń stare właściwości okna z listy
	xchg	rsi,	qword [rsp]
	call	window_remove

	mov	byte [debug],	STATIC_TRUE

	; przwróć wskaźnik do właściwości okna
	pop	rsi

.on_top:
	;-----------------------------------------------------------------------
	; aktualizuj współrzędne okna względem delty przesunięcia kursora

	; oś X
	mov	rax,	qword [variable_x_mouse_x_delta]

	; brak przemieszczenia po osi X?
	cmp	rax,	STATIC_EMPTY
	je	.axis_y

	; wartość negatywna?
	bt	rax,	STATIC_QWORD_SIGN_BIT
	jnc	.axis_x_unsigned

	; odwróć notacje
	not	rax
	inc	rax	; korekta wartości ujemnej

	; przesuń współrzędne okna
	add	qword [rsi + STRUCTURE_X_WINDOW.x],	rax

	; sprawdź czy okno znajduje się w przestrzeni ekranu
	mov	rax,	qword [static_x_width]
	sub	rax,	qword [rsi + STRUCTURE_X_WINDOW.width]
	cmp	qword [rsi + STRUCTURE_X_WINDOW.x],	rax
	jb	.axis_y

	; koryguj pozycje okna
	mov	qword [rsi + STRUCTURE_X_WINDOW.x],	rax

	; sprawdź oś Y
	jmp	.axis_y

.axis_x_unsigned:
	; przesuń współrzędne okna
	sub	qword [rsi + STRUCTURE_X_WINDOW.x],	rax
	jns	.axis_y	; wystąpiło przekręcenie licznika?

	; okno nie może wyjść poza obszar ekranu, koryguj
	mov	qword [rsi + STRUCTURE_X_WINDOW.x],	STATIC_EMPTY

.axis_y:
	; oś Y
	mov	rax,	qword [variable_x_mouse_y_delta]

	; brak przemieszczenia po osi Y?
	cmp	rax,	STATIC_EMPTY
	je	.end

	; wartość negatywna?
	bt	rax,	STATIC_QWORD_SIGN_BIT
	jnc	.axis_y_unsigned

	; odwróć notacje
	not	rax
	inc	rax	; korekta wartości ujemnej

	; przesuń współrzędne okna
	add	qword [rsi + STRUCTURE_X_WINDOW.y],	rax

	; sprawdź czy okno znajduje się w przestrzeni ekranu
	mov	rax,	qword [static_x_height]
	sub	rax,	qword [rsi + STRUCTURE_X_WINDOW.height]
	cmp	qword [rsi + STRUCTURE_X_WINDOW.y],	rax
	jb	.end

	; koryguj pozycje okna
	mov	qword [rsi + STRUCTURE_X_WINDOW.y],	rax

	; koniec
	jmp	.end

.axis_y_unsigned:
	; przesuń współrzędne okna
	sub	qword [rsi + STRUCTURE_X_WINDOW.y],	rax
	jns	.end	; wystąpiło przekręcenie licznika?

	; okno nie może wyjść poza obszar ekranu, koryguj
	mov	qword [rsi + STRUCTURE_X_WINDOW.y],	STATIC_EMPTY

.end:
	; powrót z procedury
	ret

;===============================================================================
; wejście:
;	r8 - pozycja X kursora
;	r9 - pozycja Y kursora
; wyjście:
;	Flaga CF jeśli brak elementu
;	bl - STATIC_TRUE, jeśli jest to ostatni element listy
;	rsi - wskaźnik do elementu
window_find:
	; zachowaj oryginalne rejestry
	push	rax
	push	rbx
	push	rcx
	push	rsi

	; znajdź ostatni element na liście
	mov	rsi,	qword [list_x_windows]

	; flaga ostatniego elementu listy
	mov	bl,	STATIC_TRUE

	; ilość elementów zawartych w liście
	xor	rcx,	rcx

.last:
	; element pusty?
	cmp	qword [rsi + STRUCTURE_X_WINDOW.width],	STATIC_EMPTY
	je	.find

	; następny element
	inc	rcx
	add	rsi,	STRUCTURE_X_WINDOW.SIZE
	jmp	.last

.find:
	; przeszukaj elementy wstecz za pasującym do wzorca (pozycja kursora)
	sub	rsi,	STRUCTURE_X_WINDOW.SIZE

	; kursor znajduje się w przestrzeni X,Y?
	cmp	r8,	qword [rsi + STRUCTURE_X_WINDOW.x]
	jb	.next
	cmp	r9,	qword [rsi + STRUCTURE_X_WINDOW.y]
	jb	.next

	; kursor znajduje się w przestrzeni WIDTH?
	mov	rax,	qword [rsi + STRUCTURE_X_WINDOW.x]
	add	rax,	qword [rsi + STRUCTURE_X_WINDOW.width]
	cmp	r8,	rax
	jae	.next

	; kursor znajduje się w przestrzeni HEIGHT?
	mov	rax,	qword [rsi + STRUCTURE_X_WINDOW.y]
	add	rax,	qword [rsi + STRUCTURE_X_WINDOW.height]
	cmp	r9,	rax
	jae	.next

	; flaga, sukces
	clc

	; zwróć wynik operacji
	mov	qword [rsp + STATIC_QWORD_SIZE * 0x02],	rbx
	mov	qword [rsp],	rsi

	; koniec
	jmp	.end

.next:
	; flaga ostatniego elementu listy
	mov	bl,	STATIC_FALSE

	; pozostały inne elementy?
	dec	rcx
	jnz	.find

	; flaga, błąd
	stc

.end:
	; przywróć oryginalne rejestry
	pop	rsi
	pop	rcx
	pop	rbx
	pop	rax

	; powrót z procedury
	ret

;===============================================================================
; wejście:
;	rsi - wskaźnik specyfikacji okna
window_remove:
	; zachowaj oryginalne rejestry
	push	rax
	push	rcx
	push	rsi
	push	rdi

	; ustaw wskaźnik docelowy i źródłowy
	mov	rdi,	rsi
	add	rsi,	STRUCTURE_X_WINDOW.SIZE

.loop:
	; rozmiar elementu na liście
	mov	rcx,	STRUCTURE_X_WINDOW.SIZE

	; element listy pusty?
	cmp	word [rdi + STRUCTURE_X_WINDOW.width],	STATIC_EMPTY
	je	.end

	; przenieś następny element w miejsce aktualnego
	rep	movsb

	; przenieś pozostałe elementy
	jmp	.loop

.end:
	; przywróć oryginalne rejestry
	pop	rdi
	pop	rsi
	pop	rcx
	pop	rax

	; powrót z procedury
	ret

;===============================================================================
; wejście:
;	rsi - wskaźnik specyfikacji okna
; wyjście:
;	rsi - wskaźnik do elementu listy przechowującego specyfikację okna
window_insert:
	; zachowaj oryginalne rejestry
	push	rcx
	push	rdi
	push	rsi

	; ustaw wskaźnik początku listy okien
	mov	rdi,	qword [list_x_windows]

.loop:
	; element listy wolny?
	cmp	word [rdi + STRUCTURE_X_WINDOW.width],	STATIC_EMPTY
	je	.found

	; przesuń wskaźnik na następny element
	add	rdi,	STRUCTURE_X_WINDOW.SIZE

	; szukaj dalej
	jmp	.loop

.found:
	; zwróć wskaźnik do elementu listy
	mov	qword [rsp],	rdi

	; załaduj właściwości okna do elementu listy
	mov	rcx,	STRUCTURE_X_WINDOW.SIZE
	rep	movsb

	; flaga, sukces
	clc

	; przywróć oryginalne rejestry
	pop	rsi
	pop	rdi
	pop	rcx

	; powrót z procedury
	ret
0
akasei napisał(a):
 bt  word [variable_x_mouse_status], STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB

Ja tu widzę brak abstrakcji sprzętu: kto powiedział że musi być PS2 (nawet jeśli póki co nie obsługujesz innych protokołów).

0
Azarien napisał(a):
akasei napisał(a):
 bt  word [variable_x_mouse_status], STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB

Ja tu widzę brak abstrakcji sprzętu: kto powiedział że musi być PS2 (nawet jeśli póki co nie obsługujesz innych protokołów).

Spoko napisz mi sterownik do UHCI, EHCI itp, będzie można obsłużyć każde urządzenie po USB, wtedy pisze się abstrakcję.

0

wtedy pisze się abstrakcję.

Wtedy musisz przeszukać cały kod pod kątem odwołań do PS2, zamiast od razu mieć ładny interfejs.

0
Patryk27 napisał(a):

wtedy pisze się abstrakcję.

Wtedy musisz przeszukać cały kod pod kątem odwołań do PS2, zamiast od razu mieć ładny interfejs.

Przeszukiwać to za dużo powiedziane :) ale,
jak uznam, że wystarczająco długo siedziałen nad X, może przejdę do pisania obsługi USB. Teraz myszka ogranicza sie tylko do Xów.

0

Twoje podejście brzmi jak nie będę tworzył VFS, bo póki co obsługuję tylko FAT ;-)
Nie chodzi o żadną obsługę USB, tylko o abstrakcję dostępu do sprzętu.

0
Patryk27 napisał(a):

Twoje podejście brzmi jak nie będę tworzył VFS, bo póki co obsługuję tylko FAT ;-)
Nie chodzi o żadną obsługę USB, tylko o abstrakcję dostępu do sprzętu.

Dobra, przedstawię to z innego punktu widzenia. Jeśli nie mam obsługi przynajmniej dwóch urządzeń tego samego typu na różnych protokołach to nie wiem jak mam skonstruować abstrakcję. Proste (przynajmniej dla mnie).

W tym momencie mam "abstrakcję" obsługi myszki, wiem co zrobiła i który klawisz naciśnięto. Nie pytam się jej bezpośredno tylko jądro podaje mi tą informację.

0
 bt  word [variable_x_mouse_status], STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB

Ja tu widzę brak abstrakcji sprzętu: kto powiedział że musi być PS2 (nawet jeśli póki co nie obsługujesz innych protokołów).

Spoko napisz mi sterownik do UHCI, EHCI itp, będzie można obsłużyć każde urządzenie po USB, wtedy pisze się abstrakcję.

Nie chodzi o pisanie sterowników. Chodzi o to, że już teraz powinienieś pisać kod z założeniem, że są różnie rodzaje myszy. Nazwa PS2 i szczegóły protokołu powinny się pojawiać tylko w obrębie sterownika myszy PS/2, a nie w kodzie po prostu używającym myszy.

Albo inaczej: okno nie powinno wiedzieć, jakiego rodzaju mysz jest podłączona.

0

Rozumiem, w sumie mogę tą nazwę zmienić, bo już nie dotyczy PS2 :)

0

wataha.net nie działa :(

0

Dobra, muszę przywrócić obsługę GRUBa.
Kompilacja co chwila z inną rozdzielczością jest... nieefektywna ;)

Praca nad tym zajmie mi trochę czasu, ale będzie warto (będziecie mogli dodać sobie wpis do grub.cfg :)
Rozdzielczość pracy systemu będzie można ustalać z poziomu GRUBa.

0

Teraz już wiem, nie mogę korzystać z trybu multiboot dla jądra:
http://superuser.com/a/919728

The problem was that my kernel is loaded by multiboot <filename> command and linux is loaded (in most cases) by linux <filename> command. Multiboot specification requires that information about preferred video mode is provided in the multiboot header. If that information is not provided, GRUB switches back to the text mode before starting the kernel and completely ignores gfxpayload variable.

Zatem, trzeba jądro przystosować do ELFa, poszukiwania najprostszego nagłówa ELF w trakcie (lub wygenerowanie własnego http://wiki.osdev.org/ELF#Tables).

0
mad_penguin napisał(a):

wataha.net nie działa :(

Hagefid napisał(a)]:

Trzeba wyczyscic HSTS w przegladarce i bedzie działać: http://classically.me/blogs/how-clear-hsts-settings-major-browsers

Jaki sens ma używanie jakiegoś "Strict Security" skoro nie potrafimy dotrzymać ograniczeń, jakie ono nakłada?

0
Azarien napisał(a):
mad_penguin napisał(a):

wataha.net nie działa :(

Hagefid napisał(a)]:

Trzeba wyczyscic HSTS w przegladarce i bedzie działać: http://classically.me/blogs/how-clear-hsts-settings-major-browsers

Jaki sens ma używanie jakiegoś "Strict Security" skoro nie potrafimy dotrzymać ograniczeń, jakie ono nakłada?

Wcześniej strona leżała na serwerze, który wymuszał HSTS. Teraz jest na innym.

0

Nie obejdę multiboot :|

Jeśli ktoś ma chęć może wykonać prostą aplikację z GUI (MS Windows, Apple Inc.) podmieniającą nw. wartości na własną rozdzielczość w formacie szesnastkowym.

title

Na systemach z rodziny GNU/Linux jest to o tyle proste:

# rozdzielczość 1280x720
# 1280 => 0x00000500
# 720 => 0x000002D0

$ echo -ne '\x00\x05\x00\x00' | dd conv=notrunc of=kernel bs=4 seek=9
$ echo -ne '\xD0\x02\x00\x00' | dd conv=notrunc of=kernel bs=4 seek=10
1

Staram się sprawdzić dlaczego Qemu potrafi się zrestartować...

Qemu startuje i przechodzi w stan wstrzmyania.
Uruchamiam GDB, kod systemu przeskakuje do pierwszego BREAK i wykonuję CONTINUE.
Po paru sekundach otrzymuję restart Qemu i raz jeszcze zatrzymuje mi się w moim BREAK.
Ani jednej informacji co się stało... pięknie kurcze, pięknie.

title

Z dobrych wiadomości :)
Cyjon działa już na VirtualBox :)

0

Dobra, znalazłem winowajce... Linux ;) (joke)

A dokładnie to Windows > VirtualBox > Linux > Qemu > Cyjon OS taka incepcja źle wpływa na stabilność systemu :)
Qemu się gubi z obsługą myszki co daje Triple-Fault.
Bochs to nie robi różnicy, bo symuluje wszystko.
VirtualBox ma profesjonalne zarządzanie sprzętem + GuestAddons w pierwszej wirtualce, więc to go nie rusza.

Cyjon OS uruchomiony bezpośrednio na Windows + wirtualka, działa stabilnie.
**
Aktualizacja 16/03/2017**, cofam moje słowa, Qemu zwariował.

Jeśli ktoś ma możliwość sprawdzenia dlaczego wirtualka uruchomiła się ponownie:
(link nieaktualny)
(link nieaktualny)
(link nieaktualny)
Poproszę zawartość rejestru RIP przed restartem lub zawartość stosu (z 256 Bajtów).

2

Niewiele, dekodowanie pliku BMP.
Błąd restartu Qemu zlikwidowany.

title

Do pobrania:

  • obraz [Qemu/Bochs](link nieaktualny)
  • obraz [VBox](link nieaktualny)
  • jądro systemu dla [GRUB](link nieaktualny)

Horizon Zero Dawn mam już za sobą, mogę się skupić na Cyjonie.

2
akasei napisał(a):

Nie mam pojęcia jak wykonać przeźroczystość na bazie kanału alfa, więc pomijam jego obsługę

Załóżmy że na piksel nieprzezroczystego tła R1,G1,B1 chcesz nałożyć piksel bitmapy R2,G2,B2,A2 z zachowaniem jego przezroczystości.
Załóżmy też, że wszystkie wartości są 8-bitowe, czyli 0..255.

Kolor wynikowego piksela wynosi (dla każdego kanału RGB tak samo):
·
G = G_2<em>A_2/255 + G_1</em>(255-A_2)/255
·
Jeżeli ta sama bitmapa będzie wielokrotnie nakładana, opłaca się pierwszą część operacji wykonać już podczas ładowania bitmapy do pamięci:
·
AG_2 = G_2<em>A_2/255
·
I tak przetworzoną bitmapę (AR2,AG2,AB2,A2) przechowywać. Nazywa się to PRGBA (P od “premultiplied”). Operacja nakładania jest wtedy trochę szybsza:
·
G = AG_2 + G_1</em>(255-A_2)/255
·

Wszystkie wartości oczywiście konwertujemy z 8 bitów na floating-point i odwrotnie. Czy to da się zrobić w całości na typach całkowitych to już zostawiam jako zadanie dla czytelnika ;-)

0

@Azarien: jest OK :) po prostu do pamięci odłożyłem kolory w kolejności BigEndian, czli kod dobrze napisałem :D

Za to nie wpadłem na początku na pomysł PRGBA, zostosuję. Dzięki.

1

Nie wytrzymałem do piątku ;) przeźroczystość w pełnej krasie.

title

2

@babubabu: proszę :P

0

@Akasei: zauważyłem na powyższym filmiku, że nie można przesunąć okienka poza obszar pulpitu (tzn. fragmentu okna, nie całego, bo to by sensu nie miało). Uważasz, że to dobry pomysł, czy jeszcze czegoś w kodzie brakuje (co masz zamiar dopisać), że nie jest to obsługiwane?

0

@furious programming: Właśnie złapałeś mnie na dopisywaniu tego kodu w tym momencie ;)
Nie był priorytetem.

2

Proszę bardzo jest poza ekran:

1 użytkowników online, w tym zalogowanych: 0, gości: 1