summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2010-05-24 10:06:52 +0000
committerRafaël Carré <rafael.carre@gmail.com>2010-05-24 10:06:52 +0000
commitff6b0425e438add8d12393f90fdbfe93e1fb4746 (patch)
treeb8ac1a3254a8e01051a5d7f2c5c94e61bacd5c02
parenteae2464e9a93dc3a8918abcc62348af6c8d9bc9b (diff)
downloadrockbox-ff6b0425e438add8d12393f90fdbfe93e1fb4746.tar.gz
rockbox-ff6b0425e438add8d12393f90fdbfe93e1fb4746.zip
mkamsboot/rbutil/amsinfo : do not try to detect the model of a given Sansa AMS OF
The field we thought was representative of the model is not, it has changed in the past for fuzev1 and fuzev2. For example the value 0x23 is found in 2 old fuzev1 OF versions, and in the c200v2 OF The only reliable way to detect the model of a given OF is by using the built-in list of md5sums. Modify mkamsboot and rbutilqt to load the rockbox bootloader first, and then check if the model in the bootloader corresponds to the model of the known md5sum of the given OF. That way we can continue to present the user with a list of known OF versions in case the OF is unknown to mkamsboot Also explicit the dependency of main.c on mkamsboot.h in case the prototypes change Correct the header's description not updated in r21648 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26248 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--rbutil/mkamsboot/Makefile6
-rw-r--r--rbutil/mkamsboot/main.c24
-rw-r--r--rbutil/mkamsboot/mkamsboot.c63
-rw-r--r--rbutil/mkamsboot/mkamsboot.h13
-rw-r--r--rbutil/rbutilqt/base/bootloaderinstallams.cpp33
-rw-r--r--utils/AMS/hacking/amsinfo.c37
6 files changed, 60 insertions, 116 deletions
diff --git a/rbutil/mkamsboot/Makefile b/rbutil/mkamsboot/Makefile
index 60e1ea8af8..8a9a4d3852 100644
--- a/rbutil/mkamsboot/Makefile
+++ b/rbutil/mkamsboot/Makefile
@@ -47,9 +47,9 @@ OBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(SOURCES)))
47LIBOBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(LIBSOURCES))) 47LIBOBJS := $(patsubst %.c,%.o,$(addprefix $(OBJDIR),$(LIBSOURCES)))
48EXTRADEPS := $(LIBUCL) 48EXTRADEPS := $(LIBUCL)
49 49
50# explicit dependencies on dualboot.{c,h} 50# explicit dependencies on dualboot.{c,h} and mkamsboot.h
51$(OBJDIR)mkamsboot.o: dualboot.h dualboot.c mkamsboot.c 51$(OBJDIR)mkamsboot.o: dualboot.h dualboot.c mkamsboot.c mkamsboot.h
52$(OBJDIR)main.o: dualboot.h dualboot.c main.c 52$(OBJDIR)main.o: dualboot.h dualboot.c main.c mkamsboot.h
53 53
54$(OBJDIR)%.o: %.c 54$(OBJDIR)%.o: %.c
55 @echo CC $< $ 55 @echo CC $< $
diff --git a/rbutil/mkamsboot/main.c b/rbutil/mkamsboot/main.c
index 1132334261..a864c2a5c1 100644
--- a/rbutil/mkamsboot/main.c
+++ b/rbutil/mkamsboot/main.c
@@ -59,6 +59,7 @@ int main(int argc, char* argv[])
59 int rb_packedsize; 59 int rb_packedsize;
60 int patchable; 60 int patchable;
61 int totalsize; 61 int totalsize;
62 int model;
62 char errstr[200]; 63 char errstr[200];
63 struct md5sums sum; 64 struct md5sums sum;
64 char md5sum[33]; /* 32 digits + \0 */ 65 char md5sum[33]; /* 32 digits + \0 */
@@ -81,11 +82,21 @@ int main(int argc, char* argv[])
81 bootfile = argv[2]; 82 bootfile = argv[2];
82 outfile = argv[3]; 83 outfile = argv[3];
83 84
85 /* Load bootloader file */
86 rb_packed = load_rockbox_file(bootfile, &model, &bootloader_size,
87 &rb_packedsize, errstr, sizeof(errstr));
88 if (rb_packed == NULL) {
89 fprintf(stderr, "%s", errstr);
90 fprintf(stderr, "[ERR] Could not load %s\n", bootfile);
91 return 1;
92 }
93
84 /* Load original firmware file */ 94 /* Load original firmware file */
85 buf = load_of_file(infile, &len, &sum, 95 buf = load_of_file(infile, model, &len, &sum,
86 &firmware_size, &of_packed, &of_packedsize, errstr, sizeof(errstr)); 96 &firmware_size, &of_packed, &of_packedsize, errstr, sizeof(errstr));
87 97
88 if (buf == NULL) { 98 if (buf == NULL) {
99 free(rb_packed);
89 fprintf(stderr, "%s", errstr); 100 fprintf(stderr, "%s", errstr);
90 fprintf(stderr, "[ERR] Could not load %s\n", infile); 101 fprintf(stderr, "[ERR] Could not load %s\n", infile);
91 return 1; 102 return 1;
@@ -96,17 +107,6 @@ int main(int argc, char* argv[])
96 model_names[sum.model], hw_revisions[sum.model], sum.version); 107 model_names[sum.model], hw_revisions[sum.model], sum.version);
97 108
98 109
99 /* Load bootloader file */
100 rb_packed = load_rockbox_file(bootfile, sum.model, &bootloader_size,
101 &rb_packedsize, errstr, sizeof(errstr));
102 if (rb_packed == NULL) {
103 fprintf(stderr, "%s", errstr);
104 fprintf(stderr, "[ERR] Could not load %s\n", bootfile);
105 free(buf);
106 free(of_packed);
107 return 1;
108 }
109
110 printf("[INFO] Firmware patching has begun !\n\n"); 110 printf("[INFO] Firmware patching has begun !\n\n");
111 111
112 fprintf(stderr, "[INFO] Original firmware size: %d bytes\n", 112 fprintf(stderr, "[INFO] Original firmware size: %d bytes\n",
diff --git a/rbutil/mkamsboot/mkamsboot.c b/rbutil/mkamsboot/mkamsboot.c
index 1ec9ec26e6..f47afe312a 100644
--- a/rbutil/mkamsboot/mkamsboot.c
+++ b/rbutil/mkamsboot/mkamsboot.c
@@ -323,30 +323,6 @@ static uint32_t calc_checksum(unsigned char* buf, uint32_t n)
323 return sum; 323 return sum;
324} 324}
325 325
326static int get_model(int model_id)
327{
328 switch(model_id) {
329 case 0x1e:
330 return MODEL_FUZE;
331 case 0x22:
332 return MODEL_CLIP;
333 case 0x23:
334 return MODEL_C200V2;
335 case 0x24:
336 return MODEL_E200V2;
337 case 0x25:
338 return MODEL_M200V4;
339 case 0x27:
340 return MODEL_CLIPV2;
341 case 0x28:
342 return MODEL_CLIPPLUS;
343 case 0x70:
344 return MODEL_FUZEV2;
345 }
346
347 return MODEL_UNKNOWN;
348}
349
350/* Compress using nrv2e algorithm : Thumb decompressor fits in 168 bytes ! */ 326/* Compress using nrv2e algorithm : Thumb decompressor fits in 168 bytes ! */
351static unsigned char* uclpack(unsigned char* inbuf, int insize, int* outsize) 327static unsigned char* uclpack(unsigned char* inbuf, int insize, int* outsize)
352{ 328{
@@ -388,7 +364,7 @@ static unsigned char* uclpack(unsigned char* inbuf, int insize, int* outsize)
388 364
389/* Loads a Sansa AMS Original Firmware file into memory */ 365/* Loads a Sansa AMS Original Firmware file into memory */
390unsigned char* load_of_file( 366unsigned char* load_of_file(
391 char* filename, off_t* bufsize, struct md5sums *sum, 367 char* filename, int model, off_t* bufsize, struct md5sums *sum,
392 int* firmware_size, unsigned char** of_packed, 368 int* firmware_size, unsigned char** of_packed,
393 int* of_packedsize, char* errstr, int errstrsize) 369 int* of_packedsize, char* errstr, int errstrsize)
394{ 370{
@@ -397,7 +373,6 @@ unsigned char* load_of_file(
397 off_t n; 373 off_t n;
398 unsigned int i=0; 374 unsigned int i=0;
399 uint32_t checksum; 375 uint32_t checksum;
400 int model_id;
401 unsigned int last_word; 376 unsigned int last_word;
402 377
403 fd = open(filename, O_RDONLY|O_BINARY); 378 fd = open(filename, O_RDONLY|O_BINARY);
@@ -425,21 +400,20 @@ unsigned char* load_of_file(
425 400
426 if (i < NUM_MD5S) { 401 if (i < NUM_MD5S) {
427 *sum = sansasums[i]; 402 *sum = sansasums[i];
403 if(sum->model != model) {
404 ERROR("[ERR] OF File provided is %sv%d version %s, not for %sv%d\n",
405 model_names[sum->model], hw_revisions[sum->model],
406 sum->version, model_names[model], hw_revisions[model]
407 );
408 }
428 } else { 409 } else {
429 int fw_version = (get_uint32le(&buf[0x204]) == 0x0000f000) ? 2 : 1; 410 /* OF unknown, give a list of tested versions for the requested model */
430 model_id = buf[(fw_version == 2) ? 0x219 : 0x215];
431 sum->model = get_model(model_id);
432
433 if (sum->model == MODEL_UNKNOWN)
434 ERROR("[ERR] Unknown firmware model (v%d) - model id 0x%02x\n",
435 fw_version, model_id);
436 411
437#if 1 /* comment to test new OFs */
438 char tested_versions[100]; 412 char tested_versions[100];
439 tested_versions[0] = '\0'; 413 tested_versions[0] = '\0';
440 414
441 for (i = 0; i < NUM_MD5S ; i++) 415 for (i = 0; i < NUM_MD5S ; i++)
442 if (sansasums[i].model == sum->model) { 416 if (sansasums[i].model == model) {
443 if (tested_versions[0] != '\0') { 417 if (tested_versions[0] != '\0') {
444 strncat(tested_versions, ", ", 418 strncat(tested_versions, ", ",
445 sizeof(tested_versions) - strlen(tested_versions) - 1); 419 sizeof(tested_versions) - strlen(tested_versions) - 1);
@@ -449,9 +423,8 @@ unsigned char* load_of_file(
449 } 423 }
450 424
451 ERROR("[ERR] Original firmware unknown, please try an other version." \ 425 ERROR("[ERR] Original firmware unknown, please try an other version." \
452 " Tested %s versions are : %s\n", 426 " Tested %sv%d versions are : %s\n",
453 model_names[sum->model], tested_versions); 427 model_names[model], hw_revisions[model], tested_versions);
454#endif
455 } 428 }
456 429
457 /* TODO: Do some more sanity checks on the OF image. Some images (like 430 /* TODO: Do some more sanity checks on the OF image. Some images (like
@@ -484,7 +457,7 @@ error:
484 457
485/* Loads a rockbox bootloader file into memory */ 458/* Loads a rockbox bootloader file into memory */
486unsigned char* load_rockbox_file( 459unsigned char* load_rockbox_file(
487 char* filename, int model, int* bufsize, int* rb_packedsize, 460 char* filename, int *model, int* bufsize, int* rb_packedsize,
488 char* errstr, int errstrsize) 461 char* errstr, int errstrsize)
489{ 462{
490 int fd; 463 int fd;
@@ -504,10 +477,12 @@ unsigned char* load_rockbox_file(
504 if (n != sizeof(header)) 477 if (n != sizeof(header))
505 ERROR("[ERR] Could not read file %s\n", filename); 478 ERROR("[ERR] Could not read file %s\n", filename);
506 479
507 /* Check for correct model string */ 480 for(*model = 0; *model < NUM_MODELS; (*model)++)
508 if (memcmp(rb_model_names[model], header + 4, 4)!=0) 481 if (memcmp(rb_model_names[*model], header + 4, 4) == 0)
509 ERROR("[ERR] Expected model name \"%s\" in %s, not \"%4.4s\"\n", 482 break;
510 rb_model_names[model], filename, (char*)header+4); 483
484 if(*model == NUM_MODELS)
485 ERROR("[ERR] Model name \"%4.4s\" unknown. Is this really a rockbox bootloader?\n", header + 4);
511 486
512 *bufsize = filesize(fd) - sizeof(header); 487 *bufsize = filesize(fd) - sizeof(header);
513 488
@@ -521,7 +496,7 @@ unsigned char* load_rockbox_file(
521 ERROR("[ERR] Could not read file %s\n", filename); 496 ERROR("[ERR] Could not read file %s\n", filename);
522 497
523 /* Check checksum */ 498 /* Check checksum */
524 sum = rb_model_num[model]; 499 sum = rb_model_num[*model];
525 for (i = 0; i < *bufsize; i++) { 500 for (i = 0; i < *bufsize; i++) {
526 /* add 8 unsigned bits but keep a 32 bit sum */ 501 /* add 8 unsigned bits but keep a 32 bit sum */
527 sum += buf[i]; 502 sum += buf[i];
diff --git a/rbutil/mkamsboot/mkamsboot.h b/rbutil/mkamsboot/mkamsboot.h
index 835d024d98..d87a5df4f7 100644
--- a/rbutil/mkamsboot/mkamsboot.h
+++ b/rbutil/mkamsboot/mkamsboot.h
@@ -43,6 +43,9 @@ enum {
43 MODEL_C200V2, 43 MODEL_C200V2,
44 MODEL_CLIPPLUS, 44 MODEL_CLIPPLUS,
45 MODEL_FUZEV2, 45 MODEL_FUZEV2,
46 /* new models go here */
47
48 NUM_MODELS
46}; 49};
47 50
48 51
@@ -65,8 +68,7 @@ extern const int bootloader_sizes[];
65 * ARGUMENTS 68 * ARGUMENTS
66 * 69 *
67 * filename : bootloader file to load 70 * filename : bootloader file to load
68 * model : a 4 characters string representing the Sansa model 71 * model : will be set to this bootloader's model
69 * ("fuze", "clip", "e2v2", "m2v4", or "c2v2")
70 * bootloader_size : set to the uncompressed bootloader size 72 * bootloader_size : set to the uncompressed bootloader size
71 * rb_packed_size : set to the size of compressed bootloader 73 * rb_packed_size : set to the size of compressed bootloader
72 * errstr : provided buffer to store an eventual error 74 * errstr : provided buffer to store an eventual error
@@ -78,7 +80,7 @@ extern const int bootloader_sizes[];
78 */ 80 */
79 81
80unsigned char* load_rockbox_file( 82unsigned char* load_rockbox_file(
81 char* filename, int model, int* bootloader_size, int* rb_packedsize, 83 char* filename, int *model, int* bootloader_size, int* rb_packedsize,
82 char* errstr, int errstrsize); 84 char* errstr, int errstrsize);
83 85
84 86
@@ -89,10 +91,9 @@ unsigned char* load_rockbox_file(
89 * ARGUMENTS 91 * ARGUMENTS
90 * 92 *
91 * filename : firmware file to load 93 * filename : firmware file to load
94 * model : desired player's model
92 * bufsize : set to firmware file size 95 * bufsize : set to firmware file size
93 * md5sum : set to file md5sum, must be at least 33 bytes long 96 * md5sum : set to file md5sum, must be at least 33 bytes long
94 * model : set to firmware model (MODEL_XXX)
95 * fw_version : set to firmware format version (1 or 2)
96 * firmware_size : set to firmware block's size 97 * firmware_size : set to firmware block's size
97 * of_packed : pointer to allocated memory containing the compressed 98 * of_packed : pointer to allocated memory containing the compressed
98 * original firmware block 99 * original firmware block
@@ -106,7 +107,7 @@ unsigned char* load_rockbox_file(
106 */ 107 */
107 108
108unsigned char* load_of_file( 109unsigned char* load_of_file(
109 char* filename, off_t* bufsize, struct md5sums *sum, 110 char* filename, int model, off_t* bufsize, struct md5sums *sum,
110 int* firmware_size, unsigned char** of_packed, 111 int* firmware_size, unsigned char** of_packed,
111 int* of_packedsize, char* errstr, int errstrsize); 112 int* of_packedsize, char* errstr, int errstrsize);
112 113
diff --git a/rbutil/rbutilqt/base/bootloaderinstallams.cpp b/rbutil/rbutilqt/base/bootloaderinstallams.cpp
index b1f47eda93..3bdd084c60 100644
--- a/rbutil/rbutilqt/base/bootloaderinstallams.cpp
+++ b/rbutil/rbutilqt/base/bootloaderinstallams.cpp
@@ -72,6 +72,7 @@ void BootloaderInstallAms::installStage2(void)
72 struct md5sums sum; 72 struct md5sums sum;
73 char md5sum[33]; /* 32 hex digits, plus terminating zero */ 73 char md5sum[33]; /* 32 hex digits, plus terminating zero */
74 int n; 74 int n;
75 int model;
75 int firmware_size; 76 int firmware_size;
76 int bootloader_size; 77 int bootloader_size;
77 int patchable; 78 int patchable;
@@ -84,33 +85,33 @@ void BootloaderInstallAms::installStage2(void)
84 QString bootfile = m_tempfile.fileName(); 85 QString bootfile = m_tempfile.fileName();
85 m_tempfile.close(); 86 m_tempfile.close();
86 87
87 /* Load original firmware file */
88 buf = load_of_file(m_offile.toLocal8Bit().data(), &len,&sum,&firmware_size,
89 &of_packed,&of_packedsize,errstr,sizeof(errstr));
90 if (buf == NULL)
91 {
92 qDebug() << "[BootloaderInstallAms] could not load OF: " << m_offile;
93 emit logItem(errstr, LOGERROR);
94 emit logItem(tr("Could not load %1").arg(m_offile), LOGERROR);
95 emit done(true);
96 return;
97 }
98
99 /* Load bootloader file */ 88 /* Load bootloader file */
100 rb_packed = load_rockbox_file(bootfile.toLocal8Bit().data(), sum.model, 89 rb_packed = load_rockbox_file(bootfile.toLocal8Bit().data(), &model,
101 &bootloader_size,&rb_packedsize, 90 &bootloader_size,&rb_packedsize,
102 errstr,sizeof(errstr)); 91 errstr,sizeof(errstr));
103 if (rb_packed == NULL) 92 if (rb_packed == NULL)
104 { 93 {
105 qDebug() << "[BootloaderInstallAms] could not load bootloader: " << bootfile; 94 qDebug() << "[BootloaderInstallAms] could not load bootloader: " << bootfile;
106 emit logItem(errstr, LOGERROR); 95 emit logItem(errstr, LOGERROR);
107 emit logItem(tr("Could not load %1").arg(bootfile), LOGERROR); 96 emit logItem(tr("Could not load %1").arg(bootfile), LOGERROR);
108 free(buf);
109 free(of_packed);
110 emit done(true); 97 emit done(true);
111 return; 98 return;
112 } 99 }
113 100
101 /* Load original firmware file */
102 buf = load_of_file(m_offile.toLocal8Bit().data(), model, &len, &sum,
103 &firmware_size, &of_packed ,&of_packedsize,
104 errstr, sizeof(errstr));
105 if (buf == NULL)
106 {
107 qDebug() << "[BootloaderInstallAms] could not load OF: " << m_offile;
108 emit logItem(errstr, LOGERROR);
109 emit logItem(tr("Could not load %1").arg(m_offile), LOGERROR);
110 free(rb_packed);
111 emit done(true);
112 return;
113 }
114
114 /* check total size */ 115 /* check total size */
115 patchable = check_sizes(sum.model, rb_packedsize, bootloader_size, 116 patchable = check_sizes(sum.model, rb_packedsize, bootloader_size,
116 of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr)); 117 of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr));
diff --git a/utils/AMS/hacking/amsinfo.c b/utils/AMS/hacking/amsinfo.c
index ff92175e64..433333ecca 100644
--- a/utils/AMS/hacking/amsinfo.c
+++ b/utils/AMS/hacking/amsinfo.c
@@ -66,7 +66,7 @@ uint8_t *buf; /* file content */
66 66
67/* 1st block description */ 67/* 1st block description */
68uint32_t idx,checksum,bs_multiplier,firmware_sz; 68uint32_t idx,checksum,bs_multiplier,firmware_sz;
69uint32_t unknown_4_1; uint8_t unknown_1,id; uint16_t unknown_2; 69uint32_t unknown_4_1; uint16_t unknown_1, unknown_2;
70uint32_t unknown_4_2,unknown_4_3; 70uint32_t unknown_4_2,unknown_4_3;
71 71
72static void *xmalloc(size_t s) /* malloc helper */ 72static void *xmalloc(size_t s) /* malloc helper */
@@ -76,28 +76,6 @@ static void *xmalloc(size_t s) /* malloc helper */
76 return r; 76 return r;
77} 77}
78 78
79/* known models */
80static const char * model(uint8_t id)
81{
82 switch(id)
83 {
84 case 0x1E: return "FUZE"; break;
85 case 0x22: return "CLIP"; break;
86 case 0x23: return "C200"; break;
87 case 0x24: return "E200"; break;
88 case 0x25: return "M200"; break;
89 case 0x27: return "CLV2"; break;
90 case 0x28: return "CLI+"; break;
91 case 0x70:
92 case 0x6d: return "FUZ2"; break;
93 default:
94 printf("Unknown ID 0x%x\n", id);
95
96 assert(id == 0x1E || (id >= 0x22 && id <= 0x28));
97 return "UNKNOWN!";
98 }
99}
100
101/* checksums the firmware (the firmware header contains the verification) */ 79/* checksums the firmware (the firmware header contains the verification) */
102static uint32_t do_checksum(void) 80static uint32_t do_checksum(void)
103{ 81{
@@ -142,8 +120,7 @@ static void check(void)
142 assert(bs_multiplier << 9 == PAD_TO_BOUNDARY(firmware_sz)); /* 0x200 * bs_multiplier */ 120 assert(bs_multiplier << 9 == PAD_TO_BOUNDARY(firmware_sz)); /* 0x200 * bs_multiplier */
143 121
144 unknown_4_1 = get32le(0x10 + shift); 122 unknown_4_1 = get32le(0x10 + shift);
145 unknown_1 = buf[0x14 + shift]; 123 unknown_1 = get16le(0x14 + shift);
146 id = buf[0x15 + shift];
147 unknown_2 = get16le(0x16 + shift); 124 unknown_2 = get16le(0x16 + shift);
148 unknown_4_2 = get32le(0x18 + shift); 125 unknown_4_2 = get32le(0x18 + shift);
149 unknown_4_3 = get32le(0x1c + shift); 126 unknown_4_3 = get32le(0x1c + shift);
@@ -171,9 +148,6 @@ static void check(void)
171 printf("1 Unknown %x\n",unknown_1); 148 printf("1 Unknown %x\n",unknown_1);
172 149
173 color(GREEN); 150 color(GREEN);
174 printf("1 Model ID %x (%s)\n",id,model(id));
175
176 color(GREEN);
177 printf("2 Unknown (should be 0) %x\n",unknown_2); 151 printf("2 Unknown (should be 0) %x\n",unknown_2);
178 assert(unknown_2 == 0); 152 assert(unknown_2 == 0);
179 153
@@ -185,13 +159,6 @@ static void check(void)
185 printf("4 Unknown (should be 1) %x\n",unknown_4_3); 159 printf("4 Unknown (should be 1) %x\n",unknown_4_3);
186 assert(unknown_4_3 == 1); 160 assert(unknown_4_3 == 1);
187 161
188 /* rest of the block is padded with 0xff */
189 for(i=0x20 + shift;i<0x200 - shift;i++)
190 assert(buf[i]==0xff /* normal case */ ||
191 ((id==0x1e||id==0x24) && ( /* Fuze or E200 */
192 (i>=0x3c && i<=0x3f && get32le(0x3c)==0x00005000)
193 )));
194
195 /* the 2nd block is identical, except that the 1st byte has been incremented */ 162 /* the 2nd block is identical, except that the 1st byte has been incremented */
196 assert(buf[0x0]==0&&buf[0x200]==1); 163 assert(buf[0x0]==0&&buf[0x200]==1);
197 assert(!memcmp(&buf[1],&buf[0x201],0x1FF - shift)); 164 assert(!memcmp(&buf[1],&buf[0x201],0x1FF - shift));