summaryrefslogtreecommitdiff
path: root/apps/codecs/libfaad/ic_predict.h
blob: 1f2d2c657e7a355ed7f1de44dde690cb69ce7b29 (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
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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 program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
** 
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software 
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
** $Id$
**/

#ifdef MAIN_DEC

#ifndef __IC_PREDICT_H__
#define __IC_PREDICT_H__

#ifdef __cplusplus
extern "C" {
#endif

#define ALPHA      REAL_CONST(0.90625)
#define A          REAL_CONST(0.953125)


void pns_reset_pred_state(ic_stream *ics, pred_state *state);
void reset_all_predictors(pred_state *state, uint16_t frame_len);
void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
                   uint16_t frame_len, uint8_t sf_index);
#warning MEM_ALIGN_ATTR me!
static const real_t mnt_table[128] = {
    COEF_CONST(0.9531250000), COEF_CONST(0.9453125000),
    COEF_CONST(0.9375000000), COEF_CONST(0.9296875000),
    COEF_CONST(0.9257812500), COEF_CONST(0.9179687500),
    COEF_CONST(0.9101562500), COEF_CONST(0.9023437500),
    COEF_CONST(0.8984375000), COEF_CONST(0.8906250000),
    COEF_CONST(0.8828125000), COEF_CONST(0.8789062500),
    COEF_CONST(0.8710937500), COEF_CONST(0.8671875000),
    COEF_CONST(0.8593750000), COEF_CONST(0.8515625000),
    COEF_CONST(0.8476562500), COEF_CONST(0.8398437500),
    COEF_CONST(0.8359375000), COEF_CONST(0.8281250000),
    COEF_CONST(0.8242187500), COEF_CONST(0.8203125000),
    COEF_CONST(0.8125000000), COEF_CONST(0.8085937500),
    COEF_CONST(0.8007812500), COEF_CONST(0.7968750000),
    COEF_CONST(0.7929687500), COEF_CONST(0.7851562500),
    COEF_CONST(0.7812500000), COEF_CONST(0.7773437500),
    COEF_CONST(0.7734375000), COEF_CONST(0.7656250000),
    COEF_CONST(0.7617187500), COEF_CONST(0.7578125000),
    COEF_CONST(0.7539062500), COEF_CONST(0.7500000000),
    COEF_CONST(0.7421875000), COEF_CONST(0.7382812500),
    COEF_CONST(0.7343750000), COEF_CONST(0.7304687500),
    COEF_CONST(0.7265625000), COEF_CONST(0.7226562500),
    COEF_CONST(0.7187500000), COEF_CONST(0.7148437500),
    COEF_CONST(0.7109375000), COEF_CONST(0.7070312500),
    COEF_CONST(0.6992187500), COEF_CONST(0.6953125000),
    COEF_CONST(0.6914062500), COEF_CONST(0.6875000000),
    COEF_CONST(0.6835937500), COEF_CONST(0.6796875000),
    COEF_CONST(0.6796875000), COEF_CONST(0.6757812500),
    COEF_CONST(0.6718750000), COEF_CONST(0.6679687500),
    COEF_CONST(0.6640625000), COEF_CONST(0.6601562500),
    COEF_CONST(0.6562500000), COEF_CONST(0.6523437500),
    COEF_CONST(0.6484375000), COEF_CONST(0.6445312500),
    COEF_CONST(0.6406250000), COEF_CONST(0.6406250000),
    COEF_CONST(0.6367187500), COEF_CONST(0.6328125000),
    COEF_CONST(0.6289062500), COEF_CONST(0.6250000000),
    COEF_CONST(0.6210937500), COEF_CONST(0.6210937500),
    COEF_CONST(0.6171875000), COEF_CONST(0.6132812500),
    COEF_CONST(0.6093750000), COEF_CONST(0.6054687500),
    COEF_CONST(0.6054687500), COEF_CONST(0.6015625000),
    COEF_CONST(0.5976562500), COEF_CONST(0.5937500000),
    COEF_CONST(0.5937500000), COEF_CONST(0.5898437500),
    COEF_CONST(0.5859375000), COEF_CONST(0.5820312500),
    COEF_CONST(0.5820312500), COEF_CONST(0.5781250000),
    COEF_CONST(0.5742187500), COEF_CONST(0.5742187500),
    COEF_CONST(0.5703125000), COEF_CONST(0.5664062500),
    COEF_CONST(0.5664062500), COEF_CONST(0.5625000000),
    COEF_CONST(0.5585937500), COEF_CONST(0.5585937500),
    COEF_CONST(0.5546875000), COEF_CONST(0.5507812500),
    COEF_CONST(0.5507812500), COEF_CONST(0.5468750000),
    COEF_CONST(0.5429687500), COEF_CONST(0.5429687500),
    COEF_CONST(0.5390625000), COEF_CONST(0.5390625000),
    COEF_CONST(0.5351562500), COEF_CONST(0.5312500000),
    COEF_CONST(0.5312500000), COEF_CONST(0.5273437500),
    COEF_CONST(0.5273437500), COEF_CONST(0.5234375000),
    COEF_CONST(0.5195312500), COEF_CONST(0.5195312500),
    COEF_CONST(0.5156250000), COEF_CONST(0.5156250000),
    COEF_CONST(0.5117187500), COEF_CONST(0.5117187500),
    COEF_CONST(0.5078125000), COEF_CONST(0.5078125000),
    COEF_CONST(0.5039062500), COEF_CONST(0.5039062500),
    COEF_CONST(0.5000000000), COEF_CONST(0.4980468750),
    COEF_CONST(0.4960937500), COEF_CONST(0.4941406250),
    COEF_CONST(0.4921875000), COEF_CONST(0.4902343750),
    COEF_CONST(0.4882812500), COEF_CONST(0.4863281250),
    COEF_CONST(0.4843750000), COEF_CONST(0.4824218750),
    COEF_CONST(0.4804687500), COEF_CONST(0.4785156250)
};
#warning MEM_ALIGN_ATTR me!
static const real_t exp_table[128] = {
    COEF_CONST(0.50000000000000000000000000000000000000000000000000),
    COEF_CONST(0.25000000000000000000000000000000000000000000000000),
    COEF_CONST(0.12500000000000000000000000000000000000000000000000),
    COEF_CONST(0.06250000000000000000000000000000000000000000000000),
    COEF_CONST(0.03125000000000000000000000000000000000000000000000),
    COEF_CONST(0.01562500000000000000000000000000000000000000000000),
    COEF_CONST(0.00781250000000000000000000000000000000000000000000),
    COEF_CONST(0.00390625000000000000000000000000000000000000000000),
    COEF_CONST(0.00195312500000000000000000000000000000000000000000),
    COEF_CONST(0.00097656250000000000000000000000000000000000000000),
    COEF_CONST(0.00048828125000000000000000000000000000000000000000),
    COEF_CONST(0.00024414062500000000000000000000000000000000000000),
    COEF_CONST(0.00012207031250000000000000000000000000000000000000),
    COEF_CONST(0.00006103515625000000000000000000000000000000000000),
    COEF_CONST(0.00003051757812500000000000000000000000000000000000),
    COEF_CONST(0.00001525878906250000000000000000000000000000000000),
    COEF_CONST(0.00000762939453125000000000000000000000000000000000),
    COEF_CONST(0.00000381469726562500000000000000000000000000000000),
    COEF_CONST(0.00000190734863281250000000000000000000000000000000),
    COEF_CONST(0.00000095367431640625000000000000000000000000000000),
    COEF_CONST(0.00000047683715820312500000000000000000000000000000),
    COEF_CONST(0.00000023841857910156250000000000000000000000000000),
    COEF_CONST(0.00000011920928955078125000000000000000000000000000),
    COEF_CONST(0.00000005960464477539062500000000000000000000000000),
    COEF_CONST(0.00000002980232238769531300000000000000000000000000),
    COEF_CONST(0.00000001490116119384765600000000000000000000000000),
    COEF_CONST(0.00000000745058059692382810000000000000000000000000),
    COEF_CONST(0.00000000372529029846191410000000000000000000000000),
    COEF_CONST(0.00000000186264514923095700000000000000000000000000),
    COEF_CONST(0.00000000093132257461547852000000000000000000000000),
    COEF_CONST(0.00000000046566128730773926000000000000000000000000),
    COEF_CONST(0.00000000023283064365386963000000000000000000000000),
    COEF_CONST(0.00000000011641532182693481000000000000000000000000),
    COEF_CONST(0.00000000005820766091346740700000000000000000000000),
    COEF_CONST(0.00000000002910383045673370400000000000000000000000),
    COEF_CONST(0.00000000001455191522836685200000000000000000000000),
    COEF_CONST(0.00000000000727595761418342590000000000000000000000),
    COEF_CONST(0.00000000000363797880709171300000000000000000000000),
    COEF_CONST(0.00000000000181898940354585650000000000000000000000),
    COEF_CONST(0.00000000000090949470177292824000000000000000000000),
    COEF_CONST(0.00000000000045474735088646412000000000000000000000),
    COEF_CONST(0.00000000000022737367544323206000000000000000000000),
    COEF_CONST(0.00000000000011368683772161603000000000000000000000),
    COEF_CONST(0.00000000000005684341886080801500000000000000000000),
    COEF_CONST(0.00000000000002842170943040400700000000000000000000),
    COEF_CONST(0.00000000000001421085471520200400000000000000000000),
    COEF_CONST(0.00000000000000710542735760100190000000000000000000),
    COEF_CONST(0.00000000000000355271367880050090000000000000000000),
    COEF_CONST(0.00000000000000177635683940025050000000000000000000),
    COEF_CONST(0.00000000000000088817841970012523000000000000000000),
    COEF_CONST(0.00000000000000044408920985006262000000000000000000),
    COEF_CONST(0.00000000000000022204460492503131000000000000000000),
    COEF_CONST(0.00000000000000011102230246251565000000000000000000),
    COEF_CONST(0.00000000000000005551115123125782700000000000000000),
    COEF_CONST(0.00000000000000002775557561562891400000000000000000),
    COEF_CONST(0.00000000000000001387778780781445700000000000000000),
    COEF_CONST(0.00000000000000000693889390390722840000000000000000),
    COEF_CONST(0.00000000000000000346944695195361420000000000000000),
    COEF_CONST(0.00000000000000000173472347597680710000000000000000),
    COEF_CONST(0.00000000000000000086736173798840355000000000000000),
    COEF_CONST(0.00000000000000000043368086899420177000000000000000),
    COEF_CONST(0.00000000000000000021684043449710089000000000000000),
    COEF_CONST(0.00000000000000000010842021724855044000000000000000),
    COEF_CONST(0.00000000000000000005421010862427522200000000000000),
    COEF_CONST(0.00000000000000000002710505431213761100000000000000),
    COEF_CONST(0.00000000000000000001355252715606880500000000000000),
    COEF_CONST(0.00000000000000000000677626357803440270000000000000),
    COEF_CONST(0.00000000000000000000338813178901720140000000000000),
    COEF_CONST(0.00000000000000000000169406589450860070000000000000),
    COEF_CONST(0.00000000000000000000084703294725430034000000000000),
    COEF_CONST(0.00000000000000000000042351647362715017000000000000),
    COEF_CONST(0.00000000000000000000021175823681357508000000000000),
    COEF_CONST(0.00000000000000000000010587911840678754000000000000),
    COEF_CONST(0.00000000000000000000005293955920339377100000000000),
    COEF_CONST(0.00000000000000000000002646977960169688600000000000),
    COEF_CONST(0.00000000000000000000001323488980084844300000000000),
    COEF_CONST(0.00000000000000000000000661744490042422140000000000),
    COEF_CONST(0.00000000000000000000000330872245021211070000000000),
    COEF_CONST(0.00000000000000000000000165436122510605530000000000),
    COEF_CONST(0.00000000000000000000000082718061255302767000000000),
    COEF_CONST(0.00000000000000000000000041359030627651384000000000),
    COEF_CONST(0.00000000000000000000000020679515313825692000000000),
    COEF_CONST(0.00000000000000000000000010339757656912846000000000),
    COEF_CONST(0.00000000000000000000000005169878828456423000000000),
    COEF_CONST(0.00000000000000000000000002584939414228211500000000),
    COEF_CONST(0.00000000000000000000000001292469707114105700000000),
    COEF_CONST(0.00000000000000000000000000646234853557052870000000),
    COEF_CONST(0.00000000000000000000000000323117426778526440000000),
    COEF_CONST(0.00000000000000000000000000161558713389263220000000),
    COEF_CONST(0.00000000000000000000000000080779356694631609000000),
    COEF_CONST(0.00000000000000000000000000040389678347315804000000),
    COEF_CONST(0.00000000000000000000000000020194839173657902000000),
    COEF_CONST(0.00000000000000000000000000010097419586828951000000),
    COEF_CONST(0.00000000000000000000000000005048709793414475600000),
    COEF_CONST(0.00000000000000000000000000002524354896707237800000),
    COEF_CONST(0.00000000000000000000000000001262177448353618900000),
    COEF_CONST(0.00000000000000000000000000000631088724176809440000),
    COEF_CONST(0.00000000000000000000000000000315544362088404720000),
    COEF_CONST(0.00000000000000000000000000000157772181044202360000),
    COEF_CONST(0.00000000000000000000000000000078886090522101181000),
    COEF_CONST(0.00000000000000000000000000000039443045261050590000),
    COEF_CONST(0.00000000000000000000000000000019721522630525295000),
    COEF_CONST(0.00000000000000000000000000000009860761315262647600),
    COEF_CONST(0.00000000000000000000000000000004930380657631323800),
    COEF_CONST(0.00000000000000000000000000000002465190328815661900),
    COEF_CONST(0.00000000000000000000000000000001232595164407830900),
    COEF_CONST(0.00000000000000000000000000000000616297582203915470),
    COEF_CONST(0.00000000000000000000000000000000308148791101957740),
    COEF_CONST(0.00000000000000000000000000000000154074395550978870),
    COEF_CONST(0.00000000000000000000000000000000077037197775489434),
    COEF_CONST(0.00000000000000000000000000000000038518598887744717),
    COEF_CONST(0.00000000000000000000000000000000019259299443872359),
    COEF_CONST(0.00000000000000000000000000000000009629649721936179),
    COEF_CONST(0.00000000000000000000000000000000004814824860968090),
    COEF_CONST(0.00000000000000000000000000000000002407412430484045),
    COEF_CONST(0.00000000000000000000000000000000001203706215242022),
    COEF_CONST(0.00000000000000000000000000000000000601853107621011),
    COEF_CONST(0.00000000000000000000000000000000000300926553810506),
    COEF_CONST(0.00000000000000000000000000000000000150463276905253),
    COEF_CONST(0.00000000000000000000000000000000000075231638452626),
    COEF_CONST(0.00000000000000000000000000000000000037615819226313),
    COEF_CONST(0.00000000000000000000000000000000000018807909613157),
    COEF_CONST(0.00000000000000000000000000000000000009403954806578),
    COEF_CONST(0.00000000000000000000000000000000000004701977403289),
    COEF_CONST(0.00000000000000000000000000000000000002350988701645),
    COEF_CONST(0.00000000000000000000000000000000000001175494350822),
    COEF_CONST(0.0 /* 0000000000000000000000000000000000000587747175411 "floating point underflow" */),
    COEF_CONST(0.0)
};

#ifdef __cplusplus
}
#endif
#endif

#endif
an class="hl num">0x5555] = 0xAA; /* enter command mode */ FB[0x2AAA] = 0x55; FB[0x5555] = 0xA0; /* byte program command */ *pAddr = data; /* I counted 7 instructions for this loop -> min. 0.58 us per round */ /* Plus memory waitstates it will be much more, gives margin */ while (*pAddr != data && --timeout); /* poll for programmed */ return (timeout != 0); #endif } /* this returns true if supported and fills the info struct */ bool GetFlashInfo(tFlashInfo* pInfo) { rb->memset(pInfo, 0, sizeof(tFlashInfo)); if (!ReadID(FB, &pInfo->manufacturer, &pInfo->id)) return false; if (pInfo->manufacturer == 0xBF) /* SST */ { if (pInfo->id == 0xD6) { pInfo->size = 256* 1024; /* 256k */ rb->strcpy(pInfo->name, "SST39VF020"); return true; } else if (pInfo->id == 0xD7) { pInfo->size = 512* 1024; /* 512k */ rb->strcpy(pInfo->name, "SST39VF040"); return true; } else return false; } return false; } /*********** Firmware File Functions + helpers ************/ /* test if the version number is consistent with the platform */ bool CheckPlatform(int platform_id, UINT16 version) { if (version == 200) { /* for my very first firmwares, I foolishly changed it to 200 */ return (platform_id == ID_RECORDER || platform_id == ID_FM); } else if (version == 123) { /* it can be a FM or V2 recorder */ return (platform_id == ID_FM || platform_id == ID_REC_V2); } else if (version == 132) { /* newer Ondio, and seen on a V2 recorder */ return (platform_id == ID_ONDIO_SP || platform_id == ID_ONDIO_FM || platform_id == ID_REC_V2); } else if (version == 104) { /* classic Ondio128 */ return (platform_id == ID_ONDIO_FM); } else if (version >= 115 && version <= 129) { /* the range of Recorders seen so far */ return (platform_id == ID_RECORDER); } else if (version == 0 || (version >= 300 && version <= 508)) { /* for very old players, I've seen zero */ return (platform_id == ID_PLAYER); } return false; /* unknown */ } tCheckResult CheckFirmwareFile(char* filename, int chipsize, bool is_romless) { int i; int fd; int fileleft; /* size info, how many left for reading */ int fileread = 0; /* total size as read from the file */ int read_now; /* how many to read for this sector */ int got_now; /* how many gotten for this sector */ unsigned crc32 = 0xFFFFFFFF; /* CCITT init value */ unsigned file_crc; /* CRC value read from file */ bool has_crc; fd = rb->open(filename, O_RDONLY); if (fd < 0) return eFileNotFound; fileleft = rb->filesize(fd); if (fileleft > chipsize) { rb->close(fd); return eTooBig; } else if (fileleft < 20000) /* give it some reasonable lower limit */ { rb->close(fd); return eTooSmall; } if (fileleft == 256*1024) { /* original dumped firmware file has no CRC nor platform ID */ has_crc = false; } else { has_crc = true; fileleft -= sizeof(unsigned); /* exclude the last 4 bytes */ } /* do some sanity checks */ got_now = rb->read(fd, sector, SEC_SIZE); /* read first sector */ fileread += got_now; fileleft -= got_now; if (got_now != SEC_SIZE) { rb->close(fd); return eReadErr; } /* version number in file plausible with this hardware? */ if (!CheckPlatform(PLATFORM_ID, *(UINT16*)(sector + VERSION_ADR))) { rb->close(fd); return eBadPlatform; } if (has_crc) { crc32 = rb->crc_32(sector, SEC_SIZE, crc32); /* checksum */ /* in addition to the CRC, my files also have a platform ID */ if (sector[PLATFORM_ADR] != PLATFORM_ID) /* for our hardware? */ { rb->close(fd); return eBadPlatform; } } if (is_romless) { /* in this case, there is not much we can check */ if (*(UINT32*)sector != 0x00000200) /* reset vector */ { rb->close(fd); return eBadContent; } } else { /* compare some bytes which have to be identical */ if (*(UINT32*)sector != 0x41524348) /* "ARCH" */ { rb->close(fd); return eBadContent; } for (i = 0x30; i<MASK_ADR-2; i++) /* leave two bytes for me */ { if (sector[i] != FB[i]) { rb->close(fd); return eBadContent; } } } /* check if we can read the whole file, and do checksum */ do { read_now = MIN(SEC_SIZE, fileleft); got_now = rb->read(fd, sector, read_now); fileread += got_now; fileleft -= got_now; if (read_now != got_now) { rb->close(fd); return eReadErr; } if (has_crc) { crc32 = rb->crc_32(sector, got_now, crc32); /* checksum */ } } while (fileleft); if (has_crc) { got_now = rb->read(fd, &file_crc, sizeof(file_crc)); if (got_now != sizeof(file_crc)) { rb->close(fd); return eReadErr; } } /* must be EOF now */ got_now = rb->read(fd, sector, SEC_SIZE); rb->close(fd); if (got_now != 0) return eReadErr; if (has_crc && file_crc != crc32) return eCrcErr; return eOK; } /* returns the # of failures, 0 on success */ unsigned ProgramFirmwareFile(char* filename, int chipsize) { int i, j; int fd; int read = SEC_SIZE; /* how many for this sector */ UINT16 keep = *(UINT16*)(FB + KEEP); /* we must keep this! */ unsigned failures = 0; fd = rb->open(filename, O_RDONLY); if (fd < 0) return false; for (i=0; i<chipsize; i+=SEC_SIZE) { if (!EraseSector(FB + i)) { /* nothing we can do, let the programming count the errors */ } if (read == SEC_SIZE) /* not EOF yet */ { read = rb->read(fd, sector, SEC_SIZE); if (i==0) { /* put original value back in */ *(UINT16*)(sector + KEEP) = keep; } for (j=0; j<read; j++) { if (!ProgramByte(FB + i + j, sector[j])) { failures++; } } } } rb->close(fd); return failures; } /* returns the # of failures, 0 on success */ unsigned VerifyFirmwareFile(char* filename) { int i=0, j; int fd; int read = SEC_SIZE; /* how many for this sector */ unsigned failures = 0; fd = rb->open(filename, O_RDONLY); if (fd < 0) return false; do { read = rb->read(fd, sector, SEC_SIZE); for (j=0; j<read; j++) { /* position of keep value is no error */ if (FB[i] != sector[j] && i != KEEP && i != (KEEP+1)) { failures++; } i++; } } while (read == SEC_SIZE); rb->close(fd); return failures; } /***************** Support Functions *****************/ /* check if we have "normal" boot ROM or flash mirrored to zero */ tCheckROM CheckBootROM(void) { unsigned boot_crc; unsigned* pFlash = (unsigned*)FB; unsigned* pRom = (unsigned*)0x0; unsigned i; boot_crc = rb->crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF); if (boot_crc == 0x56DBA4EE /* the known boot ROM */ #if PLATFORM_ID == ID_PLAYER /* alternative boot ROM found in one single player so far */ || boot_crc == 0x358099E8 #endif ) return eBootROM; /* check if ROM is a flash mirror */ for (i=0; i<256*1024/sizeof(unsigned); i++) { if (*pRom++ != *pFlash++) { /* difference means no mirror */ return eUnknown; } } return eROMless; } /***************** User Interface Functions *****************/ int WaitForButton(void) { int button; do { button = rb->button_get(true); } while (IS_SYSEVENT(button) || (button & BUTTON_REL)); return button; } #ifdef HAVE_LCD_BITMAP /* Recorder implementation */ /* helper for DoUserDialog() */ void ShowFlashInfo(tFlashInfo* pInfo) { char buf[32]; if (!pInfo->manufacturer) { rb->lcd_puts(0, 0, "Flash: M=?? D=??"); rb->lcd_puts(0, 1, "Impossible to program"); } else { rb->snprintf(buf, sizeof(buf), "Flash: M=%02x D=%02x", pInfo->manufacturer, pInfo->id); rb->lcd_puts(0, 0, buf); if (pInfo->size) { rb->lcd_puts(0, 1, pInfo->name); rb->snprintf(buf, sizeof(buf), "Size: %d KB", pInfo->size / 1024); rb->lcd_puts(0, 2, buf); } else { rb->lcd_puts(0, 1, "Unsupported chip"); } } rb->lcd_update(); } /* Kind of our main function, defines the application flow. */ void DoUserDialog(char* filename) { tFlashInfo FlashInfo; char buf[32]; char default_filename[32]; int button; int rc; /* generic return code */ size_t memleft; tCheckROM result; bool is_romless; /* this can only work if Rockbox runs in DRAM, not flash ROM */ if ((UINT8*)rb >= FB && (UINT8*)rb < FB + 4096*1024) /* 4 MB max */ { /* we're running from flash */ rb->splash(HZ*3, "Not from ROM"); return; /* exit */ } /* test if the user is running the correct plugin for this box */ if (!CheckPlatform(PLATFORM_ID, *(UINT16*)(FB + VERSION_ADR))) { rb->splash(HZ*3, "Wrong plugin"); return; /* exit */ } /* refuse to work if the power may fail meanwhile */ if (!rb->battery_level_safe()) { rb->splash(HZ*3, "Battery too low!"); return; /* exit */ } /* check boot ROM */ result = CheckBootROM(); if (result == eUnknown) { /* no support for any other yet */ rb->splash(HZ*3, "Wrong boot ROM"); return; /* exit */ } is_romless = (result == eROMless); /* compose filename if none given */ if (filename == NULL) { rb->snprintf( default_filename, sizeof(default_filename), "/firmware_%s%s.bin", FILE_TYPE, is_romless ? "_norom" : ""); filename = default_filename; } /* "allocate" memory */ sector = rb->plugin_get_buffer(&memleft); if (memleft < SEC_SIZE) /* need buffer for a flash sector */ { rb->splash(HZ*3, "Out of memory"); return; /* exit */ } rb->lcd_setfont(FONT_SYSFIXED); rc = GetFlashInfo(&FlashInfo); ShowFlashInfo(&FlashInfo); if (FlashInfo.size == 0) /* no valid chip */ { rb->splash(HZ*3, "Sorry!"); return; /* exit */ } rb->lcd_puts(0, 3, "using file:"); rb->lcd_puts_scroll(0, 4, filename); rb->lcd_puts(0, 6, KEYNAME1 " to check file"); rb->lcd_puts(0, 7, "other key to exit"); rb->lcd_update(); button = WaitForButton(); if (button != KEY1) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "checking..."); rb->lcd_update(); rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless); rb->lcd_puts(0, 0, "checked:"); switch (rc) { case eOK: rb->lcd_puts(0, 1, "File OK."); break; case eFileNotFound: rb->lcd_puts(0, 1, "File not found."); rb->lcd_puts(0, 2, "Put this in root:"); rb->lcd_puts_scroll(0, 4, filename); break; case eTooBig: rb->lcd_puts(0, 1, "File too big,"); rb->lcd_puts(0, 2, "larger than chip."); break; case eTooSmall: rb->lcd_puts(0, 1, "File too small."); rb->lcd_puts(0, 2, "Incomplete?"); break; case eReadErr: rb->lcd_puts(0, 1, "Read error."); break; case eBadContent: rb->lcd_puts(0, 1, "File invalid."); rb->lcd_puts(0, 2, "Sanity check fail."); break; case eCrcErr: rb->lcd_puts(0, 1, "File invalid."); rb->lcd_puts(0, 2, "CRC check failed,"); rb->lcd_puts(0, 3, "checksum mismatch."); break; case eBadPlatform: rb->lcd_puts(0, 1, "Wrong file for"); rb->lcd_puts(0, 2, "this hardware."); break; default: rb->lcd_puts(0, 1, "Check failed."); break; } if (rc == eOK) { rb->lcd_puts(0, 6, KEYNAME2 " to program"); rb->lcd_puts(0, 7, "other key to exit"); } else { /* error occured */ rb->lcd_puts(0, 6, "Any key to exit"); } rb->lcd_update(); button = WaitForButton(); if (button != KEY2 || rc != eOK) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Program all Flash?"); rb->lcd_puts(0, 1, "Are you sure?"); rb->lcd_puts(0, 2, "If it goes wrong,"); rb->lcd_puts(0, 3, "it kills your box!"); rb->lcd_puts(0, 4, "See documentation."); rb->lcd_puts(0, 6, KEYNAME3 " to proceed"); rb->lcd_puts(0, 7, "other key to exit"); rb->lcd_update(); button = WaitForButton(); if (button != KEY3) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Programming..."); rb->lcd_update(); rc = ProgramFirmwareFile(filename, FlashInfo.size); if (rc) { /* errors */ rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Panic:"); rb->lcd_puts(0, 1, "Programming fail!"); rb->snprintf(buf, sizeof(buf), "%d errors", rc); rb->lcd_puts(0, 2, buf); rb->lcd_update(); button = WaitForButton(); } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Verifying..."); rb->lcd_update(); rc = VerifyFirmwareFile(filename); rb->lcd_clear_display(); if (rc == 0) { rb->lcd_puts(0, 0, "Verify OK."); } else { rb->lcd_puts(0, 0, "Panic:"); rb->lcd_puts(0, 1, "Verify fail!"); rb->snprintf(buf, sizeof(buf), "%d errors", rc); rb->lcd_puts(0, 2, buf); } rb->lcd_puts(0, 7, "Any key to exit"); rb->lcd_update(); button = WaitForButton(); } #else /* HAVE_LCD_BITMAP */ /* Player implementation */ /* helper for DoUserDialog() */ void ShowFlashInfo(tFlashInfo* pInfo) { char buf[32]; if (!pInfo->manufacturer) { rb->lcd_puts_scroll(0, 0, "Flash: M=? D=?"); rb->lcd_puts_scroll(0, 1, "Impossible to program"); rb->lcd_update(); WaitForButton(); } else { rb->snprintf(buf, sizeof(buf), "Flash: M=%02x D=%02x", pInfo->manufacturer, pInfo->id); rb->lcd_puts_scroll(0, 0, buf); if (pInfo->size) { rb->snprintf(buf, sizeof(buf), "Size: %d KB", pInfo->size / 1024); rb->lcd_puts_scroll(0, 1, buf); rb->lcd_update(); } else { rb->lcd_puts_scroll(0, 1, "Unsupported chip"); rb->lcd_update(); WaitForButton(); } } } void DoUserDialog(char* filename) { tFlashInfo FlashInfo; char buf[32]; char default_filename[32]; int button; int rc; /* generic return code */ size_t memleft; tCheckROM result; bool is_romless; /* this can only work if Rockbox runs in DRAM, not flash ROM */ if ((UINT8*)rb >= FB && (UINT8*)rb < FB + 4096*1024) /* 4 MB max */ { /* we're running from flash */ rb->splash(HZ*3, "Not from ROM"); return; /* exit */ } /* test if the user is running the correct plugin for this box */ if (!CheckPlatform(PLATFORM_ID, *(UINT16*)(FB + VERSION_ADR))) { rb->splash(HZ*3, "Wrong version"); return; /* exit */ } /* refuse to work if the power may fail meanwhile */ if (!rb->battery_level_safe()) { rb->splash(HZ*3, "Batt. too low!"); return; /* exit */ } /* check boot ROM */ result = CheckBootROM(); if (result == eUnknown) { /* no support for any other yet */ rb->splash(HZ*3, "Wrong boot ROM"); return; /* exit */ } is_romless = (result == eROMless); /* compose filename if none given */ if (filename == NULL) { rb->snprintf( default_filename, sizeof(default_filename), "/firmware_%s%s.bin", FILE_TYPE, is_romless ? "_norom" : ""); filename = default_filename; } /* "allocate" memory */ sector = rb->plugin_get_buffer(&memleft); if (memleft < SEC_SIZE) /* need buffer for a flash sector */ { rb->splash(HZ*3, "Out of memory"); return; /* exit */ } rc = GetFlashInfo(&FlashInfo); ShowFlashInfo(&FlashInfo); if (FlashInfo.size == 0) /* no valid chip */ { return; /* exit */ } rb->lcd_puts_scroll(0, 0, filename); rb->lcd_puts_scroll(0, 1, "[Menu] to check"); rb->lcd_update(); button = WaitForButton(); if (button != BUTTON_MENU) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Checking..."); rb->lcd_update(); rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless); rb->lcd_puts(0, 0, "Checked:"); switch (rc) { case eOK: rb->lcd_puts(0, 1, "File OK."); break; case eFileNotFound: rb->lcd_puts_scroll(0, 0, "File not found:"); rb->lcd_puts_scroll(0, 1, filename); break; case eTooBig: rb->lcd_puts_scroll(0, 0, "File too big,"); rb->lcd_puts_scroll(0, 1, "larger than chip."); break; case eTooSmall: rb->lcd_puts_scroll(0, 0, "File too small."); rb->lcd_puts_scroll(0, 1, "Incomplete?"); break; case eReadErr: rb->lcd_puts_scroll(0, 0, "Read error."); break; case eBadContent: rb->lcd_puts_scroll(0, 0, "File invalid."); rb->lcd_puts_scroll(0, 1, "Sanity check failed."); break; case eCrcErr: rb->lcd_puts_scroll(0, 0, "File invalid."); rb->lcd_puts_scroll(0, 1, "CRC check failed."); break; case eBadPlatform: rb->lcd_puts_scroll(0, 0, "Wrong file for"); rb->lcd_puts_scroll(0, 1, "this hardware."); break; default: rb->lcd_puts_scroll(0, 0, "Check failed."); break; } rb->lcd_update(); rb->sleep(HZ*3); if (rc == eOK) { rb->lcd_puts_scroll(0, 0, "[On] to program,"); rb->lcd_puts_scroll(0, 1, "other key to exit."); rb->lcd_update(); } else { /* error occured */ return; } button = WaitForButton(); if (button != BUTTON_ON) { return; } rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Are you sure?"); rb->lcd_puts_scroll(0, 1, "[+] to proceed."); rb->lcd_update(); button = WaitForButton(); if (button != BUTTON_RIGHT) { return; } rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Programming..."); rb->lcd_update(); rc = ProgramFirmwareFile(filename, FlashInfo.size); if (rc) { /* errors */ rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Programming failed!"); rb->snprintf(buf, sizeof(buf), "%d errors", rc); rb->lcd_puts_scroll(0, 1, buf); rb->lcd_update(); WaitForButton(); } rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Verifying..."); rb->lcd_update(); rc = VerifyFirmwareFile(filename); rb->lcd_clear_display(); if (rc == 0) { rb->lcd_puts_scroll(0, 0, "Verify OK."); } else { rb->snprintf(buf, sizeof(buf), "Verify failed! %d errors", rc); rb->lcd_puts_scroll(0, 0, buf); } rb->lcd_puts_scroll(0, 1, "Press any key to exit."); rb->lcd_update(); WaitForButton(); } #endif /* not HAVE_LCD_BITMAP */ /***************** Plugin Entry Point *****************/ enum plugin_status plugin_start(const void* parameter) { int oldmode; /* now go ahead and have fun! */ oldmode = rb->system_memory_guard(MEMGUARD_NONE); /*disable memory guard */ DoUserDialog((char*) parameter); rb->system_memory_guard(oldmode); /* re-enable memory guard */ return PLUGIN_OK; }