diff options
Diffstat (limited to 'tools/scramble.c')
-rw-r--r-- | tools/scramble.c | 111 |
1 files changed, 15 insertions, 96 deletions
diff --git a/tools/scramble.c b/tools/scramble.c index b49bde10a2..91f46be816 100644 --- a/tools/scramble.c +++ b/tools/scramble.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "gigabeats.h" | 26 | #include "gigabeats.h" |
27 | #include "mi4.h" | 27 | #include "mi4.h" |
28 | #include "telechips.h" | 28 | #include "telechips.h" |
29 | #include "creative.h" | ||
29 | #include "iaudio_bl_flash.h" | 30 | #include "iaudio_bl_flash.h" |
30 | 31 | ||
31 | int iaudio_encode(char *iname, char *oname, char *idstring); | 32 | int iaudio_encode(char *iname, char *oname, char *idstring); |
@@ -102,7 +103,7 @@ void usage(void) | |||
102 | "\t-ipod3g ipod firmware partition format (3rd Gen)\n" | 103 | "\t-ipod3g ipod firmware partition format (3rd Gen)\n" |
103 | "\t-ipod4g ipod firmware partition format (4th Gen, Mini, Nano, Photo/Color)\n" | 104 | "\t-ipod4g ipod firmware partition format (4th Gen, Mini, Nano, Photo/Color)\n" |
104 | "\t-ipod5g ipod firmware partition format (5th Gen - aka Video)\n" | 105 | "\t-ipod5g ipod firmware partition format (5th Gen - aka Video)\n" |
105 | "\t-zvm Zen Vision:M FRESCUE structure format\n" | 106 | "\t-creative=X Creative firmware structure format\n" |
106 | "\t-gigabeat Toshiba Gigabeat F/X format\n" | 107 | "\t-gigabeat Toshiba Gigabeat F/X format\n" |
107 | "\t-gigabeats Toshiba Gigabeat S format\n" | 108 | "\t-gigabeats Toshiba Gigabeat S format\n" |
108 | "\t-mi4v2 PortalPlayer .mi4 format (revision 010201)\n" | 109 | "\t-mi4v2 PortalPlayer .mi4 format (revision 010201)\n" |
@@ -332,10 +333,21 @@ int main (int argc, char** argv) | |||
332 | oname = argv[3]; | 333 | oname = argv[3]; |
333 | return ipod_encode(iname, oname, 3, true); /* Firmware image v3 */ | 334 | return ipod_encode(iname, oname, 3, true); /* Firmware image v3 */ |
334 | } | 335 | } |
335 | else if(!strcmp(argv[1], "-zvm")) { | 336 | else if(!strncmp(argv[1], "-creative=", 10)) { |
336 | iname = argv[2]; | 337 | iname = argv[2]; |
337 | oname = argv[3]; | 338 | oname = argv[3]; |
338 | return zvm_encode(iname, oname); | 339 | if(!strcmp(&argv[1][10], "zvm")) |
340 | return zvm_encode(iname, oname, ZENVISIONM); | ||
341 | else if(!strcmp(&argv[1][10], "zvm60")) | ||
342 | return zvm_encode(iname, oname, ZENVISIONM60); | ||
343 | else if(!strcmp(&argv[1][10], "zenvision")) | ||
344 | return zvm_encode(iname, oname, ZENVISION); | ||
345 | else if(!strcmp(&argv[1][10], "zenv")) | ||
346 | return zvm_encode(iname, oname, ZENV); | ||
347 | else { | ||
348 | fprintf(stderr, "unsupported Creative device: %s\n", &argv[1][10]); | ||
349 | return 2; | ||
350 | } | ||
339 | } | 351 | } |
340 | else if(!strncmp(argv[1], "-mi4", 4)) { | 352 | else if(!strncmp(argv[1], "-mi4", 4)) { |
341 | int mi4magic; | 353 | int mi4magic; |
@@ -752,96 +764,3 @@ int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc) | |||
752 | return 0; | 764 | return 0; |
753 | } | 765 | } |
754 | 766 | ||
755 | |||
756 | /* Create an Zen Vision:M FRESCUE structure file | ||
757 | */ | ||
758 | |||
759 | int zvm_encode(char *iname, char *oname) | ||
760 | { | ||
761 | size_t len; | ||
762 | int length; | ||
763 | FILE *file; | ||
764 | unsigned int sum = 0; | ||
765 | unsigned char *outbuf; | ||
766 | int i; | ||
767 | |||
768 | file = fopen(iname, "rb"); | ||
769 | if (!file) { | ||
770 | perror(iname); | ||
771 | return -1; | ||
772 | } | ||
773 | fseek(file,0,SEEK_END); | ||
774 | length = ftell(file); | ||
775 | |||
776 | fseek(file,0,SEEK_SET); | ||
777 | |||
778 | outbuf = malloc(length+0x18+0x10); | ||
779 | |||
780 | if ( !outbuf ) { | ||
781 | printf("out of memory!\n"); | ||
782 | return -1; | ||
783 | } | ||
784 | |||
785 | len = fread(outbuf+0x18, 1, length, file); | ||
786 | if(len < length) { | ||
787 | perror(iname); | ||
788 | return -2; | ||
789 | } | ||
790 | fclose(file); | ||
791 | |||
792 | /* Calculate checksum for later use in header */ | ||
793 | for(i=0; i<length; i+= 4) | ||
794 | sum += le2int(&outbuf[0x18+i]) + (le2int(&outbuf[0x18+i])>>16); | ||
795 | |||
796 | /* Clear the header area to zero */ | ||
797 | memset(outbuf, 0, 0x18); | ||
798 | |||
799 | /* Header (EDOC) */ | ||
800 | memcpy((char*)outbuf, "EDOC", 4); | ||
801 | /* Total Size */ | ||
802 | int2le(length+0x20, &outbuf[0x4]); | ||
803 | /* 4 bytes of zero */ | ||
804 | |||
805 | /* Address = 0x900000 */ | ||
806 | int2le(0x900000, &outbuf[0xC]); | ||
807 | /* Size */ | ||
808 | int2le(length, &outbuf[0x10]); | ||
809 | /* Checksum */ | ||
810 | int2le(sum, &outbuf[0x14]); | ||
811 | outbuf[0x16] = 0; | ||
812 | outbuf[0x17] = 0; | ||
813 | /* Data starts here... */ | ||
814 | |||
815 | /* Second block starts here ... */ | ||
816 | /* Address = 0x0 */ | ||
817 | /* Size */ | ||
818 | int2le(0x4, &outbuf[0x18+length+0x4]); | ||
819 | /* Checksum */ | ||
820 | outbuf[0x18+length+0x8] = 0xB7; | ||
821 | outbuf[0x18+length+0x9] = 0xD5; | ||
822 | /* Data: LDR PC, =0x900000 */ | ||
823 | outbuf[0x18+length+0xC] = 0x18; | ||
824 | outbuf[0x18+length+0xD] = 0xF0; | ||
825 | outbuf[0x18+length+0xE] = 0x9F; | ||
826 | outbuf[0x18+length+0xF] = 0xE5; | ||
827 | |||
828 | |||
829 | file = fopen(oname, "wb"); | ||
830 | if (!file) { | ||
831 | perror(oname); | ||
832 | return -3; | ||
833 | } | ||
834 | |||
835 | len = fwrite(outbuf, 1, length+0x28, file); | ||
836 | if(len < length+0x18) { | ||
837 | perror(oname); | ||
838 | return -4; | ||
839 | } | ||
840 | |||
841 | free(outbuf); | ||
842 | |||
843 | fclose(file); | ||
844 | |||
845 | return 0; | ||
846 | } | ||
847 | |||