freemyipod r669 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r668‎ | r669 | r670 >
Date:19:31, 25 March 2011
Author:theseven
Status:new
Tags:
Comment:
emCORE: Increase iPod Nano 2G LCD shutdown delay, it was apparently too short
Modified paths:
  • /emcore/trunk/target/ipodnano2g/lcd.c (modified) (history)

Diff [purge]

Index: emcore/trunk/target/ipodnano2g/lcd.c
@@ -1,397 +1,397 @@
2 -//
3 -//
4 -// Copyright 2010 TheSeven
5 -//
6 -//
7 -// This file is part of emCORE.
8 -//
9 -// emCORE is free software: you can redistribute it and/or
10 -// modify it under the terms of the GNU General Public License as
11 -// published by the Free Software Foundation, either version 2 of the
12 -// License, or (at your option) any later version.
13 -//
14 -// emCORE is distributed in the hope that it will be useful,
15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 -// See the GNU General Public License for more details.
18 -//
19 -// You should have received a copy of the GNU General Public License along
20 -// with emCORE. If not, see <http://www.gnu.org/licenses/>.
21 -//
22 -//
23 -
24 -
25 -#include "global.h"
26 -#include "thread.h"
27 -#include "s5l8701.h"
28 -#include "util.h"
29 -
30 -
31 -static struct mutex lcd_mutex IDATA_ATTR;
32 -static struct wakeup lcd_wakeup IDATA_ATTR;
33 -
34 -static bool lcd_dma_busy IDATA_ATTR;
35 -static bool lcd_in_irq IDATA_ATTR;
36 -
37 -
38 -void lcd_init()
39 -{
40 - mutex_init(&lcd_mutex);
41 - wakeup_init(&lcd_wakeup);
42 - DMACON8 = 0x20590000;
43 - LCDCON = 0xd01;
44 - LCDPHTIME = 0;
45 - lcd_in_irq = false;
46 - lcd_dma_busy = false;
47 -}
48 -
49 -int lcd_get_width()
50 -{
51 - return LCD_WIDTH;
52 -}
53 -
54 -int lcd_get_height()
55 -{
56 - return LCD_HEIGHT;
57 -}
58 -
59 -int lcd_get_bytes_per_pixel()
60 -{
61 - return LCD_BYTESPERPIXEL;
62 -}
63 -
64 -int lcd_get_format()
65 -{
66 - return LCD_FORMAT;
67 -}
68 -
69 -static void lcd_send_cmd(uint16_t cmd) ICODE_ATTR __attribute__((noinline));
70 -static void lcd_send_cmd(uint16_t cmd)
71 -{
72 - while (LCDSTATUS & 0x10);
73 - LCDWCMD = cmd;
74 -}
75 -
76 -static void lcd_send_data(uint16_t data) ICODE_ATTR __attribute__((noinline));
77 -static void lcd_send_data(uint16_t data)
78 -{
79 - while (LCDSTATUS & 0x10);
80 - LCDWDATA = data;
81 -}
82 -
83 -static uint32_t lcd_detect() ICODE_ATTR;
84 -static uint32_t lcd_detect()
85 -{
86 - return (PDAT13 & 1) | (PDAT14 & 2);
87 -}
88 -
89 -bool displaylcd_busy() ICODE_ATTR;
90 -bool displaylcd_busy()
91 -{
92 - return lcd_dma_busy;
93 -}
94 -
95 -bool displaylcd_safe()
96 -{
97 - lcd_in_irq = true;
98 - if (!lcd_dma_busy) return true;
99 - return !(DMAALLST2 & 0x70000);
100 -}
101 -
102 -void displaylcd_sync() ICODE_ATTR;
103 -void displaylcd_sync()
104 -{
105 - mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
106 - while (displaylcd_busy()) wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
107 - mutex_unlock(&lcd_mutex);
108 -}
109 -
110 -void displaylcd_setup(unsigned int startx, unsigned int endx,
111 - unsigned int starty, unsigned int endy) ICODE_ATTR;
112 -void displaylcd_setup(unsigned int startx, unsigned int endx,
113 - unsigned int starty, unsigned int endy)
114 -{
115 - if (!lcd_in_irq)
116 - {
117 - mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
118 - displaylcd_sync();
119 - }
120 - if (lcd_detect() == 2)
121 - {
122 - lcd_send_cmd(0x50);
123 - lcd_send_data(startx);
124 - lcd_send_cmd(0x51);
125 - lcd_send_data(endx);
126 - lcd_send_cmd(0x52);
127 - lcd_send_data(starty);
128 - lcd_send_cmd(0x53);
129 - lcd_send_data(endy);
130 - lcd_send_cmd(0x20);
131 - lcd_send_data(startx);
132 - lcd_send_cmd(0x21);
133 - lcd_send_data(starty);
134 - lcd_send_cmd(0x22);
135 - }
136 - else
137 - {
138 - lcd_send_cmd(0x2a);
139 - lcd_send_data(startx);
140 - lcd_send_data(endx);
141 - lcd_send_cmd(0x2b);
142 - lcd_send_data(starty);
143 - lcd_send_data(endy);
144 - lcd_send_cmd(0x2c);
145 - }
146 -}
147 -
148 -static void displaylcd_dma(void* data, int pixels) ICODE_ATTR;
149 -static void displaylcd_dma(void* data, int pixels)
150 -{
151 - uint16_t* in = (uint16_t*)data;
152 - while (LCDSTATUS & 8);
153 - while (pixels & 3)
154 - {
155 - LCDWDATA = *in++;
156 - pixels--;
157 - }
158 - lcd_dma_busy = true;
159 - DMABASE8 = in;
160 - DMACON8 = 0x20590000;
161 - DMATCNT8 = pixels / 4;
162 - clean_dcache();
163 - DMACOM8 = 4;
164 -}
165 -
166 -static void displaylcd_solid(uint16_t data, int pixels) ICODE_ATTR;
167 -static void displaylcd_solid(uint16_t data, int pixels)
168 -{
169 - while (pixels >= 4)
170 - {
171 - while (LCDSTATUS & 8);
172 - LCDWDATA = data;
173 - LCDWDATA = data;
174 - LCDWDATA = data;
175 - LCDWDATA = data;
176 - pixels -= 4;
177 - }
178 - while (LCDSTATUS & 8);
179 - while (pixels & 3)
180 - {
181 - LCDWDATA = data;
182 - pixels--;
183 - }
184 -}
185 -
186 -void displaylcd_native(unsigned int startx, unsigned int endx,
187 - unsigned int starty, unsigned int endy, void* data)
188 -{
189 - int pixels = (endx - startx + 1) * (endy - starty + 1);
190 - if (pixels <= 0) return;
191 - displaylcd_setup(startx, endx, starty, endy);
192 - displaylcd_dma(data, pixels);
193 - if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
194 -}
195 -
196 -void filllcd_native(unsigned int startx, unsigned int endx,
197 - unsigned int starty, unsigned int endy, int color)
198 -{
199 - int pixels = (endx - startx + 1) * (endy - starty + 1);
200 - if (pixels <= 0) return;
201 - displaylcd_setup(startx, endx, starty, endy);
202 - displaylcd_solid(color, pixels);
203 - if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
204 -}
205 -
206 -void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
207 - unsigned int height, void* data, unsigned int datax,
208 - unsigned int datay, unsigned int stride, bool solid)
209 - ICODE_ATTR __attribute__((naked,noinline));
210 -void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
211 - unsigned int height, void* data, unsigned int datax,
212 - unsigned int datay, unsigned int stride, bool solid)
213 -{
214 - __asm__ volatile(" muls r12, r2, r3 \n");
215 - __asm__ volatile(" bxeq lr \n");
216 - __asm__ volatile(" stmfd sp!, {r2-r11,lr} \n");
217 - __asm__ volatile(" mov r12, r2 \n");
218 - __asm__ volatile(" add r8, r2, r2,lsl#1 \n");
219 - __asm__ volatile(" add r3, r1, r3 \n");
220 - __asm__ volatile(" sub r3, r3, #1 \n");
221 - __asm__ volatile(" mov r2, r1 \n");
222 - __asm__ volatile(" add r1, r0, r12 \n");
223 - __asm__ volatile(" sub r1, r1, #1 \n");
224 - __asm__ volatile(" bl displaylcd_setup \n");
225 - __asm__ volatile(" mov r0, r8 \n");
226 - __asm__ volatile(" bl malloc \n");
227 - __asm__ volatile(" cmp r0, #0 \n");
228 - __asm__ volatile(" beq displaylcd_dither_unlock \n");
229 - __asm__ volatile(" mov r2, r8 \n");
230 - __asm__ volatile(" mov r1, #0 \n");
231 - __asm__ volatile(" mov r8, r0 \n");
232 - __asm__ volatile(" bl memset \n");
233 - __asm__ volatile(" ldr r0, [sp,#0x30] \n");
234 - __asm__ volatile(" ldr r1, [sp,#0x34] \n");
235 - __asm__ volatile(" ldr r11, [sp,#0x38] \n");
236 - __asm__ volatile(" ldr r3, [sp,#0x2c] \n");
237 - __asm__ volatile(" mla r0, r1, r11, r0 \n");
238 - __asm__ volatile(" ldr r12, [sp,#0x04] \n");
239 - __asm__ volatile(" ldr r2, [sp,#0x3c] \n");
240 - __asm__ volatile(" add r3, r3, r0,lsl#1 \n");
241 - __asm__ volatile(" cmp r2, #0 \n");
242 - __asm__ volatile(" ldreq r1, [sp] \n");
243 - __asm__ volatile(" add r3, r3, r0 \n");
244 - __asm__ volatile(" subeq r11, r11, r1 \n");
245 - __asm__ volatile(" add r11, r11, r11,lsl#1 \n");
246 - __asm__ volatile(" movne r10, #3 \n");
247 - __asm__ volatile(" moveq r10, #0 \n");
248 - __asm__ volatile(" ldr r9, =0x38600040 \n");
249 - __asm__ volatile("displaylcd_dither_y: \n");
250 - __asm__ volatile(" ldr lr, [sp] \n");
251 - __asm__ volatile(" mov r4, #0 \n");
252 - __asm__ volatile(" mov r5, #0 \n");
253 - __asm__ volatile(" mov r6, #0 \n");
254 - __asm__ volatile(" mov r7, r8 \n");
255 - __asm__ volatile("displaylcd_dither_x: \n");
256 - __asm__ volatile(" mov r2, #0 \n");
257 - __asm__ volatile(" ldrb r1, [r3], #1 \n");
258 - __asm__ volatile(" ldrsb r0, [r7] \n");
259 - __asm__ volatile(" add r1, r1, r4 \n");
260 - __asm__ volatile(" add r1, r1, r0 \n");
 2+//
 3+//
 4+// Copyright 2010 TheSeven
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+#include "thread.h"
 27+#include "s5l8701.h"
 28+#include "util.h"
 29+
 30+
 31+static struct mutex lcd_mutex IDATA_ATTR;
 32+static struct wakeup lcd_wakeup IDATA_ATTR;
 33+
 34+static bool lcd_dma_busy IDATA_ATTR;
 35+static bool lcd_in_irq IDATA_ATTR;
 36+
 37+
 38+void lcd_init()
 39+{
 40+ mutex_init(&lcd_mutex);
 41+ wakeup_init(&lcd_wakeup);
 42+ DMACON8 = 0x20590000;
 43+ LCDCON = 0xd01;
 44+ LCDPHTIME = 0;
 45+ lcd_in_irq = false;
 46+ lcd_dma_busy = false;
 47+}
 48+
 49+int lcd_get_width()
 50+{
 51+ return LCD_WIDTH;
 52+}
 53+
 54+int lcd_get_height()
 55+{
 56+ return LCD_HEIGHT;
 57+}
 58+
 59+int lcd_get_bytes_per_pixel()
 60+{
 61+ return LCD_BYTESPERPIXEL;
 62+}
 63+
 64+int lcd_get_format()
 65+{
 66+ return LCD_FORMAT;
 67+}
 68+
 69+static void lcd_send_cmd(uint16_t cmd) ICODE_ATTR __attribute__((noinline));
 70+static void lcd_send_cmd(uint16_t cmd)
 71+{
 72+ while (LCDSTATUS & 0x10);
 73+ LCDWCMD = cmd;
 74+}
 75+
 76+static void lcd_send_data(uint16_t data) ICODE_ATTR __attribute__((noinline));
 77+static void lcd_send_data(uint16_t data)
 78+{
 79+ while (LCDSTATUS & 0x10);
 80+ LCDWDATA = data;
 81+}
 82+
 83+static uint32_t lcd_detect() ICODE_ATTR;
 84+static uint32_t lcd_detect()
 85+{
 86+ return (PDAT13 & 1) | (PDAT14 & 2);
 87+}
 88+
 89+bool displaylcd_busy() ICODE_ATTR;
 90+bool displaylcd_busy()
 91+{
 92+ return lcd_dma_busy;
 93+}
 94+
 95+bool displaylcd_safe()
 96+{
 97+ lcd_in_irq = true;
 98+ if (!lcd_dma_busy) return true;
 99+ return !(DMAALLST2 & 0x70000);
 100+}
 101+
 102+void displaylcd_sync() ICODE_ATTR;
 103+void displaylcd_sync()
 104+{
 105+ mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
 106+ while (displaylcd_busy()) wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
 107+ mutex_unlock(&lcd_mutex);
 108+}
 109+
 110+void displaylcd_setup(unsigned int startx, unsigned int endx,
 111+ unsigned int starty, unsigned int endy) ICODE_ATTR;
 112+void displaylcd_setup(unsigned int startx, unsigned int endx,
 113+ unsigned int starty, unsigned int endy)
 114+{
 115+ if (!lcd_in_irq)
 116+ {
 117+ mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
 118+ displaylcd_sync();
 119+ }
 120+ if (lcd_detect() == 2)
 121+ {
 122+ lcd_send_cmd(0x50);
 123+ lcd_send_data(startx);
 124+ lcd_send_cmd(0x51);
 125+ lcd_send_data(endx);
 126+ lcd_send_cmd(0x52);
 127+ lcd_send_data(starty);
 128+ lcd_send_cmd(0x53);
 129+ lcd_send_data(endy);
 130+ lcd_send_cmd(0x20);
 131+ lcd_send_data(startx);
 132+ lcd_send_cmd(0x21);
 133+ lcd_send_data(starty);
 134+ lcd_send_cmd(0x22);
 135+ }
 136+ else
 137+ {
 138+ lcd_send_cmd(0x2a);
 139+ lcd_send_data(startx);
 140+ lcd_send_data(endx);
 141+ lcd_send_cmd(0x2b);
 142+ lcd_send_data(starty);
 143+ lcd_send_data(endy);
 144+ lcd_send_cmd(0x2c);
 145+ }
 146+}
 147+
 148+static void displaylcd_dma(void* data, int pixels) ICODE_ATTR;
 149+static void displaylcd_dma(void* data, int pixels)
 150+{
 151+ uint16_t* in = (uint16_t*)data;
 152+ while (LCDSTATUS & 8);
 153+ while (pixels & 3)
 154+ {
 155+ LCDWDATA = *in++;
 156+ pixels--;
 157+ }
 158+ lcd_dma_busy = true;
 159+ DMABASE8 = in;
 160+ DMACON8 = 0x20590000;
 161+ DMATCNT8 = pixels / 4;
 162+ clean_dcache();
 163+ DMACOM8 = 4;
 164+}
 165+
 166+static void displaylcd_solid(uint16_t data, int pixels) ICODE_ATTR;
 167+static void displaylcd_solid(uint16_t data, int pixels)
 168+{
 169+ while (pixels >= 4)
 170+ {
 171+ while (LCDSTATUS & 8);
 172+ LCDWDATA = data;
 173+ LCDWDATA = data;
 174+ LCDWDATA = data;
 175+ LCDWDATA = data;
 176+ pixels -= 4;
 177+ }
 178+ while (LCDSTATUS & 8);
 179+ while (pixels & 3)
 180+ {
 181+ LCDWDATA = data;
 182+ pixels--;
 183+ }
 184+}
 185+
 186+void displaylcd_native(unsigned int startx, unsigned int endx,
 187+ unsigned int starty, unsigned int endy, void* data)
 188+{
 189+ int pixels = (endx - startx + 1) * (endy - starty + 1);
 190+ if (pixels <= 0) return;
 191+ displaylcd_setup(startx, endx, starty, endy);
 192+ displaylcd_dma(data, pixels);
 193+ if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
 194+}
 195+
 196+void filllcd_native(unsigned int startx, unsigned int endx,
 197+ unsigned int starty, unsigned int endy, int color)
 198+{
 199+ int pixels = (endx - startx + 1) * (endy - starty + 1);
 200+ if (pixels <= 0) return;
 201+ displaylcd_setup(startx, endx, starty, endy);
 202+ displaylcd_solid(color, pixels);
 203+ if (!lcd_in_irq) mutex_unlock(&lcd_mutex);
 204+}
 205+
 206+void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
 207+ unsigned int height, void* data, unsigned int datax,
 208+ unsigned int datay, unsigned int stride, bool solid)
 209+ ICODE_ATTR __attribute__((naked,noinline));
 210+void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
 211+ unsigned int height, void* data, unsigned int datax,
 212+ unsigned int datay, unsigned int stride, bool solid)
 213+{
 214+ __asm__ volatile(" muls r12, r2, r3 \n");
 215+ __asm__ volatile(" bxeq lr \n");
 216+ __asm__ volatile(" stmfd sp!, {r2-r11,lr} \n");
 217+ __asm__ volatile(" mov r12, r2 \n");
 218+ __asm__ volatile(" add r8, r2, r2,lsl#1 \n");
 219+ __asm__ volatile(" add r3, r1, r3 \n");
 220+ __asm__ volatile(" sub r3, r3, #1 \n");
 221+ __asm__ volatile(" mov r2, r1 \n");
 222+ __asm__ volatile(" add r1, r0, r12 \n");
 223+ __asm__ volatile(" sub r1, r1, #1 \n");
 224+ __asm__ volatile(" bl displaylcd_setup \n");
 225+ __asm__ volatile(" mov r0, r8 \n");
 226+ __asm__ volatile(" bl malloc \n");
 227+ __asm__ volatile(" cmp r0, #0 \n");
 228+ __asm__ volatile(" beq displaylcd_dither_unlock \n");
 229+ __asm__ volatile(" mov r2, r8 \n");
 230+ __asm__ volatile(" mov r1, #0 \n");
 231+ __asm__ volatile(" mov r8, r0 \n");
 232+ __asm__ volatile(" bl memset \n");
 233+ __asm__ volatile(" ldr r0, [sp,#0x30] \n");
 234+ __asm__ volatile(" ldr r1, [sp,#0x34] \n");
 235+ __asm__ volatile(" ldr r11, [sp,#0x38] \n");
 236+ __asm__ volatile(" ldr r3, [sp,#0x2c] \n");
 237+ __asm__ volatile(" mla r0, r1, r11, r0 \n");
 238+ __asm__ volatile(" ldr r12, [sp,#0x04] \n");
 239+ __asm__ volatile(" ldr r2, [sp,#0x3c] \n");
 240+ __asm__ volatile(" add r3, r3, r0,lsl#1 \n");
 241+ __asm__ volatile(" cmp r2, #0 \n");
 242+ __asm__ volatile(" ldreq r1, [sp] \n");
 243+ __asm__ volatile(" add r3, r3, r0 \n");
 244+ __asm__ volatile(" subeq r11, r11, r1 \n");
 245+ __asm__ volatile(" add r11, r11, r11,lsl#1 \n");
 246+ __asm__ volatile(" movne r10, #3 \n");
 247+ __asm__ volatile(" moveq r10, #0 \n");
 248+ __asm__ volatile(" ldr r9, =0x38600040 \n");
 249+ __asm__ volatile("displaylcd_dither_y: \n");
 250+ __asm__ volatile(" ldr lr, [sp] \n");
 251+ __asm__ volatile(" mov r4, #0 \n");
 252+ __asm__ volatile(" mov r5, #0 \n");
 253+ __asm__ volatile(" mov r6, #0 \n");
 254+ __asm__ volatile(" mov r7, r8 \n");
 255+ __asm__ volatile("displaylcd_dither_x: \n");
 256+ __asm__ volatile(" mov r2, #0 \n");
 257+ __asm__ volatile(" ldrb r1, [r3], #1 \n");
 258+ __asm__ volatile(" ldrsb r0, [r7] \n");
 259+ __asm__ volatile(" add r1, r1, r4 \n");
 260+ __asm__ volatile(" add r1, r1, r0 \n");
261261 __asm__ volatile(" cmp r1, #0xff \n");
262262 __asm__ volatile(" mvnhi r1, r1,asr#31 \n");
263263 __asm__ volatile(" andhi r1, r1, #0xff \n");
264 - __asm__ volatile(" mov r0, r1,lsr#3 \n");
265 - __asm__ volatile(" orr r2, r0,lsl#11 \n");
266 - __asm__ volatile(" sub r1, r1, r0,lsl#3 \n");
267 - __asm__ volatile(" sub r1, r1, r0,lsr#2 \n");
268 - __asm__ volatile(" mov r4, r4,lsr#1 \n");
269 - __asm__ volatile(" add r4, r4, r1,lsr#2 \n");
270 - __asm__ volatile(" strb r4, [r7], #1 \n");
271 - __asm__ volatile(" mov r4, r1,asr#1 \n");
272 - __asm__ volatile(" ldrb r1, [r3], #1 \n");
273 - __asm__ volatile(" ldrsb r0, [r7] \n");
274 - __asm__ volatile(" add r1, r1, r5 \n");
275 - __asm__ volatile(" add r1, r1, r0 \n");
 264+ __asm__ volatile(" mov r0, r1,lsr#3 \n");
 265+ __asm__ volatile(" orr r2, r0,lsl#11 \n");
 266+ __asm__ volatile(" sub r1, r1, r0,lsl#3 \n");
 267+ __asm__ volatile(" sub r1, r1, r0,lsr#2 \n");
 268+ __asm__ volatile(" mov r4, r4,lsr#1 \n");
 269+ __asm__ volatile(" add r4, r4, r1,lsr#2 \n");
 270+ __asm__ volatile(" strb r4, [r7], #1 \n");
 271+ __asm__ volatile(" mov r4, r1,asr#1 \n");
 272+ __asm__ volatile(" ldrb r1, [r3], #1 \n");
 273+ __asm__ volatile(" ldrsb r0, [r7] \n");
 274+ __asm__ volatile(" add r1, r1, r5 \n");
 275+ __asm__ volatile(" add r1, r1, r0 \n");
276276 __asm__ volatile(" cmp r1, #0xff \n");
277277 __asm__ volatile(" mvnhi r1, r1,asr#31 \n");
278278 __asm__ volatile(" andhi r1, r1, #0xff \n");
279 - __asm__ volatile(" mov r0, r1,lsr#2 \n");
280 - __asm__ volatile(" orr r2, r0,lsl#5 \n");
281 - __asm__ volatile(" sub r1, r1, r0,lsl#2 \n");
282 - __asm__ volatile(" sub r1, r1, r0,lsr#4 \n");
283 - __asm__ volatile(" mov r5, r5,lsr#1 \n");
284 - __asm__ volatile(" add r5, r5, r1,lsr#2 \n");
285 - __asm__ volatile(" strb r5, [r7], #1 \n");
286 - __asm__ volatile(" mov r5, r1,asr#1 \n");
287 - __asm__ volatile(" ldrb r1, [r3], #1 \n");
288 - __asm__ volatile(" ldrsb r0, [r7] \n");
289 - __asm__ volatile(" add r1, r1, r6 \n");
290 - __asm__ volatile(" add r1, r1, r0 \n");
 279+ __asm__ volatile(" mov r0, r1,lsr#2 \n");
 280+ __asm__ volatile(" orr r2, r0,lsl#5 \n");
 281+ __asm__ volatile(" sub r1, r1, r0,lsl#2 \n");
 282+ __asm__ volatile(" sub r1, r1, r0,lsr#4 \n");
 283+ __asm__ volatile(" mov r5, r5,lsr#1 \n");
 284+ __asm__ volatile(" add r5, r5, r1,lsr#2 \n");
 285+ __asm__ volatile(" strb r5, [r7], #1 \n");
 286+ __asm__ volatile(" mov r5, r1,asr#1 \n");
 287+ __asm__ volatile(" ldrb r1, [r3], #1 \n");
 288+ __asm__ volatile(" ldrsb r0, [r7] \n");
 289+ __asm__ volatile(" add r1, r1, r6 \n");
 290+ __asm__ volatile(" add r1, r1, r0 \n");
291291 __asm__ volatile(" cmp r1, #0xff \n");
292292 __asm__ volatile(" mvnhi r1, r1,asr#31 \n");
293293 __asm__ volatile(" andhi r1, r1, #0xff \n");
294 - __asm__ volatile(" mov r0, r1,lsr#3 \n");
295 - __asm__ volatile(" orr r2, r0 \n");
296 - __asm__ volatile(" sub r1, r1, r0,lsl#3 \n");
297 - __asm__ volatile(" sub r1, r1, r0,lsr#2 \n");
298 - __asm__ volatile(" mov r6, r6,lsr#1 \n");
299 - __asm__ volatile(" add r6, r6, r1,lsr#2 \n");
300 - __asm__ volatile(" strb r6, [r7], #1 \n");
301 - __asm__ volatile("displaylcd_dither_waitlcd: \n");
302 - __asm__ volatile(" ldr r0, [r9,#-0x24] \n");
303 - __asm__ volatile(" mov r6, r1,asr#1 \n");
304 - __asm__ volatile(" tst r0, #0x10 \n");
305 - __asm__ volatile(" bne displaylcd_dither_waitlcd\n");
306 - __asm__ volatile(" str r2, [r9] \n");
307 - __asm__ volatile(" sub r3, r3, r10 \n");
308 - __asm__ volatile(" subs lr, lr, #1 \n");
309 - __asm__ volatile(" bne displaylcd_dither_x \n");
310 - __asm__ volatile(" add r3, r3, r11 \n");
311 - __asm__ volatile(" subs r12, r12, #1 \n");
312 - __asm__ volatile(" bne displaylcd_dither_y \n");
313 - __asm__ volatile("displaylcd_dither_free: \n");
314 - __asm__ volatile(" mov r0, r8 \n");
315 - __asm__ volatile(" bl free \n");
316 - __asm__ volatile("displaylcd_dither_unlock: \n");
317 - __asm__ volatile(" ldr r0, =lcd_mutex \n");
318 - __asm__ volatile(" bl mutex_unlock \n");
319 - __asm__ volatile(" ldmfd sp!, {r2-r11,pc} \n");
320 -}
321 -
322 -void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
323 - void* data, unsigned int datax, unsigned int datay, unsigned int stride)
324 -{
325 - displaylcd_dither(x, y, width, height, data, datax, datay, stride, false);
326 -}
327 -
328 -void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
329 -{
330 - if (width * height <= 0) return;
331 - mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
332 - displaylcd_sync();
333 - displaylcd_dither(x, y, width, height, &color, 0, 0, 0, true);
334 - mutex_unlock(&lcd_mutex);
335 -}
336 -
337 -void lcd_shutdown()
338 -{
339 - displaylcd_sync();
340 - uint32_t type = lcd_detect();
341 - if (type == 2)
342 - {
343 - lcd_send_cmd(0x7);
344 - lcd_send_data(0x232);
345 - lcd_send_cmd(0x13);
346 - lcd_send_data(0x1137);
347 - lcd_send_cmd(0x7);
348 - lcd_send_data(0x201);
349 - lcd_send_cmd(0x13);
350 - lcd_send_data(0x137);
351 - lcd_send_cmd(0x7);
352 - lcd_send_data(0x200);
353 - lcd_send_cmd(0x10);
354 - lcd_send_data(0x680);
355 - lcd_send_cmd(0x12);
356 - lcd_send_data(0x160);
357 - lcd_send_cmd(0x13);
358 - lcd_send_data(0x127);
359 - lcd_send_cmd(0x10);
360 - lcd_send_data(0x600);
361 - }
362 - else
363 - {
364 - lcd_send_cmd(0x28);
365 - lcd_send_cmd(0x10);
366 - }
367 - sleep(5000);
368 -}
369 -
370 -void INT_DMA8()
371 -{
372 - DMACOM8 = 7;
373 - lcd_in_irq = true;
374 - lcd_dma_busy = false;
375 - lcdconsole_callback();
376 - wakeup_signal(&lcd_wakeup);
377 - lcd_in_irq = false;
378 -}
379 -
380 -int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
381 - ICODE_ATTR __attribute__((naked, noinline));
382 -int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
383 -{
384 - asm volatile(
385 - "cmp r0, #0xff \n\t"
386 - "moveq r0, #-1 \n\t"
387 - "moveq pc, lr \n\t"
388 - "cmp r0, #0 \n\t"
389 - "movne r0, #0xff000000 \n\t"
390 - "orrne r0, r0, #0xff0000 \n\t"
391 - "mov r2, r2,lsr#2 \n\t"
392 - "orr r0, r0, r3,lsr#3 \n\t"
393 - "mov r1, r1,lsr#3 \n\t"
394 - "orr r0, r0, r2,lsl#5 \n\t"
395 - "orr r0, r0, r1,lsl#11 \n\t"
396 - "mov pc, lr \n\t"
397 - );
398 -}
 294+ __asm__ volatile(" mov r0, r1,lsr#3 \n");
 295+ __asm__ volatile(" orr r2, r0 \n");
 296+ __asm__ volatile(" sub r1, r1, r0,lsl#3 \n");
 297+ __asm__ volatile(" sub r1, r1, r0,lsr#2 \n");
 298+ __asm__ volatile(" mov r6, r6,lsr#1 \n");
 299+ __asm__ volatile(" add r6, r6, r1,lsr#2 \n");
 300+ __asm__ volatile(" strb r6, [r7], #1 \n");
 301+ __asm__ volatile("displaylcd_dither_waitlcd: \n");
 302+ __asm__ volatile(" ldr r0, [r9,#-0x24] \n");
 303+ __asm__ volatile(" mov r6, r1,asr#1 \n");
 304+ __asm__ volatile(" tst r0, #0x10 \n");
 305+ __asm__ volatile(" bne displaylcd_dither_waitlcd\n");
 306+ __asm__ volatile(" str r2, [r9] \n");
 307+ __asm__ volatile(" sub r3, r3, r10 \n");
 308+ __asm__ volatile(" subs lr, lr, #1 \n");
 309+ __asm__ volatile(" bne displaylcd_dither_x \n");
 310+ __asm__ volatile(" add r3, r3, r11 \n");
 311+ __asm__ volatile(" subs r12, r12, #1 \n");
 312+ __asm__ volatile(" bne displaylcd_dither_y \n");
 313+ __asm__ volatile("displaylcd_dither_free: \n");
 314+ __asm__ volatile(" mov r0, r8 \n");
 315+ __asm__ volatile(" bl free \n");
 316+ __asm__ volatile("displaylcd_dither_unlock: \n");
 317+ __asm__ volatile(" ldr r0, =lcd_mutex \n");
 318+ __asm__ volatile(" bl mutex_unlock \n");
 319+ __asm__ volatile(" ldmfd sp!, {r2-r11,pc} \n");
 320+}
 321+
 322+void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
 323+ void* data, unsigned int datax, unsigned int datay, unsigned int stride)
 324+{
 325+ displaylcd_dither(x, y, width, height, data, datax, datay, stride, false);
 326+}
 327+
 328+void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
 329+{
 330+ if (width * height <= 0) return;
 331+ mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
 332+ displaylcd_sync();
 333+ displaylcd_dither(x, y, width, height, &color, 0, 0, 0, true);
 334+ mutex_unlock(&lcd_mutex);
 335+}
 336+
 337+void lcd_shutdown()
 338+{
 339+ displaylcd_sync();
 340+ uint32_t type = lcd_detect();
 341+ if (type == 2)
 342+ {
 343+ lcd_send_cmd(0x7);
 344+ lcd_send_data(0x232);
 345+ lcd_send_cmd(0x13);
 346+ lcd_send_data(0x1137);
 347+ lcd_send_cmd(0x7);
 348+ lcd_send_data(0x201);
 349+ lcd_send_cmd(0x13);
 350+ lcd_send_data(0x137);
 351+ lcd_send_cmd(0x7);
 352+ lcd_send_data(0x200);
 353+ lcd_send_cmd(0x10);
 354+ lcd_send_data(0x680);
 355+ lcd_send_cmd(0x12);
 356+ lcd_send_data(0x160);
 357+ lcd_send_cmd(0x13);
 358+ lcd_send_data(0x127);
 359+ lcd_send_cmd(0x10);
 360+ lcd_send_data(0x600);
 361+ }
 362+ else
 363+ {
 364+ lcd_send_cmd(0x28);
 365+ lcd_send_cmd(0x10);
 366+ }
 367+ sleep(10000);
 368+}
 369+
 370+void INT_DMA8()
 371+{
 372+ DMACOM8 = 7;
 373+ lcd_in_irq = true;
 374+ lcd_dma_busy = false;
 375+ lcdconsole_callback();
 376+ wakeup_signal(&lcd_wakeup);
 377+ lcd_in_irq = false;
 378+}
 379+
 380+int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
 381+ ICODE_ATTR __attribute__((naked, noinline));
 382+int lcd_translate_color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue)
 383+{
 384+ asm volatile(
 385+ "cmp r0, #0xff \n\t"
 386+ "moveq r0, #-1 \n\t"
 387+ "moveq pc, lr \n\t"
 388+ "cmp r0, #0 \n\t"
 389+ "movne r0, #0xff000000 \n\t"
 390+ "orrne r0, r0, #0xff0000 \n\t"
 391+ "mov r2, r2,lsr#2 \n\t"
 392+ "orr r0, r0, r3,lsr#3 \n\t"
 393+ "mov r1, r1,lsr#3 \n\t"
 394+ "orr r0, r0, r2,lsl#5 \n\t"
 395+ "orr r0, r0, r1,lsl#11 \n\t"
 396+ "mov pc, lr \n\t"
 397+ );
 398+}