;------------------------------------------------------------------------------
;       FYEO
;       Frank Lyonnet 1993
;       Fonctions de conversion de couleur
;       Author : Frederic Elisei
;------------------------------------------------------------------------------

                GET     h.ASMRegs
                GET     h.SWInames

                AREA |C$$code|, CODE, READONLY

;------------------------------------------------------------------------------
;       yuv_to_gcol_convert_floyd
;------------------------------------------------------------------------------
;       parametre no 1 : pointeur vers le rouge
;       parametre no 2 : pointeur vers le vert
;       parametre no 3 : pointeur vers le bleu
;       parametre no 4 : pointeur vers le resultat
;       parametre no 5 : longueur d'une ligne
;       parametre no 6 : pointeur vers la table de dithering
;       parametre no 7 : pointeur vers le buffer
;------------------------------------------------------------------------------

PAS     EQU     1

ARD     RN      0
AGR     RN      1
ABL     RN      2
DST     RN      3
LON     RN      4
RD      RN      5
GR      RN      6
BL      RN      7
COL     RN      8
ERD     RN      9
EGR     RN      10
EBL     RN      11
TBL     RN      12
EPT     RN      13
TMP     RN      14

                EXPORT  |yuv_to_gcol_convert_floyd|
|yuv_to_gcol_convert_floyd|


                ;Sauve tout les regs , r13 preserve par le code
                STMFD   sp!, {r4-r12,r14}

                ;Recup des parms sur la pile
                LDR     LON,[sp,#((10)*4)]            ;Longueur ligne
                LDR     TBL,[sp,#((10)*4+4)]          ;Pointeur table
                LDR     EBL,[sp,#((10)*4+4+4)]        ;Pointeur buffer
FLOYD
                LDR     ERD,=STORETBL                   ;Adresse table
                STR     TBL,[ERD]

                LDR     ERD,=STOREBUF                   ;Adress buffer erreur
                STR     EBL,[ERD]

                LDR     ERD,=RET14
                STR     r14,[ERD]

                LDR     ERD,=RET13
                STR     r13,[ERD]

                MOV     EPT,EBL                         ;EPT = adr buff erreur

                LDRB ERD,[EPT]                          ;ERD = BufEr[0]
                LDRB TMP,[EPT,#3]                       ;TMP = BufEr[3]
                ADD ERD,ERD,TMP                         ;ERD = BufEr[0] + BufEr[3]
                LDRB EGR,[EPT,#1]                       ;EGR = BufEr[1]
                LDRB TMP,[EPT,#4]                       ;TMP = BufEr[4]
                ADD EGR,EGR,TMP                         ;EGR = BufEr[1] + BufEr[4]
                LDRB EBL,[EPT,#2]                       ;EBL = BufEr[2]
                LDRB TMP,[EPT,#5]                       ;TMP = BufEr[5]
                ADD EBL,EBL,TMP                         ;EBL = BufEr[2] + BufEr[5]

                MOV ERD,ERD,LSL#24                      ;Signe ERD
                MOV ERD,ERD,ASR#24
                MOV EGR,EGR,LSL#24                      ;Signe EGR
                MOV EGR,EGR,ASR#24
                MOV EBL,EBL,LSL#24                      ;Signe EBL
                MOV EBL,EBL,ASR#24

                MOV TMP,#0
                STRB TMP,[EPT]                          ;BufEr[0] = 0
                STRB TMP,[EPT,#1]                       ;BufEr[1] = 0
                STRB TMP,[EPT,#2]                       ;BufEr[2] = 0
                STRB TMP,[EPT,#3]                       ;BufEr[3] = 0
                STRB TMP,[EPT,#4]                       ;BufEr[4] = 0
                STRB TMP,[EPT,#5]                       ;BufEr[5] = 0

                LDR     TMP,=STORETBL
                LDR     TBL,[TMP]                       ;TBL = adr table


AFFF            LDRB RD,[ARD],#PAS                      ;RD = Red[i++]
                ADDS RD,RD,ERD                          ;RD = Red[i] + CurErrRed
                MOVMI RD,#0
                CMP RD,#255
                MOVGT RD,#255                           ;range_limiting(0,255)

                LDRB GR,[AGR],#PAS                      ;GR = Green[i++]
                ADDS GR,GR,EGR                          ;GR = Green[i] + CurErrGreen
                MOVMI GR,#0
                CMP GR,#255
                MOVGT GR,#255                           ;range_limiting(0,255)

                LDRB BL,[ABL],#PAS                      ;BL = Blue[i++]
                ADDS BL,BL,EBL                          ;BL = Blue[i] + CurErrBlue
                MOVMI BL,#0
                CMP BL,#255
                MOVGT BL,#255                           ;range_limiting(0,255)

                ADD ERD,RD,#8
                CMP ERD,#255
                MOVGT ERD,#255                          ;Arrondi au 4e bit
                ADD EGR,GR,#8
                CMP EGR,#255
                MOVGT EGR,#255                          ;Arrondi au 4e bit
                ADD EBL,BL,#8
                CMP EBL,#255
                MOVGT EBL,#255                          ;Arrondi au 4e bit

                AND ERD,ERD,#&F0                        ;Calcul index table
                MOV EBL,EBL,LSR#4                       ;4 bit Red, 4 bit Green, 4 bit Blue
                ADD ERD,ERD,EGR,LSR#4                   ;0-3 = blue, 4-7 = green, 8-11 = red
                ADD ERD,TBL,ERD,LSL#6                   ;En 2 temps
                LDR COL,[ERD,EBL,LSL#2]                 ;Tableau de mot de 32 bits, 0-7 = couleur

                STRB COL,[DST],#1                       ;Out[i++] = GCOL

                SUB ERD,RD,COL,LSR#24                   ;Le mot contient les vrai couleurs
                MOV COL,COL,LSL#8                       ;Calcul des nouvelles erreurs
                SUB EGR,GR,COL,LSR#24                   ;Red,Green,Blue
                MOV COL,COL,LSL#8
                SUB EBL,BL,COL,LSR#24


                ;Repartitions des erreurs au points voisins dans le BufEr
                ;ROUGE

                ADD COL,ERD,ERD,LSL#1  ; 3*
                ADD COL,COL,#8
                SUB TMP,ERD,COL,ASR#4
                LDRB RD,[EPT]
                ADD RD,RD,COL,ASR#4
                STRB RD,[EPT]

                ADD COL,ERD,ERD,LSL#2  ; 5*
                ADD COL,COL,#8
                SUB TMP,TMP,COL,ASR#4
                LDRB RD,[EPT,#3]
                ADD RD,RD,COL,ASR#4
                STRB RD,[EPT,#3]

                ADD ERD,ERD,#8
                SUB TMP,TMP,ERD,ASR#4
                MOV ERD,ERD,ASR#4
                LDRB COL,[EPT,#6]
                STRB ERD,[EPT,#6]
                MOV COL,COL,LSL#24
                MOV COL,COL,ASR#24
                ADD ERD,COL,TMP

 ; GREEN

                ADD COL,EGR,EGR,LSL#1  ; 3*
                ADD COL,COL,#8
                SUB TMP,EGR,COL,ASR#4
                LDRB RD,[EPT,#1]
                ADD RD,RD,COL,ASR#4
                STRB RD,[EPT,#1]

                ADD COL,EGR,EGR,LSL#2  ; 5*
                ADD COL,COL,#8
                SUB TMP,TMP,COL,ASR#4
                LDRB RD,[EPT,#4]
                ADD RD,RD,COL,ASR#4
                STRB RD,[EPT,#4]

                ADD EGR,EGR,#8
                SUB TMP,TMP,EGR,ASR#4
                MOV EGR,EGR,ASR#4
                LDRB COL,[EPT,#7]
                STRB EGR,[EPT,#7]
                MOV COL,COL,LSL#24
                MOV COL,COL,ASR#24
                ADD EGR,COL,TMP

 ; BLEU

                ADD COL,EBL,EBL,LSL#1  ; 3*
                ADD COL,COL,#8
                SUB TMP,EBL,COL,ASR#4
                LDRB RD,[EPT,#2]
                ADD RD,RD,COL,ASR#4
                STRB RD,[EPT,#2]

                ADD COL,EBL,EBL,LSL#2  ; 5*
                ADD COL,COL,#8
                SUB TMP,TMP,COL,ASR#4
                LDRB RD,[EPT,#5]
                ADD RD,RD,COL,ASR#4
                STRB RD,[EPT,#5]

                ADD EBL,EBL,#8
                SUB TMP,TMP,EBL,ASR#4
                MOV EBL,EBL,ASR#4
                LDRB COL,[EPT,#8]
                STRB EBL,[EPT,#8]
                MOV COL,COL,LSL#24
                MOV COL,COL,ASR#24
                ADD EBL,COL,TMP

                ADD EPT,EPT,#3
                SUBS LON,LON,#PAS
                BNE AFFF

                LDR DST,=RET14
                LDR r14,[DST]
                LDR DST,=RET13
                LDR r13,[DST]

                LDMFD   sp!, {r4-r12,r15} ; RICK 2004/01/29 removed '^'

                EXPORT  |init_yuv_to_gcol_convert|

|init_yuv_to_gcol_convert|

                STMFD   sp!, {r0-r12,r14}

                MOV DST,r0
                MOV LON,r1
                MOV RD,#0

NUL             STRB RD,[DST],#1
                STRB RD,[DST],#1
                STRB RD,[DST],#1
                SUBS LON,LON,#1
                BNE NUL

                LDMFD   sp!, {r0-r12,r15} ; RICK 2004/01/29 removed '^'

                AREA |C$$data|

RET13           DCD 0
RET14           DCD 0
STORETBL        DCD 0
STOREBUF        DCD 0

                END
