1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@**********************************************************************/
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@void Filt_6k_7k(
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@     Word16 signal[],                      /* input:  signal                  */
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@     Word16 lg,                            /* input:  length of input         */
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@     Word16 mem[]                          /* in/out: memory (size=30)        */
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@)
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@******************************************************************
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ r0    ---  signal[]
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard@ r1    ---  lg
26b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard@ r2    ---  mem[]
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          .section  .text
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          .global  Filt_6k_7k_asm
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          .extern  voAWB_Copy
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          .extern  fir_6k_7k
3297e3e847179c17eb9059fb322413b6facd3e5a03Ard Biesheuvel          .hidden  fir_6k_7k
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
34e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardFilt_6k_7k_asm:
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
36b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          STMFD   		r13!, {r4 - r12, r14}
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SUB    		r13, r13, #240              @ x[L_SUBFR16k + (L_FIR - 1)]
38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r8, r0                      @ copy signal[] address
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r4, r1                      @ copy lg address
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r5, r2                      @ copy mem[] address
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r1, r13
43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r0, r2
44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r2, #30                     @ L_FIR - 1
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          BL      		voAWB_Copy                   @ memcpy(x, mem, (L_FIR - 1)<<1)
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
4774bc3e133bd59a65dbed70b5fc89549f04a545e2Ard Biesheuvel          ADR    		r3, Lable1                  @ get fir_7k address
4874bc3e133bd59a65dbed70b5fc89549f04a545e2Ard Biesheuvel          LDR   		r10, [r3]
4974bc3e133bd59a65dbed70b5fc89549f04a545e2Ard Biesheuvel          ADD   		r10, r3
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
51b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          MOV           	r14, #0
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV                   r3, r8                      @ change myMemCopy to Copy, due to Copy will change r3 content
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD     	    	r6, r13, #60                @ get x[L_FIR - 1] address
54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r7, r3                      @ get signal[i]
55e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardLOOP1:
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r8,  [r7], #2
57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r9,  [r7], #2
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r8, r8, ASR #2
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r9, r9, ASR #2
60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r11, [r7], #2
61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r12, [r7], #2
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r11, r11, ASR #2
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r12, r12, ASR #2
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r8, [r6], #2
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r9, [r6], #2
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r11, [r6], #2
67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r12, [r6], #2
68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r8,  [r7], #2
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r9,  [r7], #2
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r8, r8, ASR #2
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r9, r9, ASR #2
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r11, [r7], #2
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH         	r12, [r7], #2
74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r11, r11, ASR #2
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV           	r12, r12, ASR #2
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r8, [r6], #2
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r9, [r6], #2
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r11, [r6], #2
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH          	r12, [r6], #2
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD           	r14, r14, #8
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          CMP           	r14, #80
82b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          BLT           	LOOP1
83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STR     		r5, [sp, #-4]               @ PUSH  r5 to stack
86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          @ not use registers: r4, r10, r12, r14, r5
88b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          MOV     		r4, r13
89b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          MOV     		r5, #0                      @ i = 0
90e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardLOOP2:
91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR           	r0, [r10]
92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH  	        r1, [r4]                   @ load x[i]
94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH   	        r2, [r4, #60]              @ load x[i + 30]
95e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r6, [r4, #2]               @ load x[i + 1]
96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r7, [r4, #58]              @ load x[i + 29]
97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r1, r1, r2                 @ x[i] + x[i + 30]
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r6, r6, r7                 @ x[i + 1] + x[i + 29]
99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r8, [r4, #4]               @ load x[i + 2]
100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r9, [r4, #56]              @ load x[i + 28]
101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMULBB                r14, r1, r0                @ (x[i] + x[i + 30]) * fir_7k[0]
103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r8, r8, r9                 @ x[i + 2] + x[i + 28]
104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABT                r14, r6, r0, r14           @ (x[i + 1] + x[i + 29]) * fir_7k[1]
105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR                   r0, [r10, #4]
107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r1, [r4, #6]               @ load x[i+3]
108e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r2, [r4, #54]              @ load x[i+27]
109e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r6, [r4, #8]               @ load x[i+4]
110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r7, [r4, #52]              @ load x[i+26]
111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r1, r1, r2                 @ x[i+3] + x[i+27]
112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r6, r6, r7                 @ x[i+4] + x[i+26]
113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABB                r14, r8, r0, r14           @ (x[i + 2] + x[i + 28]) * fir_7k[2]
114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r8, [r4, #10]              @ load x[i+5]
115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r9, [r4, #50]              @ load x[i+25]
116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABT                r14, r1, r0, r14           @ (x[i+3] + x[i+27]) * fir_7k[3]
117b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          ADD                   r8, r8, r9                 @ x[i+5] + x[i+25]
118b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
119e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR                   r0, [r10, #8]
120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r1, [r4, #12]              @ x[i+6]
121e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r2, [r4, #48]              @ x[i+24]
122e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABB                r14, r6, r0, r14           @ (x[i+4] + x[i+26]) * fir_7k[4]
123b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          LDRSH                 r6, [r4, #14]              @ x[i+7]
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r7, [r4, #46]              @ x[i+23]
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABT                r14, r8, r0, r14           @ (x[i+5] + x[i+25]) * fir_7k[5]
126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR                   r0, [r10, #12]
127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r1, r1, r2                 @ (x[i+6] + x[i+24])
128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r6, r6, r7                 @ (x[i+7] + x[i+23])
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABB                r14, r1, r0, r14           @ (x[i+6] + x[i+24]) * fir_7k[6]
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r8, [r4, #16]              @ x[i+8]
131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          LDRSH                 r9, [r4, #44]              @ x[i+22]
132b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          SMLABT                r14, r6, r0, r14           @ (x[i+7] + x[i+23]) * fir_7k[7]
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR                   r0, [r10, #16]
134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r1, [r4, #18]              @ x[i+9]
135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r2, [r4, #42]              @ x[i+21]
136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r6, [r4, #20]              @ x[i+10]
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r7, [r4, #40]              @ x[i+20]
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r8, r8, r9                 @ (x[i+8] + x[i+22])
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r1, r1, r2                 @ (x[i+9] + x[i+21])
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r6, r6, r7                 @ (x[i+10] + x[i+20])
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABB                r14, r8, r0, r14           @ (x[i+8] + x[i+22]) * fir_7k[8]
142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r8, [r4, #22]              @ x[i+11]
143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r9, [r4, #38]              @ x[i+19]
144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABT                r14, r1, r0, r14           @ (x[i+9] + x[i+21]) * fir_7k[9]
145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR                   r0, [r10, #20]
146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r1, [r4, #24]              @ x[i+12]
147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r2, [r4, #36]              @ x[i+18]
148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABB                r14, r6, r0, r14           @ (x[i+10] + x[i+20]) * fir_7k[10]
149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r6, [r4, #26]              @ x[i+13]
150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          ADD                   r8, r8, r9                 @ (x[i+11] + x[i+19])
151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r7, [r4, #34]              @ x[i+17]
152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABT                r14, r8, r0, r14           @ (x[i+11] + x[i+19]) * fir_7k[11]
153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR                   r0, [r10, #24]
154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r1, r1, r2                 @ x[i+12] + x[i+18]
155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r8, [r4, #28]              @ x[i+14]
156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABB                r14, r1, r0, r14           @ (x[i+12] + x[i+18]) * fir_7k[12]
157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r6, r6, r7                 @ (x[i+13] + x[i+17])
158b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          LDRSH                 r9, [r4, #32]              @ x[i+16]
159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABT                r14, r6, r0, r14           @ (x[i+13] + x[i+17]) * fir_7k[13]
160b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          LDR                   r0, [r10, #28]
161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD                   r8, r8, r9                 @ (x[i+14] + x[i+16])
162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDRSH                 r1, [r4, #30]              @ x[i+15]
163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          SMLABB                r14, r8, r0, r14           @ (x[i+14] + x[i+16]) * fir_7k[14]
164b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          SMLABT                r14, r1, r0, r14           @ x[i+15] * fir_7k[15]
165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD     		r5, r5, #1
167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD     		r14, r14, #0x4000
168b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          ADD     		r4, r4, #2
169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r1, r14, ASR #15
170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          CMP     		r5, #80
171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          STRH    		r1, [r3], #2               @signal[i] = (L_tmp + 0x4000) >> 15
172b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          BLT     		LOOP2
173b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          LDR     		r1, [sp, #-4]               @mem address
175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          ADD     		r0, r13, #160               @x + lg
176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          MOV     		r2, #30
177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          BL      		voAWB_Copy
178b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
179e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardFilt_6k_7k_end:
180b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          ADD     		r13, r13, #240
181b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          LDMFD   		r13!, {r4 - r12, r15}
182b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
183e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardLable1:
18474bc3e133bd59a65dbed70b5fc89549f04a545e2Ard Biesheuvel          .word   		fir_6k_7k-Lable1
185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard          @ENDFUNC
1863f7149c1c8f211c9ef5eb6c4012f078d9d08387bChih-Hung Hsieh          .end
187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
189