summaryrefslogtreecommitdiff
path: root/firmware/target/arm/ipod/lcd-as-gray.S
blob: a066e55a054867e2f511027a7cbcc3d0ec1ef2ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2008 by Jens Arnold
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#include "config.h"
#include "cpu.h"

#if CONFIG_CPU == PP5002
    .section    .icode,"ax",%progbits
#else
    .text
#endif
    .align      2


    .global     lcd_write_data
    .type       lcd_write_data,%function

lcd_write_data:
    str     lr, [sp, #-4]!
    ldr     lr, =LCD1_BASE

.loop:
    ldrb    r2, [r0], #1

#ifdef IPOD_MINI2G
    ldrb    r3, [r0], #1
    orr     r2, r3, r2, lsl #8
    orr     r2, r2, #0x760000
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r2, [lr, #0x08]
#else
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r2, [lr, #0x10]

    ldrb    r2, [r0], #1
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r2, [lr, #0x10]
#endif

    subs    r1, r1, #1
    bne     .loop

    ldr     pc, [sp], #4
    .size   lcd_write_data,.-lcd_write_data
    

#ifdef IPOD_MINI2G

    .global     lcd_write_data_shifted
    .type       lcd_write_data_shifted,%function
    
lcd_write_data_shifted:
    stmfd   sp!, {r4, r5, lr}
    ldr     lr, =LCD1_BASE
    mov     r5, #0x760000
    ldrb    r2, [r0], #1

.sloop:
    ldrb    r3, [r0], #1
    orr     r2, r3, r2, lsl #8
    ldrb    r3, [r0], #1
    orr     r2, r3, r2, lsl #8
    mov     r4, r2, lsl #12
    orr     r4, r5, r4, lsr #16
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r4, [lr, #0x08]

    subs    r1, r1, #1
    bne     .sloop

    ldmfd   sp!, {r4, r5, pc}
    .size   lcd_write_data_shifted,.-lcd_write_data_shifted
    
#elif defined IPOD_MINI

    .global     lcd_write_data_shifted
    .type       lcd_write_data_shifted,%function
    
lcd_write_data_shifted:
    stmfd   sp!, {r4, lr}
    ldr     lr, =LCD1_BASE
    ldrb    r2, [r0], #1

.sloop:
    ldrb    r3, [r0], #1
    orr     r2, r3, r2, lsl #8
    mov     r4, r2, lsr #4
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r4, [lr, #0x10]

    ldrb    r3, [r0], #1
    orr     r2, r3, r2, lsl #8
    mov     r4, r2, lsr #4
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r4, [lr, #0x10]

    subs    r1, r1, #1
    bne     .sloop

    ldmfd   sp!, {r4, pc}
    .size   lcd_write_data_shifted,.-lcd_write_data_shifted

#endif

    .global     lcd_mono_data
    .type       lcd_mono_data,%function
    
lcd_mono_data:
    stmfd   sp!, {r4, r5, lr}
    ldr     lr, =LCD1_BASE
    adr     r5, .dibits

.mloop:
    ldrb    r2, [r0], #1
    mov     r3, r2, lsr #4
    ldrb    r4, [r5, r3]

#ifdef IPOD_MINI2G
    and     r3, r2, #0x0f
    ldrb    r3, [r5, r3]
    orr     r4, r3, r4, lsl #8
    orr     r4, r4, #0x760000
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r4, [lr, #0x08]
#else
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r4, [lr, #0x10]

    and     r3, r2, #0x0f
    ldrb    r4, [r5, r3]
1:
    ldr     r3, [lr]
    tst     r3, #LCD1_BUSY_MASK
    bne     1b
    str     r4, [lr, #0x10]
#endif

    subs    r1, r1, #1
    bne     .mloop

    ldmfd   sp!, {r4, r5, pc}

.dibits:
    .byte   0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F
    .byte   0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF

    .size   lcd_mono_data,.-lcd_mono_data


    .global     lcd_grey_data
    .type       lcd_grey_data,%function

/* A high performance function to write grey phase data to the display,
 * one or multiple pixels.
 *
 * Arguments:
 *   r0 - pixel value data address
 *   r1 - pixel phase data address
 *   r2 - pixel block count
 *
 * Register usage:
 *   r3/r4 - current block of phases
 *   r5/r6 - current block of values
 *   r7 - lcd data accumulator
 *   r8 - phase signs mask
 *   lr - lcd bridge address
 */
 
lcd_grey_data:
    stmfd   sp!, {r4-r8, lr}
    mov     r8, #0x80
    orr     r8, r8, r8, lsl #8
    orr     r8, r8, r8, lsl #16
    ldr     lr, =LCD1_BASE

.greyloop:
    ldmia   r1, {r3-r4}         /* Fetch 8 pixel phases */
    ldmia   r0!, {r5-r6}        /* Fetch 8 pixel values */

#ifdef IPOD_MINI2G              /* Serial bridge mode */
    mov     r7, #0x760000
    tst     r3, #0x80
    orreq   r7, r7, #0xc000
    tst     r3, #0x8000
    orreq   r7, r7, #0x3000
    tst     r3, #0x800000
    orreq   r7, r7, #0x0c00
    tst     r3, #0x80000000
    orreq   r7, r7, #0x0300
    bic     r3, r3, r8
    add     r3, r3, r5
#else                           /* Parallel bridge mode */
    mov     r7, #0
    tst     r3, #0x80
    orreq   r7, r7, #0xc0
    tst     r3, #0x8000
    orreq   r7, r7, #0x30
    tst     r3, #0x800000
    orreq   r7, r7, #0x0c
    tst     r3, #0x80000000
    orreq   r7, r7, #0x03
    bic     r3, r3, r8
    add     r3, r3, r5

1:
    ldr     r5, [lr]
    tst     r5, #LCD1_BUSY_MASK
    bne     1b

    str     r7, [lr, #0x10]
    mov     r7, #0
#endif

    tst     r4, #0x80
    orreq   r7, r7, #0xc0
    tst     r4, #0x8000
    orreq   r7, r7, #0x30
    tst     r4, #0x800000
    orreq   r7, r7, #0x0c
    tst     r4, #0x80000000
    orreq   r7, r7, #0x03
    bic     r4, r4, r8
    add     r4, r4, r6

    stmia   r1!, {r3-r4}

1:
    ldr     r5, [lr]
    tst     r5, #LCD1_BUSY_MASK
    bne     1b
#ifdef IPOD_MINI2G
    str     r7, [lr, #0x08]
#else
    str     r7, [lr, #0x10]
#endif

    subs    r2, r2, #1
    bne     .greyloop

    ldmfd   sp!, {r4-r8, pc}
    .size   lcd_grey_data,.-lcd_grey_data