Program na konkurs OSDev

W tym miejscu zadajemy pytania na temat języka Assembler, dzielimy się swoją wiedzą, udzielamy wsparcia, rozwiązujemy problemy programistyczne.
Awatar użytkownika
PROTON
Expert
Expert
Posty: 527
Rejestracja: czwartek 08 paź 2015, 18:35
Lokalizacja: Warszawa

Program na konkurs OSDev

Postautor: PROTON » poniedziałek 20 cze 2016, 20:05

Na kanale YT, podczas livestreamu OSDev #4, Gynvael Coldwind zorganizował konkurs na program, szczegóły:

KONKURS (tym razem skillowy)
DO: 12.06 23:59
Napisz efekt graficzny:
- działający w trybie tekstowym
- działający jako bootloader
- zajmujący max 512 bajtów (stage1 ;>)
- działający minimum pod Bochs
Nagroda: gift card 100 GBP na amazon.co.uk


Więcej informacji: http://gynvael.coldwind.pl/?id=609

Napisałem programik przedstawiający przesuwające się paski ZX Spectrum, wyświetlający adres: HTTP://MICROGEEK.EU, wyświetlający datę i godzinę oraz wykorzystujący takie mechanizmy:

- odczyt godziny i daty z RTC
- wykorzystanie przerwania IRQ0 (18.2 razy na sekundę) do animacji
- wykorzystanie bufora obrazu
- kopiowanie obszarów pamięci (rep movsw)
- korzystanie z różnych segmentów pamięci

zegarek.png


Przedstawienie prac i wynik konkursu na YT.
https://www.youtube.com/watch?v=4gWVPkrv8ts

Przyznam że było bardzo dużo świetnych prac, zachęcam do obejrzenia filmiku na YT, można się zdziwić ile można zrobić w 512 bajtach.

Źródło ASM:

Kod: Zaznacz cały

[bits 16]
[org 0x7c00]
start:

%define petla_ile   16*8
%define vram_bufor  0x0800
%define vram_vga    0xb800
%define stos        0x07f0

;NOTES:
;B800:0000 - początek VRAM - tryb tekstowy
;8000:0000 - początek bufora
;AX - indeks pod który wielokrotnie kopiujemy wzorek do bufora
;BX - iterator, wielkokrotne kopiowane wzorka do bufora
;CX - iterator, kopiowanie do bufora i bufora do VRAM, instrukcje movsb stosb
;DX - DL kod koloru przy wrzucaniu wzorka do bufora

;VGA
;3D4h - Addres register
;3D5h - Data register
;0Ah  - Cursor Start register
;00100000 - cursor disable


;SEGMENT
;CS - Code Segment
;DS - Data Segment
;ES,FS,GS - Extra Segment
;SS - Stack Segment             -

;INDEX
;DI - Destination Index (ES:DI)
;SI - Source Index      (DS:SI)
;BP - Base Pointer      (SS:BP) -
;SP - Stack Pointer     (SS:SP) -
;IP - Index Pointer     (CS:IP) -

;###################################
;ustawienie stosu
;###################################

mov ax, stos
mov sp, ax

;###################################
;schowanie kursora
;###################################

mov al, 0x0A        ;Cursor Start register
mov dx, 0x3D4       ;Addres register
out dx, al
mov al, 0b00100000  ;Cursor disable
mov dx, 0x3D5       ;Data register
out dx, al

;###################################
;rejestracja obsługi przerwania w IVT
;###################################

;blokowanie cli nic nie daje, przewanie z timera jest NMI
cli

xor ax, ax
mov es, ax
mov bx, ax

mov word [es:bx+8*4+2], ax  ;segment
mov ax, IRQ0_handler
mov word [es:bx+8*4], ax    ;adres

;konfiguracja 8259 PIC  --  nie jest potrzebna, domyślna konfiguracja jest OK

; ICW 1
;mov al, 0x11
;out 0x20, al
;out 0xA0, al

; ICW 2
;mov al, 0x20
;out 0x21, al
;mov al, 0x28
;out 0xA1, al

; ICW 3
;mov al, 0x04
;out 0x21, al
;mov al, 0x02
;out 0xA1, al

; ICW 4
;mov al, 0x01
;out 0x21, al
;out 0xA1, al

;mov al, 0xfe   ;maskowanie przerwań, 1-blokuje, 0-aktywuje
;out 0x21, al   ;0xFE - odblokowane tylko INT 0
                ;0x01 - blokuje przerwanie z timera (IRQ 0)
;out 0xA1, al

sti

; zrobione

;###################################
;skok do głównego programu
;###################################
jmp word 0:code


;###################################
;IRQ0 Handler
;###################################
;Przerwanie jest wykonywane 18.2 razy na sekundę,
;zwiększa ono rejestr [rej_krok] o 1 przy każdym wywołanu,
;po przekroczeniu w rejestrze wartości 78, rejest jest zerowany.

IRQ0_handler:   
push ax
push di
push ds
xor di, di
mov ds, di
mov ax, [rej_krok]
inc ax
cmp ax,78
jle IRQ0_dalej
xor ax, ax
IRQ0_dalej:
mov [rej_krok], ax
mov al, 0x20            ;kasowanie przerwania w 8259
out 0x20, al
pop ds
pop di
pop ax
iret

;###################################
;Główna pętla
code:
;###################################

xor di, di      ;DI = 0000
mov ds, di      ;DS = 0000

;###################################

;ustawienie bufora: vram_bufor
mov ax, vram_bufor
mov es, ax      ;ES = vram_bufor

;###################################
;rysowanie kolorowego wzorka
;###################################

mov ax, [rej_krok]
mov [rej_przesuniecie], ax  ;kopiuje [rej_krok] do [rej_przesuniecie]
mov bx, petla_ile           ;ile razy ma być powtórzony wzorek,

petla_wzorka:

;wypisanie wzorka
mov ax, petla_ile
sub ax, bx

mov ax, [rej_przesuniecie]
shl ax, 1
mov di, ax ;DI - indeks pod który piszemy

;wybór koloru wzorka
mov dx, bx
and dx, 0b0000000000000011  ;maskowanie koloru
mov [rej_dx], dx
add dx, mapa_koloru
mov si, dx
mov dx, [si]    ;skopiowanie do DX kodu koloru

mov si, wzorek
mov cx, wzorek_dl
xor ax, ax

pisz_wzorek:
movsb
mov al, dl  ;kolor do AL
stosb
loop pisz_wzorek

;obliczanie przesunięcia wzorka
mov ax, [rej_przesuniecie]  ;wczytanie przesunęcia z pamięci
add ax, wzorek_dl
mov dx,[rej_dx]
cmp dl, 3
jne dalej_0
add ax, 39
dalej_0:
mov [rej_przesuniecie], ax  ;zapamiętanie przesunięcia w pamięci

dec bx
jnz petla_wzorka

;###################################
;skopiowanie tekstu do bufora
;###################################

mov di, (80*12+40-10)*2
mov si, text
mov cx, text_dl
;push bx
mov bx, [rej_krok]
shr bx, 1           
shl bx, 4           ;kolor tła
or bx, 0x0e         ;dodanie koloru czczionki do koloru tła

write:
movsb               ;mov byte DS:SI ->  ES:DI
mov al, bl          ;KOD KOLORU
stosb               ;store AL at address ES:DI
loop write
;pop bx

;###############################################
;odczyt godziny (tryb BCD) i zapisanie do bufora
;###############################################
clc
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
mov ah, 0x2
int 1ah
 
;przetwarzanie godziny
;godzina
xor ax, ax
mov al, ch
shr al, 4
add al, "0"
mov [data], al
 
mov al, ch
and al, 0b00001111
add al, "0"
mov [data+1], al
 
mov al,":"
mov [data+2], al
 
;minuta
mov al, cl
shr al, 4
add al, "0"
mov [data+3], al
 
mov al, cl
and al, 0b00001111
add al, "0"
mov [data+4], al
 
mov al,":"
mov [data+5], al
 
;sekunda
mov al, dh
shr al, 4
add al, "0"
mov [data+6], al
 
mov al, dh
and al, 0b00001111
add al, "0"
mov [data+7], al
 
mov al, " "
mov [data+8], al
mov [data+9], al
 
;wypisanie godziny
mov di, (80*13+40-4)*2
mov si, data
mov cx, data_dl-2
write2:
movsb
mov al, 4
stosb
loop write2
 
;#########################################
;odczyt daty i zapisanie do bufora
;#########################################

clc
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
mov ah, 0x4
int 1ah
 
;przetwarzanie daty
;century
xor ax, ax
mov al, ch
shr al, 4
add al, "0"
mov [data], al
 
mov al, ch
and al, 0b00001111
add al, "0"
mov [data+1], al
 
;rok
mov al, cl
shr al, 4
add al, "0"
mov [data+2], al
 
mov al, cl
and al, 0b00001111
add al, "0"
mov [data+3], al
 
mov al,"-"
mov [data+4], al
 
;miesiac
mov al, dh
shr al, 4
add al, "0"
mov [data+5], al
 
mov al, dh
and al, 0b00001111
add al, "0"
mov [data+6], al
 
mov al,"-"
mov [data+7], al
 
;dzien
mov al, dl
shr al, 4
add al, "0"
mov [data+8], al
 
mov al, dl
and al, 0b00001111
add al, "0"
mov [data+9], al
 
;wypisanie daty
mov di, (80*14+40-5)*2
mov si, data
mov cx, data_dl
write3:
movsb
mov al, 6
stosb
loop write3
 
;czekanie na klawisz
;xor ax, ax
;int 16h

;#########################################
; kopiowanie bufora do VRAM
;#########################################

;UWAGA zmiana segmentów ES i DS

mov ax, vram_vga
mov es, ax 
mov ax, vram_bufor
mov ds, ax
;mov cx, 80*25*2
mov cx, 80*25
mov si, 80*2      ;zamaskowanie górnej lini.
xor di, di
;rep movsb
rep movsw

jmp code
 
; stop
jmp $
 
;#########################################
;#########################################
;#########################################
;text  db "<HTTP://SPECCY.PL>"
text db " HTTP://MICROGEEK.EU "
text_dl equ $ - text

wzorek db 0,176,177,219,219,219,219,177,176,0
wzorek_dl equ $ - wzorek

mapa_koloru db 0x2,0xE,0x4,0x1

;TODO: to można umieścić poza pamiecią programu
rej_dx dw 0
rej_kolor dw 0
rej_przesuniecie dw 0
rej_krok dw 0
data times 10 db " "
data_dl equ $ - data

;#########################################
;uzupełnienie do 1,44MB
;#########################################

times (510-($-start)) db 0
db 0x55, 0xAA
times ((1440*1024)-($-start)) db 0

;#########################################
;kompilacja:
;nasm zegar.asm -o zegar.img
;#########################################

Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Gott weiß ich will kein Engel sein.

Awatar użytkownika
PROTON
Expert
Expert
Posty: 527
Rejestracja: czwartek 08 paź 2015, 18:35
Lokalizacja: Warszawa

Re: Program na konkurs OSDev

Postautor: PROTON » poniedziałek 20 cze 2016, 20:10

Gott weiß ich will kein Engel sein.

Awatar użytkownika
j23
Expert
Expert
Posty: 506
Rejestracja: czwartek 08 paź 2015, 18:40

Re: Program na konkurs OSDev

Postautor: j23 » poniedziałek 04 lip 2016, 07:20

Ja tylko dodam, że na stronie podanej przez Kolegę PROTON'a znajduje się paczka zip, a w niej wszystkie źródła z kodem assemblerowym. W sumie 14 różnych prac. Ocena jury.. Hmm... Rzecz gustu, ale w każdym razie inicjatywa była zacna. Jest na co popatrzeć. Polecam. Oglądając to należy brać pod uwagę, że każdy z tych kodów mieści się w/poniżej 0,5 kB.
Dobra robota Kolego PROTON!
Internet łączy ludzi, którzy dzielą się swoimi zainteresowaniami, pomysłami i potrzebami, bez względu na geograficzne (przeciwności).
BOB TAYLOR, PARC


Wróć do „Pisanie programów w Assembler”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 5 gości