;######################################################;
; Funkcja:      Skalowanie - Interpolacja dwuliniowa    ;
; Autor:        Jacek 'jsxm' Szwaj, grupa: K1I3         ;
;######################################################;
                                                                ;
section .bss                                                    ; Deklaracja zmiennych
        no_x:  resd 1                                           ;
        no_y:  resd 1                                           ;
        st_x:  resd 1                                           ;
        st_y:  resd 1                                           ;
        rt_x:  resd 4                                           ;
        rt_y:  resd 4                                           ;
        tm_x:  resd 4                                           ;
        tm_x_int:      resd 4                                       ;
        tm_y:  resd 4                                           ;
        tm_y_int:      resd 4                                       ;
        tm_a:  resd 4                                           ;
        tm_b:  resd 4                                           ;
        licz_1: resd 4                                 ;
        licz_2: resd 4                                 ;
        ebp_8: resd 4                                          ;
        ebp_12: resd 4                                 ;
        wiersz: resd 4                                 ;
        ten_adr: resd 4                                        ;
        tmp_1: resd 1                                          ;  
        tmp_2: resd 1                                          ;
        f00: resd 1                                            ;
        f01: resd 1                                            ;
        f10: resd 1                                            ;
        f11: resd 1                                            ;
        fa0: resd 1                                            ;
        fa1: resd 1                                            ;
        fab: resd 1                                            ;
                                                                ;
;#######################################################
                                                                ;
section .text                                                   ;
global scale_x86                                                ;
                                                                ;
scale_x86:                                                      ; Pocztek funkcji
        push   ebp                                              ; Epilog
        mov    ebp, esp                                  ;
                                                                ;
        xor    eax, eax                                   ; Zerowanie EAX i EBX
        xor    ebx, ebx                                   ;            
                                                                ;
        mov    ebx, DWORD [ebp+28]                               ; Pobranie starej wysokosci bitmapy i zapisanie do odpowiedniej zmiennej
        mov    eax, st_y                                 ;
        mov    DWORD [eax], ebx                          ;
                                                                ;
        mov    ebx, DWORD [ebp+24]                               ; Pobranie starej szerokosci bitmapy i zapisanie do odpowiedniej zmiennej
        mov    eax, st_x                                 ;
        mov    DWORD [eax], ebx                          ;
                                                                ;
        mov    ebx, DWORD [ebp+8]                                ; Pobranie adresu starej pamieci i zapisanie do odpowiedniej zmiennej
        mov    eax, ebp_8                                        ;
        mov    DWORD [eax], ebx                          ;
                                                                ;
        mov    ebx, DWORD [ebp+12]                               ; Pobranie adresu nowej pamieci i zapisanie do odpowiedniej zmiennej
        mov    eax, ebp_12                                       ;
        mov    DWORD [eax], ebx                          ;
                                                                ;
        mov    ebx, DWORD [ebp+16]                               ; Pobranie nowej wysokosci bitmapy i zapisanie do odpowiedniej zmiennej
        mov    eax, no_y                                 ;
        mov    DWORD [eax], ebx                          ;
        mov    eax, licz_1                                       ;
        mov    DWORD [eax], 0                       ;
                                                                ;
        mov    ebx, DWORD [ebp+20]                               ; Pobranie nowej szerokosci bitmapy i zapisanie do odpowiedniej zmiennej
        mov    eax, no_x                                 ;
        mov    DWORD [eax], ebx                          ;
        mov    eax, licz_2                                       ;
        mov    DWORD [eax], 0                       ;
                                                                ;
        finit                                                  ; Inicjalizacja koprocesora
                                                                ; 
                fstcw         WORD[tmp_1]                            ; Ustawinie flagi c1 koprocesora na 0 aby zaokraglac w dol !
                mov   ax, WORD[tmp_1]                  ; 
                or    ax, 0xc00;                        ;
                mov   ebx, tmp_1                               ;
                mov   WORD [ebx], ax                   ;
                fldcw         WORD[tmp_1]                            ;
                                                                ;
        fild   DWORD [st_x]                                      ; Dzielna, pobranie
        fild   DWORD [no_y]      ; celowo odwrotnie           ; Dzielnik, pobranie
        fdivp  st1                                              ; Dzielenie
        fstp   DWORD [rt_x]                                      ; Zapisanie ilorazu, nasze ratio_x
                                                                ;      
        fild   DWORD [st_y]                                      ; Dzielna, pobranie
        fild   DWORD [no_x]      ; celowo odwrotnie           ; Dzielnik, pobranie
        fdivp  st1                                              ; Dzielenie
        fstp   DWORD [rt_y]                                      ; Zapisanie ilorazu, nasze ratio_y
                                                                ;
        mov    edx, DWORD [ebp_12]                               ; Zaladowanie adresu docelowej tablicy do zmiennej wiersz
        mov    eax, wiersz                                       ;
        mov    DWORD [eax], edx                          ;
;#######################################################                                
                                                                ;
petla_1:                                                        ;
        mov    edx, DWORD [licz_1]                               ; Pobranie licznika petli zewnetrznej
        cmp    edx, 128                                  ; Warunek zakonczenia petli [1]
        jz near        wyskocz_petla_1                        ;
                                                                ;
        petla_2:                                               ;
                mov   ebx, DWORD [licz_2]                      ; Pobranie licznika petli zewnetrznej
                cmp   ebx, 64;                         ; Warunek zakonczenia petli [2]
                jz near       wyskocz_petla_2               ;
                                                                
                fild  DWORD [licz_1]                   ; Czynnik, pobranie
                fld   DWORD [rt_x]                              ; Czynnik, pobranie, fld zmiennoprzcinkowe
                fmulp st1                                     ; Mnoenie
                fstp  DWORD [tm_x]                             ; Zapisanie iloczynu, nasze tmp_x

                fild  DWORD [licz_2]                   ; Czynnik, pobranie
                fld   DWORD [rt_y]                              ; Czynnik, pobranie, fld zmiennoprzcinkowe
                fmulp st1                                     ; Mnoenie
                fstp  DWORD [tm_y]                             ; Zapisanie iloczynu, nasze tmp_y
                
                fld   DWORD [tm_x]                              ; Obliczenie tmp_a
                frndint                                       ;
                fst   DWORD [tm_x_int]
                fld   DWORD [tm_x]                              ;
                fxch  st0, st1                         ;
                fsubp  st1, st0                               ;
                fstp  DWORD [tm_a]                             ;
                                                                ;
                fld   DWORD [tm_y]                              ; Obliczenie tmp_b
                frndint                                       ; 
                fst   DWORD [tm_y_int]
                fld   DWORD [tm_y]                              ;
                fxch  st0, st1                         ;
                fsubp  st1, st0                               ;
                fstp  DWORD [tm_b]                             ;
pocz_pobr:
                mov   eax, DWORD [ebp_8]                       ; Pobranie adresu poczatku bufora danych
                                                                ;              
                fld1                                          ;           12
                fld1                                          ;           12
                faddp st1, st0                                ;           12
                fld1                                          ;           12
                fld1                                          ;           12
                faddp st1, st0                                ;           12
                fmulp st1, st0                                ;           12
                fld1                                          ;           12
                fld1                                          ;           12
                faddp st1, st0                                ;           12
                fld1                                          ;           12
                faddp st1, st0                                ;           12
                fmulp st1, st0                                ;           12
test_1:
                fild  DWORD [st_x]                             ; Obliczanie odlegoci od poczatku tablicy
                fld   DWORD [tm_x_int]                  ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_y_int]                  ;
                faddp st1, st0                                ;  
                fmulp st1, st0                                ;
                fistp DWORD [ten_adr]                 ;

                mov   ebx, DWORD [ten_adr]                      ; 
                add   eax, ebx                          ; Dodanie obliczonej odleglosci do poczatku bufora
                xor   edx, edx                         ;

                mov   edx, DWORD [eax]                 ;  pobranie f00      
spr1:  
                mov   ebx, f00                         ;
                mov   DWORD [ebx], edx                 ;


                mov   edx, DWORD [eax+12*32];[eax+12]  ;  pobranie f10
spr2:  
                mov   ebx, f10                         ;
                mov   DWORD [ebx], edx                 ;


                mov   edx, DWORD [eax+12];[eax];               ;  pobranie f01
spr3:  
                mov   ebx, f01                         ;
                mov   DWORD [ebx], edx                 ;

                mov   edx, DWORD [eax+12*32+12]                ;  pobranie f11      
spr4:  
                mov   ebx, f11                         ;
                mov   DWORD [ebx], edx                 ;
obl:
                fld1                                          ;
                fld   DWORD [tm_a]                              ; obliczanie fa0 w FPU
                fsubp  st1, st0                               ;
                fild  DWORD [f00]                              ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_a]                              ;
                fild  DWORD [f10]                              ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fstp  DWORD [fa0]                              ;
                                                                ;
                fld1                                          ;
                fld   DWORD [tm_a]                              ; obliczanie fa1 w FPU
                fsubp  st1, st0                               ;
                fild  DWORD [f01]                              ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_a]                              ;
                fild  DWORD [f11]                              ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fstp  DWORD [fa1]                              ;

                fld1                                          ;
                fld   DWORD [tm_b]                              ; obliczanie fab w FPU
                fsubp  st1, st0                               ;
                fld   DWORD [fa0]                               ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_b]                              ;
                fld   DWORD [fa1]                               ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fistp DWORD [fab]                             ;

                xor   ebx, ebx                         ;
                mov   ebx, DWORD [wiersz]                      ; Pobranie adresu pod ktory zapiszemy obliczony kolor

                xor   edx, edx                         ;
                mov   edx, DWORD [fab] ;[fab]          ;
bp_1:
                mov   DWORD[ebx], edx                  ; Zapis obliczonego koloru [NIEBIESKI]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                xor   edx, edx                         ;
                mov   edx, DWORD [eax+4]                       ;  pobranie f00    
        
                mov   ebx, f00                         ;
                mov   DWORD [ebx], edx                 ;


                mov   edx, DWORD [eax+12*32+4]         ;  pobranie f10        
        
                mov   ebx, f10                         ;
                mov   DWORD [ebx], edx                 ;


                mov   edx, DWORD [eax+16];                     ;  pobranie f01
        
                mov   ebx, f01                         ;
                mov   DWORD [ebx], edx                 ;

                mov   edx, DWORD [eax+12*32+16]                ;  pobranie f11      
        
                mov   ebx, f11                         ;
                mov   DWORD [ebx], edx                 ;

                fld1                                          ;
                fld   DWORD [tm_a]                              ; obliczanie fa0 w FPU
                fsubp  st1, st0                               ;
                fild  DWORD [f00]                              ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_a]                              ; interpolacja w kierunku poziomym
                fild  DWORD [f10]                              ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fstp  DWORD [fa0]                              ;
                                                                ;
                fld1                                          ;
                fld   DWORD [tm_a]                              ; obliczanie fa1 w FPU
                fsubp  st1, st0                               ;
                fild  DWORD [f01]                              ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_a]                              ; interpolacja w kierunku poziomym
                fild  DWORD [f11]                              ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fstp  DWORD [fa1]                              ;

                fld1                                          ;
                fld   DWORD [tm_b]                              ; obliczanie fab w FPU
                fsubp  st1, st0                               ;
                fld   DWORD [fa0]                               ;
                fmulp st1, st0                                ; interpolacja w kierunku pionowym
                fld   DWORD [tm_b]                              ;
                fld   DWORD [fa1]                               ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fistp DWORD [fab]                             ;

                xor   ebx, ebx                         ;
                mov   ebx, DWORD [wiersz]                      ;

                xor   edx, edx                         ;
                mov   edx, DWORD [fab] ;[fab]          ;

                mov   DWORD[ebx+4], edx                        ; Zapis obliczonego koloru [ZIELONY]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                xor   edx, edx                         ;
                mov   edx, DWORD [eax+8]                       ;  pobranie f00    
                mov   ebx, f00                         ;
                mov   DWORD [ebx], edx                 ;


                mov   edx, DWORD [eax+12*32+8];[eax+12]        ;  pobranie f10
                mov   ebx, f10                         ;
                mov   DWORD [ebx], edx                 ;


                mov   edx, DWORD [eax+20];[eax+8];     ;  pobranie f01
                mov   ebx, f01                         ;
                mov   DWORD [ebx], edx                 ;

                mov   edx, DWORD [eax+12*32+20]                ;  pobranie f11      
                mov   ebx, f11                         ;
                mov   DWORD [ebx], edx                 ;

                fld1                                          ;
                fld   DWORD [tm_a]                              ; obliczanie fa0 w FPU
                fsubp  st1, st0                               ;
                fild  DWORD [f00]                              ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_a]                              ;
                fild  DWORD [f10]                              ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fstp  DWORD [fa0]                              ;
                                                                ;
                fld1                                          ;
                fld   DWORD [tm_a]                              ; obliczanie fa1 w FPU
                fsubp  st1, st0                               ;
                fild  DWORD [f01]                              ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_a]                              ;
                fild  DWORD [f11]                              ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fstp  DWORD [fa1]                              ;

                fld1                                          ;
                fld   DWORD [tm_b]                              ; obliczanie fab w FPU
                fsubp  st1, st0                               ;
                fld   DWORD [fa0]                               ;
                fmulp st1, st0                                ;
                fld   DWORD [tm_b]                              ;
                fld   DWORD [fa1]                               ;
                fmulp st1, st0                                ;
                faddp st1, st0                                ;
                fistp DWORD [fab]                             ;

                xor   ebx, ebx                         ;
                mov   ebx, DWORD [wiersz]                      ;

                xor   edx, edx                         ;
                mov   edx, DWORD [fab] ;[fab]          ;

                mov   DWORD[ebx+8], edx                        ; Zapis obliczonego koloru [CZERWONY]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                                                ;
                        mov  ebx, DWORD [wiersz]             ; Przejscie do kolejnego piksela
                        add  ebx, 12                  ;
                        mov  edx, wiersz                     ;
                        mov  DWORD [edx], ebx                ;
                                                                ;
                ;;;;;;;;;;;;;;;;;;;;;;;;;                     ;
                mov   ebx, DWORD [licz_2]                      ; Inkrementacja licznika petli wewnetrznej
                inc   ebx                                       ;
                mov   edx, licz_2                              ;
                mov   DWORD [edx], ebx                 ;
                                                                ;
               jmp petla_2                                     ; koniec [2]

wyskocz_petla_2:
                                                                ;
                mov   eax, licz_2                              ; Zaladowanie wartosci licznika petli wewnetrznej [2]
                mov   DWORD [eax], 0             ;
                                                                ;
        mov    ebx, DWORD [licz_1]                               ; Inkrementacja licznika petli zewnetrznej
        inc    ebx                                                ;
        mov    eax, licz_1                                       ;
        mov    DWORD [eax], ebx                          ;
                                                                ;
        jmp    petla_1                                   ; koniec [1]

wyskocz_petla_1:
                                                                ;
epilog:                                                 ; Epilog
        mov    esp, ebp                                  ;
        pop    ebp                                               ;
        ret                                                    ;
                                                                ;
;#######################################################