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: 504
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: 504
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
User
User
Posty: 421
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!
Chcę wiedzieć, jak Bóg stworzył ten świat. Nie interesuje mnie to czy inne zjawisko. Chcę znać Jego myśli, reszta to szczegóły.
ALBERT EINSTEIN


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 1 gość