Subversion Repositories freemyipod

Rev

Rev 492 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 492 Rev 540
Line 89... Line 89...
89
}
89
}
90
 
90
 
91
void displaylcd_sync() ICODE_ATTR;
91
void displaylcd_sync() ICODE_ATTR;
92
void displaylcd_sync()
92
void displaylcd_sync()
93
{
93
{
94
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
-
 
95
    while (displaylcd_busy()) sleep(100);
94
    while (displaylcd_busy()) sleep(100);
96
    mutex_unlock(&lcd_mutex);
-
 
97
}
95
}
98
 
96
 
99
void displaylcd_setup(unsigned int startx, unsigned int endx,
97
void displaylcd_setup(unsigned int startx, unsigned int endx,
100
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
98
                      unsigned int starty, unsigned int endy) ICODE_ATTR;
101
void displaylcd_setup(unsigned int startx, unsigned int endx,
99
void displaylcd_setup(unsigned int startx, unsigned int endx,
102
                      unsigned int starty, unsigned int endy)
100
                      unsigned int starty, unsigned int endy)
103
{
101
{
104
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
-
 
105
    displaylcd_sync();
102
    displaylcd_sync();
-
 
103
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
106
    if (lcd_detect() == 2)
104
    if (lcd_detect() == 2)
107
    {
105
    {
108
        lcd_send_cmd(0x50);
106
        lcd_send_cmd(0x50);
109
        lcd_send_data(startx);
107
        lcd_send_data(startx);
110
        lcd_send_cmd(0x51);
108
        lcd_send_cmd(0x51);
Line 188... Line 186...
188
    mutex_unlock(&lcd_mutex);
186
    mutex_unlock(&lcd_mutex);
189
}
187
}
190
 
188
 
191
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
189
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
192
                       unsigned int height, void* data, unsigned int datax,
190
                       unsigned int height, void* data, unsigned int datax,
193
                       unsigned int datay, unsigned int stride, bool solid) ICODE_ATTR;
191
                       unsigned int datay, unsigned int stride, bool solid)
-
 
192
     ICODE_ATTR __attribute__((naked,noinline));
194
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
193
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
195
                       unsigned int height, void* data, unsigned int datax,
194
                       unsigned int height, void* data, unsigned int datax,
196
                       unsigned int datay, unsigned int stride, bool solid)
195
                       unsigned int datay, unsigned int stride, bool solid)
197
{
196
{
-
 
197
    __asm__ volatile("    muls r12, r2, r3             \n");
198
    int pixels = width * height;
198
    __asm__ volatile("    bxeq lr                      \n");
-
 
199
    __asm__ volatile("    stmfd sp!, {r2-r11,lr}       \n");
-
 
200
    __asm__ volatile("    mov r12, r2                  \n");
-
 
201
    __asm__ volatile("    add r8, r2, r2,lsl#1         \n");
-
 
202
    __asm__ volatile("    add r3, r1, r3               \n");
-
 
203
    __asm__ volatile("    sub r3, r3, #1               \n");
-
 
204
    __asm__ volatile("    mov r2, r1                   \n");
-
 
205
    __asm__ volatile("    add r1, r0, r12              \n");
-
 
206
    __asm__ volatile("    sub r1, r1, #1               \n");
199
    if (pixels <= 0) return;
207
    __asm__ volatile("    bl displaylcd_setup          \n");
-
 
208
    __asm__ volatile("    mov r0, r8                   \n");
200
    displaylcd_setup(x, x + width - 1, y, y + height - 1);
209
    __asm__ volatile("    bl malloc                    \n");
-
 
210
    __asm__ volatile("    cmp r0, #0                   \n");
201
    int corrsize = width * 3;
211
    __asm__ volatile("    beq displaylcd_dither_unlock \n");
-
 
212
    __asm__ volatile("    mov r2, r8                   \n");
-
 
213
    __asm__ volatile("    mov r1, #0                   \n");
-
 
214
    __asm__ volatile("    mov r8, r0                   \n");
-
 
215
    __asm__ volatile("    bl memset                    \n");
-
 
216
    __asm__ volatile("    ldr r0, [sp,#0x30]           \n");
-
 
217
    __asm__ volatile("    ldr r1, [sp,#0x34]           \n");
-
 
218
    __asm__ volatile("    ldr r11, [sp,#0x38]          \n");
-
 
219
    __asm__ volatile("    ldr r3, [sp,#0x2c]           \n");
-
 
220
    __asm__ volatile("    mla r0, r1, r11, r0          \n");
-
 
221
    __asm__ volatile("    ldr r12, [sp,#0x04]          \n");
-
 
222
    __asm__ volatile("    ldr r2, [sp,#0x3c]           \n");
-
 
223
    __asm__ volatile("    add r3, r3, r0,lsl#1         \n");
-
 
224
    __asm__ volatile("    cmp r2, #0                   \n");
-
 
225
    __asm__ volatile("    ldreq r1, [sp]               \n");
-
 
226
    __asm__ volatile("    add r3, r3, r0               \n");
-
 
227
    __asm__ volatile("    subeq r11, r11, r1           \n");
202
    signed char* corr = (signed char*)malloc(corrsize);
228
    __asm__ volatile("    add r11, r11, r11,lsl#1      \n");
-
 
229
    __asm__ volatile("    movne r10, #3                \n");
-
 
230
    __asm__ volatile("    moveq r10, #0                \n");
-
 
231
    __asm__ volatile("    ldr r9, =0x38600040          \n");
-
 
232
    __asm__ volatile("displaylcd_dither_y:             \n");
-
 
233
    __asm__ volatile("    ldr lr, [sp]                 \n");
-
 
234
    __asm__ volatile("    mov r4, #0                   \n");
-
 
235
    __asm__ volatile("    mov r5, #0                   \n");
-
 
236
    __asm__ volatile("    mov r6, #0                   \n");
203
    if (!corr)
237
    __asm__ volatile("    mov r7, r8                   \n");
204
    {
-
 
205
        mutex_unlock(&lcd_mutex);
238
    __asm__ volatile("displaylcd_dither_x:             \n");
-
 
239
    __asm__ volatile("    mov r2, #0                   \n");
206
        return;
240
    __asm__ volatile("    ldrb r1, [r3], #1            \n");
207
    }
-
 
-
 
241
    __asm__ volatile("    ldrsb r0, [r7]               \n");
-
 
242
    __asm__ volatile("    add r1, r1, r4               \n");
-
 
243
    __asm__ volatile("    add r1, r1, r0               \n");
-
 
244
    __asm__ volatile("    cmp r1, #0                   \n");
-
 
245
    __asm__ volatile("    movlt r1, #0                 \n");
-
 
246
    __asm__ volatile("    cmp r1, #0xff                \n");
-
 
247
    __asm__ volatile("    movgt r1, #0xff              \n");
-
 
248
    __asm__ volatile("    mov r0, r1,lsr#3             \n");
208
    memset(corr, 0, corrsize);
249
    __asm__ volatile("    orr r2, r0,lsl#11            \n");
-
 
250
    __asm__ volatile("    sub r1, r1, r0,lsl#3         \n");
209
    unsigned char* in = (unsigned char*)data + (stride * datay + datax) * 3;
251
    __asm__ volatile("    sub r1, r1, r0,lsr#2         \n");
210
    for (y = 0; y < height; y++)
252
    __asm__ volatile("    mov r4, r4,lsr#1             \n");
211
    {
-
 
-
 
253
    __asm__ volatile("    add r4, r4, r1,lsr#2         \n");
212
        int i;
254
    __asm__ volatile("    strb r4, [r7], #1            \n");
213
        signed char* corrptr = corr;
255
    __asm__ volatile("    mov r4, r1,asr#1             \n");
-
 
256
    __asm__ volatile("    ldrb r1, [r3], #1            \n");
214
        signed char lastcorr[3] = {0};
257
    __asm__ volatile("    ldrsb r0, [r7]               \n");
215
        for (x = 0; x < width; x++)
258
    __asm__ volatile("    add r1, r1, r5               \n");
216
        {
259
    __asm__ volatile("    add r1, r1, r0               \n");
217
            unsigned int pixel = 0;
260
    __asm__ volatile("    cmp r1, #0                   \n");
-
 
261
    __asm__ volatile("    movlt r1, #0                 \n");
218
            signed char* lastcorrptr = lastcorr;
262
    __asm__ volatile("    cmp r1, #0xff                \n");
-
 
263
    __asm__ volatile("    movgt r1, #0xff              \n");
219
            int orig = *in++ + *corrptr + *lastcorrptr;
264
    __asm__ volatile("    mov r0, r1,lsr#2             \n");
220
            orig = MAX(0, MIN(255, orig));
265
    __asm__ volatile("    orr r2, r0,lsl#5             \n");
221
            unsigned int real = orig >> 3;
266
    __asm__ volatile("    sub r1, r1, r0,lsl#2         \n");
222
            pixel |= real << 11;
267
    __asm__ volatile("    sub r1, r1, r0,lsr#4         \n");
223
            int err = orig - ((real << 3) | (real >> 2));
268
    __asm__ volatile("    mov r5, r5,lsr#1             \n");
-
 
269
    __asm__ volatile("    add r5, r5, r1,lsr#2         \n");
224
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
270
    __asm__ volatile("    strb r5, [r7], #1            \n");
225
            *lastcorrptr++ = err >> 1;
271
    __asm__ volatile("    mov r5, r1,asr#1             \n");
226
            orig = *in++ + *corrptr + *lastcorrptr;
272
    __asm__ volatile("    ldrb r1, [r3], #1            \n");
227
            orig = MAX(0, MIN(255, orig));
273
    __asm__ volatile("    ldrsb r0, [r7]               \n");
-
 
274
    __asm__ volatile("    add r1, r1, r6               \n");
228
            real = orig >> 2;
275
    __asm__ volatile("    add r1, r1, r0               \n");
-
 
276
    __asm__ volatile("    cmp r1, #0                   \n");
-
 
277
    __asm__ volatile("    movlt r1, #0                 \n");
-
 
278
    __asm__ volatile("    cmp r1, #0xff                \n");
229
            pixel |= real << 5;
279
    __asm__ volatile("    movgt r1, #0xff              \n");
-
 
280
    __asm__ volatile("    mov r0, r1,lsr#3             \n");
230
            err = orig - ((real << 2) | (real >> 4));
281
    __asm__ volatile("    orr r2, r0                   \n");
-
 
282
    __asm__ volatile("    sub r1, r1, r0,lsl#3         \n");
-
 
283
    __asm__ volatile("    sub r1, r1, r0,lsr#2         \n");
231
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
284
    __asm__ volatile("    mov r6, r6,lsr#1             \n");
232
            *lastcorrptr++ = err >> 1;
285
    __asm__ volatile("    add r6, r6, r1,lsr#2         \n");
233
            orig = *in++ + *corrptr + *lastcorrptr;
286
    __asm__ volatile("    strb r6, [r7], #1            \n");
-
 
287
    __asm__ volatile("displaylcd_dither_waitlcd:       \n");
234
            orig = MAX(0, MIN(255, orig));
288
    __asm__ volatile("    ldr r0, [r9,#-0x24]          \n");
235
            real = orig >> 3;
289
    __asm__ volatile("    mov r6, r1,asr#1             \n");
-
 
290
    __asm__ volatile("    tst r0, #0x10                \n");
236
            pixel |= real;
291
    __asm__ volatile("    bne displaylcd_dither_waitlcd\n");
-
 
292
    __asm__ volatile("    str r2, [r9]                 \n");
237
            err = orig - ((real << 3) | (real >> 2));
293
    __asm__ volatile("    sub r3, r3, r10              \n");
238
            *corrptr++ = (*lastcorrptr >> 1) + err >> 2;
294
    __asm__ volatile("    subs lr, lr, #1              \n");
239
            *lastcorrptr++ = err >> 1;
295
    __asm__ volatile("    bne displaylcd_dither_x      \n");
-
 
296
    __asm__ volatile("    add r3, r3, r11              \n");
240
            LCDWDATA = pixel;
297
    __asm__ volatile("    subs r12, r12, #1            \n");
241
            if (solid) in -= 3;
298
    __asm__ volatile("    bne displaylcd_dither_y      \n");
242
        }
299
    __asm__ volatile("displaylcd_dither_free:          \n");
243
        if (solid) in += stride * 3;
300
    __asm__ volatile("    mov r0, r8                   \n");
244
        else in += (stride - width) * 3;
301
    __asm__ volatile("    bl free                      \n");
245
    }
-
 
246
    free(corr);
302
    __asm__ volatile("displaylcd_dither_unlock:        \n");
247
    mutex_unlock(&lcd_mutex);
303
    __asm__ volatile("    ldr r0, =lcd_mutex           \n");
-
 
304
    __asm__ volatile("    bl mutex_unlock              \n");
-
 
305
    __asm__ volatile("    ldmfd sp!, {r2-r11,pc}       \n");
248
}
306
}
249
 
307
 
250
void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
308
void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
251
                void* data, unsigned int datax, unsigned int datay, unsigned int stride)
309
                void* data, unsigned int datax, unsigned int datay, unsigned int stride)
252
{
310
{
Line 254... Line 312...
254
}
312
}
255
 
313
 
256
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
314
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
257
{
315
{
258
    if (width * height <= 0) return;
316
    if (width * height <= 0) return;
-
 
317
    displaylcd_sync();
259
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
318
    mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
260
    displaylcd_dither(x, y, width, height, &color, 0, 0, 0, true);
319
    displaylcd_dither(x, y, width, height, &color, 0, 0, 0, true);
261
    mutex_unlock(&lcd_mutex);
320
    mutex_unlock(&lcd_mutex);
262
}
321
}
263
 
322