Make sure files which aren't windows-specific use \n line endings only
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26893 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3d2b1cfa6e
commit
c0bd4173aa
23 changed files with 14110 additions and 14110 deletions
|
@ -1,226 +1,226 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id:
|
||||
*
|
||||
* Copyright (C) 2009 by Andree Buschmann
|
||||
*
|
||||
* 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"
|
||||
|
||||
.section .text, "ax", %progbits
|
||||
|
||||
/****************************************************************************
|
||||
* void atrac3_iqmf_matrixing(int32_t *dest,
|
||||
* int32_t *inlo,
|
||||
* int32_t *inhi,
|
||||
* unsigned int count);
|
||||
*
|
||||
* Matrixing step within iqmf of atrac3 synthesis. Reference implementation:
|
||||
*
|
||||
* for(i=0; i<counter; i+=2){
|
||||
* dest[2*i+0] = inlo[i ] + inhi[i ];
|
||||
* dest[2*i+1] = inlo[i ] - inhi[i ];
|
||||
* dest[2*i+2] = inlo[i+1] + inhi[i+1];
|
||||
* dest[2*i+3] = inlo[i+1] - inhi[i+1];
|
||||
* }
|
||||
* Note: r12 is a scratch register and can be used without restorage.
|
||||
****************************************************************************/
|
||||
.align 2
|
||||
.global atrac3_iqmf_matrixing
|
||||
.type atrac3_iqmf_matrixing, %function
|
||||
|
||||
atrac3_iqmf_matrixing:
|
||||
/* r0 = dest */
|
||||
/* r1 = inlo */
|
||||
/* r2 = inhi */
|
||||
/* r3 = counter */
|
||||
stmfd sp!, {r4-r9, lr} /* save non-scratch registers */
|
||||
|
||||
.iqmf_matrixing_loop:
|
||||
ldmia r1!, { r4, r6, r8, r12} /* load inlo[0...3] */
|
||||
ldmia r2!, { r5, r7, r9, lr } /* load inhi[0...3] */
|
||||
add r4, r4, r5 /* r4 = inlo[0] + inhi[0] */
|
||||
sub r5, r4, r5, asl #1 /* r5 = inlo[0] - inhi[0] */
|
||||
add r6, r6, r7 /* r6 = inlo[1] + inhi[1] */
|
||||
sub r7, r6, r7, asl #1 /* r7 = inlo[1] - inhi[1] */
|
||||
add r8, r8, r9 /* r8 = inlo[2] + inhi[2] */
|
||||
sub r9, r8, r9, asl #1 /* r9 = inlo[2] - inhi[2] */
|
||||
add r12, r12, lr /* r12 = inlo[3] + inhi[3] */
|
||||
sub lr , r12, lr, asl #1 /* lr = inlo[3] - inhi[3] */
|
||||
stmia r0!, {r4-r9, r12, lr} /* store results to dest */
|
||||
subs r3, r3, #4 /* counter -= 4 */
|
||||
bgt .iqmf_matrixing_loop
|
||||
|
||||
ldmpc regs=r4-r9 /* restore registers */
|
||||
|
||||
.atrac3_iqmf_matrixing_end:
|
||||
.size atrac3_iqmf_matrixing,.atrac3_iqmf_matrixing_end-atrac3_iqmf_matrixing
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* atrac3_iqmf_dewindowing(int32_t *out,
|
||||
* int32_t *in,
|
||||
* int32_t *win,
|
||||
* unsigned int nIn);
|
||||
*
|
||||
* Dewindowing step within iqmf of atrac3 synthesis. Reference implementation:
|
||||
*
|
||||
* for (j = nIn; j != 0; j--) {
|
||||
* s1 = fixmul32(in[0], win[0]);
|
||||
* s2 = fixmul32(in[1], win[1]);
|
||||
* for (i = 2; i < 48; i += 2) {
|
||||
* s1 += fixmul32(in[i ], win[i ]);
|
||||
* s2 += fixmul32(in[i+1], win[i+1]);
|
||||
* }
|
||||
* out[0] = s2 << 1;
|
||||
* out[1] = s1 << 1;
|
||||
* in += 2;
|
||||
* out += 2;
|
||||
* }
|
||||
* Note: r12 is a scratch register and can be used without restorage.
|
||||
****************************************************************************/
|
||||
.align 2
|
||||
.global atrac3_iqmf_dewindowing
|
||||
.type atrac3_iqmf_dewindowing, %function
|
||||
|
||||
atrac3_iqmf_dewindowing:
|
||||
/* r0 = dest */
|
||||
/* r1 = input samples */
|
||||
/* r2 = window coefficients */
|
||||
/* r3 = counter */
|
||||
stmfd sp!, {r4-r9, lr} /* save non-scratch registers */
|
||||
|
||||
.iqmf_dewindow_outer_loop: /* outer loop 0...counter-1 */
|
||||
/* 0.. 7 */
|
||||
ldmia r2!, {r4, r5} /* load win[0..1] */
|
||||
ldmia r1!, {r6, r7} /* load in[0..1] */
|
||||
smull lr , r9, r4, r6 /* s1 = win[0] * in[0] */
|
||||
smull r12, r8, r5, r7 /* s2 = win[1] * in[1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 8..15 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 16..23 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 24..31 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 32..39 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 40..47 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
|
||||
mov lr , lr , lsr #31
|
||||
orr r9, lr , r9, lsl #1 /* s1 = low>>31 || hi<<1 */
|
||||
mov r12, r12, lsr #31
|
||||
orr r8, r12, r8, lsl #1 /* s2 = low>>31 || hi<<1 */
|
||||
|
||||
stmia r0!, {r8, r9} /* store result out[0]=s2, out[1]=s1 */
|
||||
sub r1, r1, #184 /* roll back 64 entries = 184 bytes */
|
||||
sub r2, r2, #192 /* roll back 48 entries = 192 bytes = win[0] */
|
||||
|
||||
subs r3, r3, #1 /* outer loop -= 1 */
|
||||
bgt .iqmf_dewindow_outer_loop
|
||||
|
||||
ldmpc regs=r4-r9 /* restore registers */
|
||||
|
||||
.atrac3_iqmf_dewindowing_end:
|
||||
.size atrac3_iqmf_dewindowing,.atrac3_iqmf_dewindowing_end-atrac3_iqmf_dewindowing
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id:
|
||||
*
|
||||
* Copyright (C) 2009 by Andree Buschmann
|
||||
*
|
||||
* 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"
|
||||
|
||||
.section .text, "ax", %progbits
|
||||
|
||||
/****************************************************************************
|
||||
* void atrac3_iqmf_matrixing(int32_t *dest,
|
||||
* int32_t *inlo,
|
||||
* int32_t *inhi,
|
||||
* unsigned int count);
|
||||
*
|
||||
* Matrixing step within iqmf of atrac3 synthesis. Reference implementation:
|
||||
*
|
||||
* for(i=0; i<counter; i+=2){
|
||||
* dest[2*i+0] = inlo[i ] + inhi[i ];
|
||||
* dest[2*i+1] = inlo[i ] - inhi[i ];
|
||||
* dest[2*i+2] = inlo[i+1] + inhi[i+1];
|
||||
* dest[2*i+3] = inlo[i+1] - inhi[i+1];
|
||||
* }
|
||||
* Note: r12 is a scratch register and can be used without restorage.
|
||||
****************************************************************************/
|
||||
.align 2
|
||||
.global atrac3_iqmf_matrixing
|
||||
.type atrac3_iqmf_matrixing, %function
|
||||
|
||||
atrac3_iqmf_matrixing:
|
||||
/* r0 = dest */
|
||||
/* r1 = inlo */
|
||||
/* r2 = inhi */
|
||||
/* r3 = counter */
|
||||
stmfd sp!, {r4-r9, lr} /* save non-scratch registers */
|
||||
|
||||
.iqmf_matrixing_loop:
|
||||
ldmia r1!, { r4, r6, r8, r12} /* load inlo[0...3] */
|
||||
ldmia r2!, { r5, r7, r9, lr } /* load inhi[0...3] */
|
||||
add r4, r4, r5 /* r4 = inlo[0] + inhi[0] */
|
||||
sub r5, r4, r5, asl #1 /* r5 = inlo[0] - inhi[0] */
|
||||
add r6, r6, r7 /* r6 = inlo[1] + inhi[1] */
|
||||
sub r7, r6, r7, asl #1 /* r7 = inlo[1] - inhi[1] */
|
||||
add r8, r8, r9 /* r8 = inlo[2] + inhi[2] */
|
||||
sub r9, r8, r9, asl #1 /* r9 = inlo[2] - inhi[2] */
|
||||
add r12, r12, lr /* r12 = inlo[3] + inhi[3] */
|
||||
sub lr , r12, lr, asl #1 /* lr = inlo[3] - inhi[3] */
|
||||
stmia r0!, {r4-r9, r12, lr} /* store results to dest */
|
||||
subs r3, r3, #4 /* counter -= 4 */
|
||||
bgt .iqmf_matrixing_loop
|
||||
|
||||
ldmpc regs=r4-r9 /* restore registers */
|
||||
|
||||
.atrac3_iqmf_matrixing_end:
|
||||
.size atrac3_iqmf_matrixing,.atrac3_iqmf_matrixing_end-atrac3_iqmf_matrixing
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* atrac3_iqmf_dewindowing(int32_t *out,
|
||||
* int32_t *in,
|
||||
* int32_t *win,
|
||||
* unsigned int nIn);
|
||||
*
|
||||
* Dewindowing step within iqmf of atrac3 synthesis. Reference implementation:
|
||||
*
|
||||
* for (j = nIn; j != 0; j--) {
|
||||
* s1 = fixmul32(in[0], win[0]);
|
||||
* s2 = fixmul32(in[1], win[1]);
|
||||
* for (i = 2; i < 48; i += 2) {
|
||||
* s1 += fixmul32(in[i ], win[i ]);
|
||||
* s2 += fixmul32(in[i+1], win[i+1]);
|
||||
* }
|
||||
* out[0] = s2 << 1;
|
||||
* out[1] = s1 << 1;
|
||||
* in += 2;
|
||||
* out += 2;
|
||||
* }
|
||||
* Note: r12 is a scratch register and can be used without restorage.
|
||||
****************************************************************************/
|
||||
.align 2
|
||||
.global atrac3_iqmf_dewindowing
|
||||
.type atrac3_iqmf_dewindowing, %function
|
||||
|
||||
atrac3_iqmf_dewindowing:
|
||||
/* r0 = dest */
|
||||
/* r1 = input samples */
|
||||
/* r2 = window coefficients */
|
||||
/* r3 = counter */
|
||||
stmfd sp!, {r4-r9, lr} /* save non-scratch registers */
|
||||
|
||||
.iqmf_dewindow_outer_loop: /* outer loop 0...counter-1 */
|
||||
/* 0.. 7 */
|
||||
ldmia r2!, {r4, r5} /* load win[0..1] */
|
||||
ldmia r1!, {r6, r7} /* load in[0..1] */
|
||||
smull lr , r9, r4, r6 /* s1 = win[0] * in[0] */
|
||||
smull r12, r8, r5, r7 /* s2 = win[1] * in[1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 8..15 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 16..23 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 24..31 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 32..39 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
/* 40..47 */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
ldmia r2!, {r4, r5} /* load win[i...i+1] */
|
||||
ldmia r1!, {r6, r7} /* load in[i...i+1] */
|
||||
smlal lr , r9, r4, r6 /* s1 = win[i ] * in[i ] */
|
||||
smlal r12, r8, r5, r7 /* s2 = win[i+1] * in[i+1] */
|
||||
|
||||
mov lr , lr , lsr #31
|
||||
orr r9, lr , r9, lsl #1 /* s1 = low>>31 || hi<<1 */
|
||||
mov r12, r12, lsr #31
|
||||
orr r8, r12, r8, lsl #1 /* s2 = low>>31 || hi<<1 */
|
||||
|
||||
stmia r0!, {r8, r9} /* store result out[0]=s2, out[1]=s1 */
|
||||
sub r1, r1, #184 /* roll back 64 entries = 184 bytes */
|
||||
sub r2, r2, #192 /* roll back 48 entries = 192 bytes = win[0] */
|
||||
|
||||
subs r3, r3, #1 /* outer loop -= 1 */
|
||||
bgt .iqmf_dewindow_outer_loop
|
||||
|
||||
ldmpc regs=r4-r9 /* restore registers */
|
||||
|
||||
.atrac3_iqmf_dewindowing_end:
|
||||
.size atrac3_iqmf_dewindowing,.atrac3_iqmf_dewindowing_end-atrac3_iqmf_dewindowing
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
Original Copyright
|
||||
FILE........: AK2LSPD.H
|
||||
TYPE........: Turbo C header file
|
||||
COMPANY.....: Voicetronix
|
||||
AUTHOR......: James Whitehall
|
||||
DATE CREATED: 21/11/95
|
||||
|
||||
Modified by Jean-Marc Valin
|
||||
|
||||
This file contains functions for converting Linear Prediction
|
||||
Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
|
||||
LSP coefficients are not in radians format but in the x domain of the
|
||||
unit circle.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file lsp.h
|
||||
@brief Line Spectral Pair (LSP) functions.
|
||||
*/
|
||||
/* Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __AK2LSPD__
|
||||
#define __AK2LSPD__
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);
|
||||
void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
|
||||
|
||||
/*Added by JMV*/
|
||||
void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin);
|
||||
|
||||
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes);
|
||||
|
||||
#endif /* __AK2LSPD__ */
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Original Copyright
|
||||
FILE........: AK2LSPD.H
|
||||
TYPE........: Turbo C header file
|
||||
COMPANY.....: Voicetronix
|
||||
AUTHOR......: James Whitehall
|
||||
DATE CREATED: 21/11/95
|
||||
|
||||
Modified by Jean-Marc Valin
|
||||
|
||||
This file contains functions for converting Linear Prediction
|
||||
Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
|
||||
LSP coefficients are not in radians format but in the x domain of the
|
||||
unit circle.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file lsp.h
|
||||
@brief Line Spectral Pair (LSP) functions.
|
||||
*/
|
||||
/* Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __AK2LSPD__
|
||||
#define __AK2LSPD__
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);
|
||||
void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
|
||||
|
||||
/*Added by JMV*/
|
||||
void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin);
|
||||
|
||||
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes);
|
||||
|
||||
#endif /* __AK2LSPD__ */
|
||||
|
|
22782
apps/lang/ukrainian.lang
22782
apps/lang/ukrainian.lang
File diff suppressed because it is too large
Load diff
|
@ -1,174 +1,174 @@
|
|||
##########################################################################
|
||||
# IMPORTANT NOTE #
|
||||
# #
|
||||
# This is the readme file of the ProFont distribution for #
|
||||
# Apple Macintosh. I've added it because it felt wrong to distribute #
|
||||
# a Windows version of ProFont without the words of the original #
|
||||
# authors. #
|
||||
# !! Please note that some of the information provided below is #
|
||||
# NOT valid for ProFont/Windows !! Just figure it out ... ;-) #
|
||||
# The Windows version was created using the files from the #
|
||||
# “ProFontWindows 2.2 ƒ” folder mentioned below. #
|
||||
# #
|
||||
# Comparing Mac + Win version, you'll see that all font sizes are #
|
||||
# off by 1. This means that Win 8pt version displays like Mac 9pt #
|
||||
# version. #
|
||||
# #
|
||||
# For questions about the windows version of ProFont, contact: #
|
||||
# mail@tobias-jung.de (please write in english or german language) #
|
||||
# Tobias Jung, August 2002 #
|
||||
##########################################################################
|
||||
# For version information, #
|
||||
# PLEASE READ v1_vs_v2.txt ! #
|
||||
##########################################################################
|
||||
|
||||
ProFont Distribution 2.2
|
||||
21 July 1997
|
||||
SQ Software
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
• What is ProFont?
|
||||
|
||||
ProFont began life as a better version of “Monaco 9” which is especially good for programmers. It was created circa 1987 by Andrew Welch.
|
||||
|
||||
In version 1.1 of the ProFont distribution, ProFont ceased being just a 9 point bitmap font. Carl Osterwald contributed bitmaps at several larger sizes and an outline version of ProFont in both TrueType and Adobe Type 1 (ATM) formats.
|
||||
|
||||
In version 1.2 of the ProFont distribution, Carl extended ProFont to include the entire Macintosh character set including accented characters with ASCII codes from 0x80 to 0xFF.
|
||||
|
||||
In version 2.0 of the ProFont distribution, Carl provided an ISOLatin1 encoded version of ProFont. The shapes of several of the characters have been modified for improved readability, and a 7 pt bitmap version of ProFont is included.
|
||||
|
||||
In version 2.2 of the ProFont distribution, Carl produced a version of ProFont that uses the Windows character set. Once again the shapes of several of the characters have been modified for improved readability--especially when the fonts are anti-aliased.
|
||||
|
||||
• What is the ProFont Distribution?
|
||||
|
||||
ProFont was originally released as shareware by Andrew Welch. At that time, it was distributed inside an installer application which could replace Apple’s Monaco 9 with ProFont 9. This made using ProFont as a substitute for Monaco 9 very easy. When the Mac II and SE came out, the magic used by the original installer became ineffective. Over the years I (Steve Gilardi) have figured out how to install ProFont 9 in place of Monaco 9 through the various releases of the System Software. After a time I asked Andrew for permission to distribute ProFont along with my instructions and he agreed and also decided to change ProFont’s status from shareware to freeware.
|
||||
|
||||
The methods for accomplishing the substitution for Monaco 9 have gone through significant changes over the years as the Macintosh font architecture has evolved. The various releases of what has become the “ProFont Distribution” have been my effort to share my knowledge of how to use ProFont as a replacement for Monaco 9.
|
||||
|
||||
Since Carl Osterwald became involved with the project, ProFont has blossomed into a full-fledged font in its own right and most recently into a suite of related fonts. ProFont is unusual among fonts in that the outline version was designed to closely follow the original 9 pt bitmap version. More often, fonts are conceived as outlines and then rendered at the various point sizes.
|
||||
|
||||
Earlier versions of the ProFont Distribution have included very involved instructions and utility programs to allow installation of ProFont as a replacement for Monaco 9. Release 2.2 contains none of those instructions. Instead, I have developed a control panel called “Monaco Tuner” which allows you to substitute a font of your choosing for Monaco. The substitution can be just for Monaco 9 or for all sizes of Monaco. Of course, I think the best substitute font to use is ProFont! See the information in the “Monaco Tuner 1.1.1 ƒ” folder for details.
|
||||
|
||||
• What does ProFont 2.2 look like?
|
||||
|
||||
Here’s a sample:
|
||||
[ see "provsmonaco.gif" and "profomac.gif" ]
|
||||
|
||||
|
||||
Also, each font folder in the ProFont distribution contains a file showing the font’s character set at 9 and 18 point sizes. You don’t need to install the corresponding font to see the character set.
|
||||
|
||||
• What is included in this distribution?
|
||||
|
||||
The distribution includes 7 items:
|
||||
|
||||
+ “About ProFont Distribution 2.2” SimpleText document
|
||||
This is the file you are reading now.
|
||||
|
||||
+ “ProFont Quick Start” SimpleText document
|
||||
Quick instructions for installing ProFont and Monaco Tuner.
|
||||
|
||||
+ “ProFont 2.2 ƒ” folder
|
||||
Version 2.2 of the “ProFont” font. This includes both TrueType and ATM versions of ProFont.
|
||||
|
||||
+ “ProFontISOLatin1 2.2 ƒ” folder
|
||||
Version 2.2 of the “ProFontISOLatin1” font. TrueType and ATM versions of ProFontISOLatin1 are included.
|
||||
|
||||
+ “ProFontClassic 1.2 ƒ” folder
|
||||
ProFontClassic 1.2 is the 9 pt size of ProFont from the 1.2 release of the ProFont distribution. It’s included mainly for those who prefer the look of ProFont 1.2 to that of ProFont 2.2 and who are only interested in substituting ProFontClassic for Monaco 9 using Monaco Tuner.
|
||||
|
||||
+ “ProFontWindows 2.2 ƒ” folder
|
||||
Version 2.2 of the “ProFontWindows” font. This is the first release of this font, but it is version 2.2 to keep its version number in sync with that of the “ProFont” font. TrueType and ATM versions of ProFontWindows are included. This font can be useful for viewing files that originate on Windows machines.
|
||||
|
||||
+ “Monaco Tuner 1.1.1 ƒ” folder
|
||||
“Monaco Tuner” is a control panel which replaces the complicated instructions for installing “ProFont(Monaco)” included in previous releases. It lets you pick a font (such as ProFont) to be substituted for Monaco in all applications. See the file “About Monaco Tuner” inside this folder for details.
|
||||
|
||||
• What kind of Macintosh and System Software do I need to use ProFont?
|
||||
|
||||
The family of ProFont fonts are standard Macintosh fonts and should work on any Macintosh (or compatible) running any version of System 7 or Mac OS 8. The fonts may be compatible with System 6.0.8, but that has not been tested. Monaco Tuner requires System 7 or better and has been tested on several machines including a PowerBook 100 running System 7.0.1 and a PowerMac 8100/100 running System 7.5.3 and Mac OS 8 with and without QuickDraw GX.
|
||||
|
||||
• What happens if I have problems with ProFont Distribution?
|
||||
|
||||
“ProFont Distribution” is provided in the hope that it will be useful. However, it is provided AS IS and carries NO WARRANTY that it will do anything good and NO WARRANTY that it will not do anything bad. Your use of the fonts and software that make up “ProFont Distribution” is ENTIRELY AT YOUR OWN RISK. SQ Software, Stephen C. Gilardi, Carl R. Osterwald and Tobias Jung hereby disclaim any and all liability for any difficulty you may have as a result of using any part of “ProFont Distribution”. If these terms are not acceptable to you, then you must not use any part of “ProFont Distribution”.
|
||||
|
||||
That being said, if you do have any difficulties or any suggestions, I’ll be very appreciative if you let me know about them so I can attempt to improve future releases of ProFont Distribution.
|
||||
|
||||
• How do I install the various versions of ProFont?
|
||||
|
||||
The various versions of ProFont included in this release are standard Macintosh fonts. You install them into any version of System 7 or Mac OS 8 by dragging the font suitcase containing the font you want to install onto the System Folder icon on your startup disk.
|
||||
|
||||
“ProFont 2.2”, “ProFontISOLatin1 2.2”, and “ProFontWindows 2.2” also include ATM versions. Since the System Software prefers TrueType fonts to ATM fonts, special suitcases are included in the distribution which do not contain the TrueType outline version of the font. These suitcases and the corresponding PostScript font files are inside a folder called “ATM Version” within each font’s folder. To install the ATM version of one of these fonts, drag the two files contained in its “ATM Version” folder onto the System Folder icon on your startup disk.
|
||||
|
||||
Note: During testing it was discovered that some internal tables in “ProFontISOLatin1” suitcase can be damaged if you use the Finder to remove the TrueType version by dragging it out of the suitcase. Fortunately, you don’t need to do that because ProFont Distribution includes the suitcase called “ProFontISOLatin1 Bitmaps” which is does not contain the TrueType version. As the instructions above indicate, please use the “ProFontISOLatin1 Bitmaps” suitcase if you want to use ProFontISOLatin1 with ATM.
|
||||
|
||||
• Can I redistribute ProFont Distribution?
|
||||
|
||||
“ProFont Distribution” is Copyright © 1997, SQ Software. The ProFont fonts are Copyright © 1997, Carl R. Osterwald. It is our intention that “ProFont Distribution” get the widest possible distribution. You may redistribute unmodified copies of “ProFont Distriubtion” as long as it is accompanied by an unmodified copy of “About ProFont Distribution 2.2” (this file). You may not charge anyone money for the “ProFont Distribution” package itself. The “ProFont Distribution” package can be distributed for free along with products for which you do charge money. The “ProFont Distribution” package can also be distributed for free as part of collections of more than 10 third party products sold as a collection (such as on the Apprentice CD series). If you do distribute “ProFont Distribution” along with another product or as part of a collection, Stephen C. Gilardi and Carl R. Osterwald would appreciate very much each receiving a complimentary copy of the whole distribution (e.g., any CD-ROM it appears on), but this is not a requirement. If you have questions about redistribution, please contact Stephen C. Gilardi at squeegee@usa.net.
|
||||
|
||||
• Who is responsible for ProFont?
|
||||
|
||||
+ Andrew Welch
|
||||
The original “ProFont” was created by Andrew Welch. It was originally shareware. Andrew generously gave his permission for it to be distributed freely: “let’s make it free though [...] just credit me for making the font in the first place, and you’re good to go!” Andrew’s ProFont 9 font is no longer distributed in the ProFont Distribution, but the fonts included in ProFont Distribution 2.2 are based on it.
|
||||
|
||||
Thanks Andrew!
|
||||
|
||||
+ Carl Osterwald
|
||||
The fonts included in ProFont Distribution 2.2 were created by Carl Osterwald. Carl created the outline versions of ProFont and implemented the Macintosh Extended ASCII Character Set for all versions of ProFont. Most recently Carl created the ProFontWindows font and did the modifications of the character shapes for ProFont 2.2. Please send praise, comments, etc., about the fonts in “ProFont Distribution 2.2” to him.
|
||||
|
||||
Thanks Carl!
|
||||
|
||||
Carl can be reached at “carl_osterwald@usa.net”.
|
||||
|
||||
+ Steve Gilardi
|
||||
I am the author of the “modern” (post Mac II/Mac SE era) ProFont distributions. I have gotten ProFont to work with successive System releases for my personal use, and have shared the methods with other folks from time to time through these distributions. Most recently I developed the “Monaco Tuner” control panel to ease the use of ProFont as a replacement for Monaco 9. Please send comments, suggestions, and questions about Monaco Tuner, ProFont in general, or the ProFont Distribution as a whole to me.
|
||||
|
||||
I can be reached at “squeegee@usa.net”.
|
||||
|
||||
Enjoy ProFont!
|
||||
|
||||
--Steve
|
||||
|
||||
Stephen C. Gilardi
|
||||
SQ Software
|
||||
21 July 1997
|
||||
|
||||
• Version History:
|
||||
|
||||
Version 2.2:
|
||||
+ ProFont 2.2 and ProFontISOLatin1 2.2 include modifications to several characters
|
||||
for improved readability especially when anti-aliased.
|
||||
+ Several small bugs fixed in the fonts.
|
||||
+ Improved QuickDraw GX compatibility
|
||||
+ ProFontWindows 2.2 introduced.
|
||||
+ Monaco Tuner version bumped to 1.1.1 for minor documentation updates.
|
||||
|
||||
Version 2.1:
|
||||
+ Monaco Tuner 1.1 adds “Resizing of Monaco 9” and works around a bug which
|
||||
affected desk accessories on Power Macs.
|
||||
|
||||
Version 2.0:
|
||||
+ ProFont 2.0 includes modifications to several characters
|
||||
+ ProFont 2.0 includes a 7 pt bitmap version
|
||||
+ ProFontISOLatin1 2.0 released in response to requests from international users
|
||||
+ Monaco Tuner 1.0 replaces far-too-complicated “ProFont(Monaco)” installation
|
||||
instructions
|
||||
+ ProFontClassic 1.2 is the 9 pt size of ProFont from the version 1.2 release
|
||||
|
||||
Version 1.2:
|
||||
+ Both versions of ProFont now implement the full Macintosh Extended ASCII
|
||||
character set.
|
||||
|
||||
Version 1.1.1:
|
||||
+ “ProFont Info” (this file) now actually prints on LaserWriters. Sorry!
|
||||
+ Added item labeled “What about Monaco 12?”
|
||||
+ Minor editing of “ProFont Info”
|
||||
|
||||
Version 1.1:
|
||||
+ “ProFont (ProFont)” now includes TrueType and Type 1 Outline Fonts!
|
||||
+ Includes instructions for installation under System 7.5.1.
|
||||
+ I think ProFont needs an installer. If you agree, please read the bullet item labeled
|
||||
“Aren’t those instructions a little bit too complicated?”.
|
||||
##########################################################################
|
||||
# IMPORTANT NOTE #
|
||||
# #
|
||||
# This is the readme file of the ProFont distribution for #
|
||||
# Apple Macintosh. I've added it because it felt wrong to distribute #
|
||||
# a Windows version of ProFont without the words of the original #
|
||||
# authors. #
|
||||
# !! Please note that some of the information provided below is #
|
||||
# NOT valid for ProFont/Windows !! Just figure it out ... ;-) #
|
||||
# The Windows version was created using the files from the #
|
||||
# “ProFontWindows 2.2 ƒ” folder mentioned below. #
|
||||
# #
|
||||
# Comparing Mac + Win version, you'll see that all font sizes are #
|
||||
# off by 1. This means that Win 8pt version displays like Mac 9pt #
|
||||
# version. #
|
||||
# #
|
||||
# For questions about the windows version of ProFont, contact: #
|
||||
# mail@tobias-jung.de (please write in english or german language) #
|
||||
# Tobias Jung, August 2002 #
|
||||
##########################################################################
|
||||
# For version information, #
|
||||
# PLEASE READ v1_vs_v2.txt ! #
|
||||
##########################################################################
|
||||
|
||||
ProFont Distribution 2.2
|
||||
21 July 1997
|
||||
SQ Software
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
• What is ProFont?
|
||||
|
||||
ProFont began life as a better version of “Monaco 9” which is especially good for programmers. It was created circa 1987 by Andrew Welch.
|
||||
|
||||
In version 1.1 of the ProFont distribution, ProFont ceased being just a 9 point bitmap font. Carl Osterwald contributed bitmaps at several larger sizes and an outline version of ProFont in both TrueType and Adobe Type 1 (ATM) formats.
|
||||
|
||||
In version 1.2 of the ProFont distribution, Carl extended ProFont to include the entire Macintosh character set including accented characters with ASCII codes from 0x80 to 0xFF.
|
||||
|
||||
In version 2.0 of the ProFont distribution, Carl provided an ISOLatin1 encoded version of ProFont. The shapes of several of the characters have been modified for improved readability, and a 7 pt bitmap version of ProFont is included.
|
||||
|
||||
In version 2.2 of the ProFont distribution, Carl produced a version of ProFont that uses the Windows character set. Once again the shapes of several of the characters have been modified for improved readability--especially when the fonts are anti-aliased.
|
||||
|
||||
• What is the ProFont Distribution?
|
||||
|
||||
ProFont was originally released as shareware by Andrew Welch. At that time, it was distributed inside an installer application which could replace Apple’s Monaco 9 with ProFont 9. This made using ProFont as a substitute for Monaco 9 very easy. When the Mac II and SE came out, the magic used by the original installer became ineffective. Over the years I (Steve Gilardi) have figured out how to install ProFont 9 in place of Monaco 9 through the various releases of the System Software. After a time I asked Andrew for permission to distribute ProFont along with my instructions and he agreed and also decided to change ProFont’s status from shareware to freeware.
|
||||
|
||||
The methods for accomplishing the substitution for Monaco 9 have gone through significant changes over the years as the Macintosh font architecture has evolved. The various releases of what has become the “ProFont Distribution” have been my effort to share my knowledge of how to use ProFont as a replacement for Monaco 9.
|
||||
|
||||
Since Carl Osterwald became involved with the project, ProFont has blossomed into a full-fledged font in its own right and most recently into a suite of related fonts. ProFont is unusual among fonts in that the outline version was designed to closely follow the original 9 pt bitmap version. More often, fonts are conceived as outlines and then rendered at the various point sizes.
|
||||
|
||||
Earlier versions of the ProFont Distribution have included very involved instructions and utility programs to allow installation of ProFont as a replacement for Monaco 9. Release 2.2 contains none of those instructions. Instead, I have developed a control panel called “Monaco Tuner” which allows you to substitute a font of your choosing for Monaco. The substitution can be just for Monaco 9 or for all sizes of Monaco. Of course, I think the best substitute font to use is ProFont! See the information in the “Monaco Tuner 1.1.1 ƒ” folder for details.
|
||||
|
||||
• What does ProFont 2.2 look like?
|
||||
|
||||
Here’s a sample:
|
||||
[ see "provsmonaco.gif" and "profomac.gif" ]
|
||||
|
||||
|
||||
Also, each font folder in the ProFont distribution contains a file showing the font’s character set at 9 and 18 point sizes. You don’t need to install the corresponding font to see the character set.
|
||||
|
||||
• What is included in this distribution?
|
||||
|
||||
The distribution includes 7 items:
|
||||
|
||||
+ “About ProFont Distribution 2.2” SimpleText document
|
||||
This is the file you are reading now.
|
||||
|
||||
+ “ProFont Quick Start” SimpleText document
|
||||
Quick instructions for installing ProFont and Monaco Tuner.
|
||||
|
||||
+ “ProFont 2.2 ƒ” folder
|
||||
Version 2.2 of the “ProFont” font. This includes both TrueType and ATM versions of ProFont.
|
||||
|
||||
+ “ProFontISOLatin1 2.2 ƒ” folder
|
||||
Version 2.2 of the “ProFontISOLatin1” font. TrueType and ATM versions of ProFontISOLatin1 are included.
|
||||
|
||||
+ “ProFontClassic 1.2 ƒ” folder
|
||||
ProFontClassic 1.2 is the 9 pt size of ProFont from the 1.2 release of the ProFont distribution. It’s included mainly for those who prefer the look of ProFont 1.2 to that of ProFont 2.2 and who are only interested in substituting ProFontClassic for Monaco 9 using Monaco Tuner.
|
||||
|
||||
+ “ProFontWindows 2.2 ƒ” folder
|
||||
Version 2.2 of the “ProFontWindows” font. This is the first release of this font, but it is version 2.2 to keep its version number in sync with that of the “ProFont” font. TrueType and ATM versions of ProFontWindows are included. This font can be useful for viewing files that originate on Windows machines.
|
||||
|
||||
+ “Monaco Tuner 1.1.1 ƒ” folder
|
||||
“Monaco Tuner” is a control panel which replaces the complicated instructions for installing “ProFont(Monaco)” included in previous releases. It lets you pick a font (such as ProFont) to be substituted for Monaco in all applications. See the file “About Monaco Tuner” inside this folder for details.
|
||||
|
||||
• What kind of Macintosh and System Software do I need to use ProFont?
|
||||
|
||||
The family of ProFont fonts are standard Macintosh fonts and should work on any Macintosh (or compatible) running any version of System 7 or Mac OS 8. The fonts may be compatible with System 6.0.8, but that has not been tested. Monaco Tuner requires System 7 or better and has been tested on several machines including a PowerBook 100 running System 7.0.1 and a PowerMac 8100/100 running System 7.5.3 and Mac OS 8 with and without QuickDraw GX.
|
||||
|
||||
• What happens if I have problems with ProFont Distribution?
|
||||
|
||||
“ProFont Distribution” is provided in the hope that it will be useful. However, it is provided AS IS and carries NO WARRANTY that it will do anything good and NO WARRANTY that it will not do anything bad. Your use of the fonts and software that make up “ProFont Distribution” is ENTIRELY AT YOUR OWN RISK. SQ Software, Stephen C. Gilardi, Carl R. Osterwald and Tobias Jung hereby disclaim any and all liability for any difficulty you may have as a result of using any part of “ProFont Distribution”. If these terms are not acceptable to you, then you must not use any part of “ProFont Distribution”.
|
||||
|
||||
That being said, if you do have any difficulties or any suggestions, I’ll be very appreciative if you let me know about them so I can attempt to improve future releases of ProFont Distribution.
|
||||
|
||||
• How do I install the various versions of ProFont?
|
||||
|
||||
The various versions of ProFont included in this release are standard Macintosh fonts. You install them into any version of System 7 or Mac OS 8 by dragging the font suitcase containing the font you want to install onto the System Folder icon on your startup disk.
|
||||
|
||||
“ProFont 2.2”, “ProFontISOLatin1 2.2”, and “ProFontWindows 2.2” also include ATM versions. Since the System Software prefers TrueType fonts to ATM fonts, special suitcases are included in the distribution which do not contain the TrueType outline version of the font. These suitcases and the corresponding PostScript font files are inside a folder called “ATM Version” within each font’s folder. To install the ATM version of one of these fonts, drag the two files contained in its “ATM Version” folder onto the System Folder icon on your startup disk.
|
||||
|
||||
Note: During testing it was discovered that some internal tables in “ProFontISOLatin1” suitcase can be damaged if you use the Finder to remove the TrueType version by dragging it out of the suitcase. Fortunately, you don’t need to do that because ProFont Distribution includes the suitcase called “ProFontISOLatin1 Bitmaps” which is does not contain the TrueType version. As the instructions above indicate, please use the “ProFontISOLatin1 Bitmaps” suitcase if you want to use ProFontISOLatin1 with ATM.
|
||||
|
||||
• Can I redistribute ProFont Distribution?
|
||||
|
||||
“ProFont Distribution” is Copyright © 1997, SQ Software. The ProFont fonts are Copyright © 1997, Carl R. Osterwald. It is our intention that “ProFont Distribution” get the widest possible distribution. You may redistribute unmodified copies of “ProFont Distriubtion” as long as it is accompanied by an unmodified copy of “About ProFont Distribution 2.2” (this file). You may not charge anyone money for the “ProFont Distribution” package itself. The “ProFont Distribution” package can be distributed for free along with products for which you do charge money. The “ProFont Distribution” package can also be distributed for free as part of collections of more than 10 third party products sold as a collection (such as on the Apprentice CD series). If you do distribute “ProFont Distribution” along with another product or as part of a collection, Stephen C. Gilardi and Carl R. Osterwald would appreciate very much each receiving a complimentary copy of the whole distribution (e.g., any CD-ROM it appears on), but this is not a requirement. If you have questions about redistribution, please contact Stephen C. Gilardi at squeegee@usa.net.
|
||||
|
||||
• Who is responsible for ProFont?
|
||||
|
||||
+ Andrew Welch
|
||||
The original “ProFont” was created by Andrew Welch. It was originally shareware. Andrew generously gave his permission for it to be distributed freely: “let’s make it free though [...] just credit me for making the font in the first place, and you’re good to go!” Andrew’s ProFont 9 font is no longer distributed in the ProFont Distribution, but the fonts included in ProFont Distribution 2.2 are based on it.
|
||||
|
||||
Thanks Andrew!
|
||||
|
||||
+ Carl Osterwald
|
||||
The fonts included in ProFont Distribution 2.2 were created by Carl Osterwald. Carl created the outline versions of ProFont and implemented the Macintosh Extended ASCII Character Set for all versions of ProFont. Most recently Carl created the ProFontWindows font and did the modifications of the character shapes for ProFont 2.2. Please send praise, comments, etc., about the fonts in “ProFont Distribution 2.2” to him.
|
||||
|
||||
Thanks Carl!
|
||||
|
||||
Carl can be reached at “carl_osterwald@usa.net”.
|
||||
|
||||
+ Steve Gilardi
|
||||
I am the author of the “modern” (post Mac II/Mac SE era) ProFont distributions. I have gotten ProFont to work with successive System releases for my personal use, and have shared the methods with other folks from time to time through these distributions. Most recently I developed the “Monaco Tuner” control panel to ease the use of ProFont as a replacement for Monaco 9. Please send comments, suggestions, and questions about Monaco Tuner, ProFont in general, or the ProFont Distribution as a whole to me.
|
||||
|
||||
I can be reached at “squeegee@usa.net”.
|
||||
|
||||
Enjoy ProFont!
|
||||
|
||||
--Steve
|
||||
|
||||
Stephen C. Gilardi
|
||||
SQ Software
|
||||
21 July 1997
|
||||
|
||||
• Version History:
|
||||
|
||||
Version 2.2:
|
||||
+ ProFont 2.2 and ProFontISOLatin1 2.2 include modifications to several characters
|
||||
for improved readability especially when anti-aliased.
|
||||
+ Several small bugs fixed in the fonts.
|
||||
+ Improved QuickDraw GX compatibility
|
||||
+ ProFontWindows 2.2 introduced.
|
||||
+ Monaco Tuner version bumped to 1.1.1 for minor documentation updates.
|
||||
|
||||
Version 2.1:
|
||||
+ Monaco Tuner 1.1 adds “Resizing of Monaco 9” and works around a bug which
|
||||
affected desk accessories on Power Macs.
|
||||
|
||||
Version 2.0:
|
||||
+ ProFont 2.0 includes modifications to several characters
|
||||
+ ProFont 2.0 includes a 7 pt bitmap version
|
||||
+ ProFontISOLatin1 2.0 released in response to requests from international users
|
||||
+ Monaco Tuner 1.0 replaces far-too-complicated “ProFont(Monaco)” installation
|
||||
instructions
|
||||
+ ProFontClassic 1.2 is the 9 pt size of ProFont from the version 1.2 release
|
||||
|
||||
Version 1.2:
|
||||
+ Both versions of ProFont now implement the full Macintosh Extended ASCII
|
||||
character set.
|
||||
|
||||
Version 1.1.1:
|
||||
+ “ProFont Info” (this file) now actually prints on LaserWriters. Sorry!
|
||||
+ Added item labeled “What about Monaco 12?”
|
||||
+ Minor editing of “ProFont Info”
|
||||
|
||||
Version 1.1:
|
||||
+ “ProFont (ProFont)” now includes TrueType and Type 1 Outline Fonts!
|
||||
+ Includes instructions for installation under System 7.5.1.
|
||||
+ I think ProFont needs an installer. If you agree, please read the bullet item labeled
|
||||
“Aren’t those instructions a little bit too complicated?”.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
folder:808080
|
||||
ipod:00B0B0
|
||||
mp3:00FF00
|
||||
flac:00FF00
|
||||
ogg:00FF00
|
||||
txt:FF0000
|
||||
cfg:D00000
|
||||
folder:808080
|
||||
ipod:00B0B0
|
||||
mp3:00FF00
|
||||
flac:00FF00
|
||||
ogg:00FF00
|
||||
txt:FF0000
|
||||
cfg:D00000
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/*
|
||||
* (C) Copyright 2007 Catalin Patulea <cat@vv.carleton.ca>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef DSP_H
|
||||
/*
|
||||
* (C) Copyright 2007 Catalin Patulea <cat@vv.carleton.ca>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef DSP_H
|
||||
#define DSP_H
|
||||
|
||||
/* DSP memory is mapped into ARM space via HPIB. */
|
||||
#define DSP_(addr) (*(volatile unsigned short *)(0x40000 + ((addr) << 1)))
|
||||
|
||||
/* DSP memory is mapped into ARM space via HPIB. */
|
||||
#define DSP_(addr) (*(volatile unsigned short *)(0x40000 + ((addr) << 1)))
|
||||
|
||||
/* A "DSP image" is an array of these, terminated by raw_data_size_half = 0. */
|
||||
struct dsp_section {
|
||||
|
@ -34,9 +34,9 @@ struct dsp_section {
|
|||
|
||||
/* Must define struct dsp_section before including the image. */
|
||||
#include "dsp/dsp-image.h"
|
||||
|
||||
|
||||
void dsp_wake(void);
|
||||
void dsp_load(const struct dsp_section *im);
|
||||
void dsp_load(const struct dsp_section *im);
|
||||
void dsp_reset(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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 "audio.h"
|
||||
#include "registers.h"
|
||||
|
||||
/* based on http://archopen.svn.sourceforge.net/viewvc/archopen/ArchOpen/trunk/libdsp/aic23.c?revision=213&view=markup */
|
||||
void audiohw_init(void)
|
||||
{
|
||||
/* port config */
|
||||
#if 0
|
||||
SPCR10 = 0; /* DLB = 0 ** RJUST = 0 ** CLKSTP = 0 ** DXENA = 0 ** ABIS = 0 ** RINTM = 0 ** RSYNCER = 0 ** RFULL = 0 ** RRDY = 0 ** RRST = 0 */
|
||||
SPCR20 = (1 << 9); /* FREE = 1 ** SOFT = 0 ** FRST = 0 ** GRST = 0 ** XINTM = 0 ** XSYNCER = 0 ** XEMPTY = 0 ** XRDY = 0 ** XRST = 0 */
|
||||
RCR10 = (1 << 8) | (2 << 5); /* RFRLEN1 = 1 ** RWDLEN1 = 2 */
|
||||
RCR20 = 0; /* RPHASE = 0 ** RFRLEN2 = 0 ** RWDLEN2 = 0 ** RCOMPAND = 0 ** RFIG = 0 ** RDATDLY = 0 */
|
||||
XCR10 = (1 << 8) | (2 << 5); /* XFRLEN1 = 1 ** XWDLEN1 = 2 */
|
||||
XCR20 = 0; /* XPHASE = 0 ** XFRLEN2 = 0 ** XWDLEN2 = 0 ** XCOMPAND = 0 ** XFIG = 0 ** XDATDLY = 0 */
|
||||
SRGR10 = 0; /* FWID = 0 ** CLKGDV = 0 */
|
||||
SRGR20 = 0; /* FREE = 0 ** CLKSP = 0 ** CLKSM = 0 ** FSGM = 0 ** FPER = 0 */
|
||||
PCR0 = (1 << 1) | 1; /* IDLEEN = 0 ** XIOEN = 0 ** RIOEN = 0 ** FSXM = 0 ** FSRM = 0 ** SCLKME = 0 ** CLKSSTAT = 0 ** DXSTAT = 0 ** DRSTAT = 0 ** CLKXM = 0 ** CLKRM = 0 ** FSXP = 0 ** FSRP = 0 ** CLKXP = 1 ** CLKRP = 1 */
|
||||
#else
|
||||
SPCR10 = 0;
|
||||
SPCR20 = 0x0200; /* SPCR : free running mode */
|
||||
|
||||
RCR10 = 0x00A0;
|
||||
RCR20 = 0x00A1; /* RCR : 32 bit receive data length */
|
||||
|
||||
XCR10 = 0x00A0;
|
||||
XCR20 = 0x00A0; /* XCR : 32 bit transmit data length */
|
||||
|
||||
SRGR10 = 0;
|
||||
SRGR20 = 0x3000; /* SRGR 1 & 2 */
|
||||
|
||||
PCR0 = 0x000E - 8; /* PCR : FSX, FSR active low, external FS/CLK source */
|
||||
#endif
|
||||
}
|
||||
|
||||
void audiohw_postinit(void)
|
||||
{
|
||||
/* Trigger first XEVT0 */
|
||||
SPCR20 |= 1;
|
||||
}
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "audio.h"
|
||||
#include "registers.h"
|
||||
|
||||
/* based on http://archopen.svn.sourceforge.net/viewvc/archopen/ArchOpen/trunk/libdsp/aic23.c?revision=213&view=markup */
|
||||
void audiohw_init(void)
|
||||
{
|
||||
/* port config */
|
||||
#if 0
|
||||
SPCR10 = 0; /* DLB = 0 ** RJUST = 0 ** CLKSTP = 0 ** DXENA = 0 ** ABIS = 0 ** RINTM = 0 ** RSYNCER = 0 ** RFULL = 0 ** RRDY = 0 ** RRST = 0 */
|
||||
SPCR20 = (1 << 9); /* FREE = 1 ** SOFT = 0 ** FRST = 0 ** GRST = 0 ** XINTM = 0 ** XSYNCER = 0 ** XEMPTY = 0 ** XRDY = 0 ** XRST = 0 */
|
||||
RCR10 = (1 << 8) | (2 << 5); /* RFRLEN1 = 1 ** RWDLEN1 = 2 */
|
||||
RCR20 = 0; /* RPHASE = 0 ** RFRLEN2 = 0 ** RWDLEN2 = 0 ** RCOMPAND = 0 ** RFIG = 0 ** RDATDLY = 0 */
|
||||
XCR10 = (1 << 8) | (2 << 5); /* XFRLEN1 = 1 ** XWDLEN1 = 2 */
|
||||
XCR20 = 0; /* XPHASE = 0 ** XFRLEN2 = 0 ** XWDLEN2 = 0 ** XCOMPAND = 0 ** XFIG = 0 ** XDATDLY = 0 */
|
||||
SRGR10 = 0; /* FWID = 0 ** CLKGDV = 0 */
|
||||
SRGR20 = 0; /* FREE = 0 ** CLKSP = 0 ** CLKSM = 0 ** FSGM = 0 ** FPER = 0 */
|
||||
PCR0 = (1 << 1) | 1; /* IDLEEN = 0 ** XIOEN = 0 ** RIOEN = 0 ** FSXM = 0 ** FSRM = 0 ** SCLKME = 0 ** CLKSSTAT = 0 ** DXSTAT = 0 ** DRSTAT = 0 ** CLKXM = 0 ** CLKRM = 0 ** FSXP = 0 ** FSRP = 0 ** CLKXP = 1 ** CLKRP = 1 */
|
||||
#else
|
||||
SPCR10 = 0;
|
||||
SPCR20 = 0x0200; /* SPCR : free running mode */
|
||||
|
||||
RCR10 = 0x00A0;
|
||||
RCR20 = 0x00A1; /* RCR : 32 bit receive data length */
|
||||
|
||||
XCR10 = 0x00A0;
|
||||
XCR20 = 0x00A0; /* XCR : 32 bit transmit data length */
|
||||
|
||||
SRGR10 = 0;
|
||||
SRGR20 = 0x3000; /* SRGR 1 & 2 */
|
||||
|
||||
PCR0 = 0x000E - 8; /* PCR : FSX, FSR active low, external FS/CLK source */
|
||||
#endif
|
||||
}
|
||||
|
||||
void audiohw_postinit(void)
|
||||
{
|
||||
/* Trigger first XEVT0 */
|
||||
SPCR20 |= 1;
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
void audiohw_init(void);
|
||||
void audiohw_postinit(void);
|
||||
|
||||
#endif
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
void audiohw_init(void);
|
||||
void audiohw_postinit(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,233 +1,233 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Catalin Patulea
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
* Copyright (C) 2009 by Karl Kurbjun
|
||||
*
|
||||
* 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 "registers.h"
|
||||
#include "arm.h"
|
||||
#include "ipc.h"
|
||||
|
||||
/* Size of data buffer in words (16 bit) */
|
||||
#define DSP_BUFFER_SIZE (0x1000)
|
||||
|
||||
/* Put the "data" buffer in it's own .dma section so that it can
|
||||
* be handled in the linker.cmd. */
|
||||
#pragma DATA_SECTION (data, ".dma")
|
||||
|
||||
/* This is the "data" buffer on the DSP side used for SARAM to McBSP (IIS) */
|
||||
static signed short data[DSP_BUFFER_SIZE];
|
||||
|
||||
/* These two describe the location of the buffer on the ARM (set in DSPHINT) */
|
||||
volatile unsigned short sdem_addrh;
|
||||
volatile unsigned short sdem_addrl;
|
||||
|
||||
/* This is the size of the ARM buffer (set in DSPHINT) */
|
||||
volatile unsigned short sdem_dsp_size;
|
||||
|
||||
/* These two variables keep track of the buffer level in the DSP, dsp_level,
|
||||
* (SARAM to McBSP) and the level on the ARM buffer (sdem_level).
|
||||
* sdem_level is used in the main firmware to keep track of the current
|
||||
* playback status. dsp_level is only used in this function. */
|
||||
static unsigned short dsp_level;
|
||||
volatile unsigned short sdem_level;
|
||||
|
||||
/* This is used to keep track of the last SDRAM to SARAM transfer */
|
||||
static unsigned short last_size;
|
||||
|
||||
/* This tells us which half of the DSP buffer (data) is free */
|
||||
static unsigned short dma0_unlocked;
|
||||
|
||||
/* This is used by the ARM to flag playback status and start/stop the DMA
|
||||
* transfers. */
|
||||
volatile unsigned short dma0_stopped;
|
||||
|
||||
/* This is used to effectively flag whether the ARM has new data ready or not */
|
||||
short waiting;
|
||||
|
||||
|
||||
/* rebuffer sets up the next SDRAM to SARAM transfer and tells the ARM when DMA
|
||||
* needs a new buffer.
|
||||
*
|
||||
* Note: The upper limit on larger buffers is the size of a short. If larger
|
||||
* buffer sizes are needed the code on the ARM side needs to be changed to
|
||||
* update a full long.
|
||||
*/
|
||||
void rebuffer(void)
|
||||
{
|
||||
unsigned long sdem_addr;
|
||||
|
||||
if(dma0_stopped==1 || dma0_stopped==2) /* Stop / Pause */
|
||||
{
|
||||
/* Stop MCBSP DMA0 */
|
||||
DMPREC &= 0xFFFE;
|
||||
/* Shut the transmitter down */
|
||||
audiohw_stop();
|
||||
|
||||
/* Stop the HPIB transfer if it is running */
|
||||
DMA_TRG = 0;
|
||||
|
||||
/* Reset the following variables for DMA restart */
|
||||
sdem_level = 0;
|
||||
dsp_level = 0;
|
||||
last_size = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the sdem_level is equal to the buffer size the ARM code gave
|
||||
* (sdem_dsp_size) then reset the size and ask the arm for another buffer
|
||||
*/
|
||||
if(sdem_level == sdem_dsp_size)
|
||||
{
|
||||
sdem_level=0;
|
||||
|
||||
/* Get a new buffer (location and size) from ARM */
|
||||
status.msg = MSG_REFILL;
|
||||
waiting=1;
|
||||
|
||||
/* trigger DSPHINT on the ARM */
|
||||
int_arm();
|
||||
}
|
||||
|
||||
if(!waiting)
|
||||
{
|
||||
/* Size is in bytes (but forced 32 bit transfers). Comparison is
|
||||
* against DSP_BUFFER_SIZE because it is in words and this needs to
|
||||
* compare against half the total size in bytes. */
|
||||
if( dsp_level + sdem_dsp_size - sdem_level > DSP_BUFFER_SIZE)
|
||||
{
|
||||
last_size = DSP_BUFFER_SIZE - dsp_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_size = sdem_dsp_size - sdem_level;
|
||||
}
|
||||
|
||||
/* DSP addresses are 16 bit (word). dsp_level is in bytes so it needs to
|
||||
* be converted to words. */
|
||||
DSP_ADDRL = (unsigned short)data + dma0_unlocked + (dsp_level >> 1);
|
||||
DSP_ADDRH = 0;
|
||||
|
||||
/* SDRAM addresses are 8 bit (byte)
|
||||
* Warning: These addresses are forced to 32 bit alignment!
|
||||
*/
|
||||
sdem_addr = ((unsigned long)sdem_addrh << 16 | sdem_addrl) + sdem_level;
|
||||
SDEM_ADDRL = sdem_addr & 0xffff;
|
||||
SDEM_ADDRH = sdem_addr >> 16;
|
||||
|
||||
/* Set the size of the SDRAM to SARAM transfer (demac transfer) */
|
||||
DMA_SIZE = last_size;
|
||||
|
||||
DMA_CTRL = 0;
|
||||
|
||||
/* These are just debug signals that are not used/needed right now */
|
||||
status.payload.refill._DMA_TRG = DMA_TRG;
|
||||
status.payload.refill._SDEM_ADDRH = SDEM_ADDRH;
|
||||
status.payload.refill._SDEM_ADDRL = SDEM_ADDRL;
|
||||
status.payload.refill._DSP_ADDRH = DSP_ADDRH;
|
||||
status.payload.refill._DSP_ADDRL = DSP_ADDRL;
|
||||
|
||||
/* Start the demac transfer */
|
||||
DMA_TRG = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* This interupt handler is for the SARAM (on DSP) to McBSP IIS DMA transfer.
|
||||
* It interupts at 1/2 empty and empty so that we can start filling a new buffer
|
||||
* from SDRAM when a half is free. dsp_level should always be full when this
|
||||
* interupt occurs except for the initial start. */
|
||||
interrupt void handle_dma0(void)
|
||||
{
|
||||
/* Byte offset to half-buffer locked by DMA0.
|
||||
0 for top, DSP_BUFFER_SIZE/2 for bottom */
|
||||
unsigned short dma0_locked;
|
||||
|
||||
IFR = 1 << 6;
|
||||
|
||||
/* DMSRC0 is the beginning of the DMA0-locked SARAM half-buffer. */
|
||||
DMSA = 0x00 /* DMSRC0 (banked register, see page 133 of SPRU302B */;
|
||||
|
||||
/* Note that these address offsets (dma0_locked and dma0_unlocked are in
|
||||
* words. */
|
||||
dma0_locked = DMSDN & (DSP_BUFFER_SIZE>>1);
|
||||
dma0_unlocked = dma0_locked ^ (DSP_BUFFER_SIZE>>1);
|
||||
|
||||
dsp_level = 0;
|
||||
|
||||
/* Start the SDRAM to SARAM copy */
|
||||
rebuffer();
|
||||
}
|
||||
|
||||
/* This interupt handler runs every time a DMA transfer is complete from SDRAM
|
||||
* to the SARAM buffer. It is used to update the SARAM buffer level
|
||||
* (dsp_level), the SDRAM buffer level (sdem_level) and to rebuffer if the dsp
|
||||
* buffer is not full. */
|
||||
interrupt void handle_dmac(void) {
|
||||
IFR = 1 << 11; /* Clear interrupt */
|
||||
|
||||
/* dsp_level and sdem_level are in bytes */
|
||||
dsp_level += last_size;
|
||||
sdem_level += last_size;
|
||||
|
||||
/* compare to DSP_BUFFER_SIZE without a divide because it is in words and
|
||||
* we want half the total size in bytes. */
|
||||
if(dsp_level < DSP_BUFFER_SIZE)
|
||||
{
|
||||
rebuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void dma_init(void) {
|
||||
/* Initialize some of the global variables to known values avoiding the
|
||||
* .cinit section. */
|
||||
dsp_level = 0;
|
||||
sdem_level = 0;
|
||||
|
||||
last_size = 0;
|
||||
dma0_unlocked = 0;
|
||||
dma0_stopped = 1;
|
||||
|
||||
waiting = 0;
|
||||
|
||||
/* Configure SARAM to McBSP DMA */
|
||||
|
||||
/* Event XEVT0, 32-bit transfers, 0 frame count */
|
||||
DMSFC0 = 2 << 12 | 1 << 11;
|
||||
|
||||
/* Interrupts generated, Half and full buffer.
|
||||
* ABU mode, From data space with postincrement, to data space with no
|
||||
* change
|
||||
*/
|
||||
DMMCR0 = 1 << 14 | 1 << 13 |
|
||||
1 << 12 | 1 << 8 | 1 << 6 | 1;
|
||||
|
||||
/* Set the source (incrementing) location */
|
||||
DMSRC0 = (unsigned short)&data;
|
||||
|
||||
/* Set the destination (static) location to the McBSP IIS interface */
|
||||
DMDST0 = (unsigned short)&DXR20;
|
||||
|
||||
/* Set the size of the buffer */
|
||||
DMCTR0 = sizeof(data);
|
||||
|
||||
/* Setup DMA0 interrupts and start the transfer */
|
||||
DMPREC = 2 << 6;
|
||||
}
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Catalin Patulea
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
* Copyright (C) 2009 by Karl Kurbjun
|
||||
*
|
||||
* 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 "registers.h"
|
||||
#include "arm.h"
|
||||
#include "ipc.h"
|
||||
|
||||
/* Size of data buffer in words (16 bit) */
|
||||
#define DSP_BUFFER_SIZE (0x1000)
|
||||
|
||||
/* Put the "data" buffer in it's own .dma section so that it can
|
||||
* be handled in the linker.cmd. */
|
||||
#pragma DATA_SECTION (data, ".dma")
|
||||
|
||||
/* This is the "data" buffer on the DSP side used for SARAM to McBSP (IIS) */
|
||||
static signed short data[DSP_BUFFER_SIZE];
|
||||
|
||||
/* These two describe the location of the buffer on the ARM (set in DSPHINT) */
|
||||
volatile unsigned short sdem_addrh;
|
||||
volatile unsigned short sdem_addrl;
|
||||
|
||||
/* This is the size of the ARM buffer (set in DSPHINT) */
|
||||
volatile unsigned short sdem_dsp_size;
|
||||
|
||||
/* These two variables keep track of the buffer level in the DSP, dsp_level,
|
||||
* (SARAM to McBSP) and the level on the ARM buffer (sdem_level).
|
||||
* sdem_level is used in the main firmware to keep track of the current
|
||||
* playback status. dsp_level is only used in this function. */
|
||||
static unsigned short dsp_level;
|
||||
volatile unsigned short sdem_level;
|
||||
|
||||
/* This is used to keep track of the last SDRAM to SARAM transfer */
|
||||
static unsigned short last_size;
|
||||
|
||||
/* This tells us which half of the DSP buffer (data) is free */
|
||||
static unsigned short dma0_unlocked;
|
||||
|
||||
/* This is used by the ARM to flag playback status and start/stop the DMA
|
||||
* transfers. */
|
||||
volatile unsigned short dma0_stopped;
|
||||
|
||||
/* This is used to effectively flag whether the ARM has new data ready or not */
|
||||
short waiting;
|
||||
|
||||
|
||||
/* rebuffer sets up the next SDRAM to SARAM transfer and tells the ARM when DMA
|
||||
* needs a new buffer.
|
||||
*
|
||||
* Note: The upper limit on larger buffers is the size of a short. If larger
|
||||
* buffer sizes are needed the code on the ARM side needs to be changed to
|
||||
* update a full long.
|
||||
*/
|
||||
void rebuffer(void)
|
||||
{
|
||||
unsigned long sdem_addr;
|
||||
|
||||
if(dma0_stopped==1 || dma0_stopped==2) /* Stop / Pause */
|
||||
{
|
||||
/* Stop MCBSP DMA0 */
|
||||
DMPREC &= 0xFFFE;
|
||||
/* Shut the transmitter down */
|
||||
audiohw_stop();
|
||||
|
||||
/* Stop the HPIB transfer if it is running */
|
||||
DMA_TRG = 0;
|
||||
|
||||
/* Reset the following variables for DMA restart */
|
||||
sdem_level = 0;
|
||||
dsp_level = 0;
|
||||
last_size = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the sdem_level is equal to the buffer size the ARM code gave
|
||||
* (sdem_dsp_size) then reset the size and ask the arm for another buffer
|
||||
*/
|
||||
if(sdem_level == sdem_dsp_size)
|
||||
{
|
||||
sdem_level=0;
|
||||
|
||||
/* Get a new buffer (location and size) from ARM */
|
||||
status.msg = MSG_REFILL;
|
||||
waiting=1;
|
||||
|
||||
/* trigger DSPHINT on the ARM */
|
||||
int_arm();
|
||||
}
|
||||
|
||||
if(!waiting)
|
||||
{
|
||||
/* Size is in bytes (but forced 32 bit transfers). Comparison is
|
||||
* against DSP_BUFFER_SIZE because it is in words and this needs to
|
||||
* compare against half the total size in bytes. */
|
||||
if( dsp_level + sdem_dsp_size - sdem_level > DSP_BUFFER_SIZE)
|
||||
{
|
||||
last_size = DSP_BUFFER_SIZE - dsp_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_size = sdem_dsp_size - sdem_level;
|
||||
}
|
||||
|
||||
/* DSP addresses are 16 bit (word). dsp_level is in bytes so it needs to
|
||||
* be converted to words. */
|
||||
DSP_ADDRL = (unsigned short)data + dma0_unlocked + (dsp_level >> 1);
|
||||
DSP_ADDRH = 0;
|
||||
|
||||
/* SDRAM addresses are 8 bit (byte)
|
||||
* Warning: These addresses are forced to 32 bit alignment!
|
||||
*/
|
||||
sdem_addr = ((unsigned long)sdem_addrh << 16 | sdem_addrl) + sdem_level;
|
||||
SDEM_ADDRL = sdem_addr & 0xffff;
|
||||
SDEM_ADDRH = sdem_addr >> 16;
|
||||
|
||||
/* Set the size of the SDRAM to SARAM transfer (demac transfer) */
|
||||
DMA_SIZE = last_size;
|
||||
|
||||
DMA_CTRL = 0;
|
||||
|
||||
/* These are just debug signals that are not used/needed right now */
|
||||
status.payload.refill._DMA_TRG = DMA_TRG;
|
||||
status.payload.refill._SDEM_ADDRH = SDEM_ADDRH;
|
||||
status.payload.refill._SDEM_ADDRL = SDEM_ADDRL;
|
||||
status.payload.refill._DSP_ADDRH = DSP_ADDRH;
|
||||
status.payload.refill._DSP_ADDRL = DSP_ADDRL;
|
||||
|
||||
/* Start the demac transfer */
|
||||
DMA_TRG = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* This interupt handler is for the SARAM (on DSP) to McBSP IIS DMA transfer.
|
||||
* It interupts at 1/2 empty and empty so that we can start filling a new buffer
|
||||
* from SDRAM when a half is free. dsp_level should always be full when this
|
||||
* interupt occurs except for the initial start. */
|
||||
interrupt void handle_dma0(void)
|
||||
{
|
||||
/* Byte offset to half-buffer locked by DMA0.
|
||||
0 for top, DSP_BUFFER_SIZE/2 for bottom */
|
||||
unsigned short dma0_locked;
|
||||
|
||||
IFR = 1 << 6;
|
||||
|
||||
/* DMSRC0 is the beginning of the DMA0-locked SARAM half-buffer. */
|
||||
DMSA = 0x00 /* DMSRC0 (banked register, see page 133 of SPRU302B */;
|
||||
|
||||
/* Note that these address offsets (dma0_locked and dma0_unlocked are in
|
||||
* words. */
|
||||
dma0_locked = DMSDN & (DSP_BUFFER_SIZE>>1);
|
||||
dma0_unlocked = dma0_locked ^ (DSP_BUFFER_SIZE>>1);
|
||||
|
||||
dsp_level = 0;
|
||||
|
||||
/* Start the SDRAM to SARAM copy */
|
||||
rebuffer();
|
||||
}
|
||||
|
||||
/* This interupt handler runs every time a DMA transfer is complete from SDRAM
|
||||
* to the SARAM buffer. It is used to update the SARAM buffer level
|
||||
* (dsp_level), the SDRAM buffer level (sdem_level) and to rebuffer if the dsp
|
||||
* buffer is not full. */
|
||||
interrupt void handle_dmac(void) {
|
||||
IFR = 1 << 11; /* Clear interrupt */
|
||||
|
||||
/* dsp_level and sdem_level are in bytes */
|
||||
dsp_level += last_size;
|
||||
sdem_level += last_size;
|
||||
|
||||
/* compare to DSP_BUFFER_SIZE without a divide because it is in words and
|
||||
* we want half the total size in bytes. */
|
||||
if(dsp_level < DSP_BUFFER_SIZE)
|
||||
{
|
||||
rebuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void dma_init(void) {
|
||||
/* Initialize some of the global variables to known values avoiding the
|
||||
* .cinit section. */
|
||||
dsp_level = 0;
|
||||
sdem_level = 0;
|
||||
|
||||
last_size = 0;
|
||||
dma0_unlocked = 0;
|
||||
dma0_stopped = 1;
|
||||
|
||||
waiting = 0;
|
||||
|
||||
/* Configure SARAM to McBSP DMA */
|
||||
|
||||
/* Event XEVT0, 32-bit transfers, 0 frame count */
|
||||
DMSFC0 = 2 << 12 | 1 << 11;
|
||||
|
||||
/* Interrupts generated, Half and full buffer.
|
||||
* ABU mode, From data space with postincrement, to data space with no
|
||||
* change
|
||||
*/
|
||||
DMMCR0 = 1 << 14 | 1 << 13 |
|
||||
1 << 12 | 1 << 8 | 1 << 6 | 1;
|
||||
|
||||
/* Set the source (incrementing) location */
|
||||
DMSRC0 = (unsigned short)&data;
|
||||
|
||||
/* Set the destination (static) location to the McBSP IIS interface */
|
||||
DMDST0 = (unsigned short)&DXR20;
|
||||
|
||||
/* Set the size of the buffer */
|
||||
DMCTR0 = sizeof(data);
|
||||
|
||||
/* Setup DMA0 interrupts and start the transfer */
|
||||
DMPREC = 2 << 6;
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DMA_H
|
||||
#define DMA_H
|
||||
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DMA_H
|
||||
#define DMA_H
|
||||
|
||||
void dma_init(void);
|
||||
void rebuffer(void);
|
||||
|
||||
extern int waiting;
|
||||
|
||||
extern volatile unsigned short dma0_stopped;
|
||||
|
||||
#endif
|
||||
extern volatile unsigned short dma0_stopped;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Catalin Patulea
|
||||
*
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Catalin Patulea
|
||||
*
|
||||
* 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 "audio.h"
|
||||
#include "registers.h"
|
||||
|
||||
void audiohw_init(void)
|
||||
{
|
||||
/* Configure McBSP */
|
||||
SPCR10 = 0; /* Receiver reset */
|
||||
SPCR20 = 3 << 4; /* Rate gen disabled, RINT=XSYNCERR, TX disabled for now */
|
||||
PCR0 = 1 << 1; /* Serial port pins, external frame sync, external clock,
|
||||
frame sync FSX is active-high,
|
||||
TX data sampled on falling clock */
|
||||
XCR10 = 0x00a0; /* 1 word per frame, 32 bits per word */
|
||||
XCR20 = 0; /* Single-phase, unexpected frame pulse restarts xfer,
|
||||
0-bit data delay */
|
||||
}
|
||||
|
||||
void audiohw_start(void)
|
||||
{
|
||||
/* Trigger first XEVT0 */
|
||||
SPCR20 |= 1;
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "audio.h"
|
||||
#include "registers.h"
|
||||
|
||||
void audiohw_init(void)
|
||||
{
|
||||
/* Configure McBSP */
|
||||
SPCR10 = 0; /* Receiver reset */
|
||||
SPCR20 = 3 << 4; /* Rate gen disabled, RINT=XSYNCERR, TX disabled for now */
|
||||
PCR0 = 1 << 1; /* Serial port pins, external frame sync, external clock,
|
||||
frame sync FSX is active-high,
|
||||
TX data sampled on falling clock */
|
||||
XCR10 = 0x00a0; /* 1 word per frame, 32 bits per word */
|
||||
XCR20 = 0; /* Single-phase, unexpected frame pulse restarts xfer,
|
||||
0-bit data delay */
|
||||
}
|
||||
|
||||
|
||||
void audiohw_start(void)
|
||||
{
|
||||
/* Trigger first XEVT0 */
|
||||
SPCR20 |= 1;
|
||||
}
|
||||
|
||||
void audiohw_stop(void)
|
||||
{
|
||||
/* Reset the transmitter */
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
#ifndef DSP_IMAGE_HELLOWORLD
|
||||
#define DSP_IMAGE_HELLOWORLD
|
||||
/*
|
||||
* This is just a dummy DSP image so that dsp-dm320.c compiles.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
static const struct dsp_section dsp_image_helloworld[] = {
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
|
||||
/* Symbol table, usable with the DSP_() macro (see dsp-target.h). */
|
||||
#define _status 0x0000
|
||||
#define _acked 0x0000
|
||||
|
||||
#endif
|
||||
#ifndef DSP_IMAGE_HELLOWORLD
|
||||
#define DSP_IMAGE_HELLOWORLD
|
||||
/*
|
||||
* This is just a dummy DSP image so that dsp-dm320.c compiles.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
static const struct dsp_section dsp_image_helloworld[] = {
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
|
||||
/* Symbol table, usable with the DSP_() macro (see dsp-target.h). */
|
||||
#define _status 0x0000
|
||||
#define _acked 0x0000
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
/*
|
||||
* (C) Copyright 2007 Catalin Patulea <cat@vv.carleton.ca>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
void uart_init(void);
|
||||
bool uart1_available(void);
|
||||
|
||||
int uart1_gets_queue(char *, int);
|
||||
void uart1_puts(const char *str, int size);
|
||||
void uart1_gets(char *str, int size);
|
||||
void uart1_putc(char ch);
|
||||
|
||||
void uart1_clear_queue(void);
|
||||
#endif
|
||||
/*
|
||||
* (C) Copyright 2007 Catalin Patulea <cat@vv.carleton.ca>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
void uart_init(void);
|
||||
bool uart1_available(void);
|
||||
|
||||
int uart1_gets_queue(char *, int);
|
||||
void uart1_puts(const char *str, int size);
|
||||
void uart1_gets(char *str, int size);
|
||||
void uart1_putc(char ch);
|
||||
|
||||
void uart1_clear_queue(void);
|
||||
#endif
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
@ -1,2 +1,2 @@
|
|||
SUBDIRS = rbutilqt
|
||||
SUBDIRS = rbutilqt
|
||||
TEMPLATE = subdirs
|
|
@ -1,25 +1,25 @@
|
|||
CFLAGS=-Wall -W -D_LARGEFILE64_SOURCE
|
||||
|
||||
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
|
||||
CROSS=
|
||||
CFLAGS+=-mno-cygwin
|
||||
else
|
||||
ifeq ($(findstring MINGW,$(shell uname)),MINGW)
|
||||
CROSS=
|
||||
else
|
||||
CROSS=i586-mingw32msvc-
|
||||
endif
|
||||
endif
|
||||
|
||||
NATIVECC = gcc
|
||||
CC = $(CROSS)gcc
|
||||
WINDRES = $(CROSS)windres
|
||||
|
||||
|
||||
all: bin2c
|
||||
|
||||
bin2c: bin2c.c
|
||||
$(NATIVECC) $(CFLAGS) -o bin2c bin2c.c
|
||||
|
||||
clean:
|
||||
$(RM) bin2c bin2c.exe
|
||||
CFLAGS=-Wall -W -D_LARGEFILE64_SOURCE
|
||||
|
||||
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
|
||||
CROSS=
|
||||
CFLAGS+=-mno-cygwin
|
||||
else
|
||||
ifeq ($(findstring MINGW,$(shell uname)),MINGW)
|
||||
CROSS=
|
||||
else
|
||||
CROSS=i586-mingw32msvc-
|
||||
endif
|
||||
endif
|
||||
|
||||
NATIVECC = gcc
|
||||
CC = $(CROSS)gcc
|
||||
WINDRES = $(CROSS)windres
|
||||
|
||||
|
||||
all: bin2c
|
||||
|
||||
bin2c: bin2c.c
|
||||
$(NATIVECC) $(CFLAGS) -o bin2c bin2c.c
|
||||
|
||||
clean:
|
||||
$(RM) bin2c bin2c.exe
|
||||
|
|
|
@ -1,232 +1,232 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2009, Dave Chapman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "mtp_common.h"
|
||||
|
||||
#include "../MTP_DLL/MTP_DLL.h"
|
||||
|
||||
|
||||
static int filesize(const char* filename);
|
||||
|
||||
|
||||
int mtp_init(struct mtp_info_t* mtp_info)
|
||||
{
|
||||
/* Fill the info struct with zeros - mainly for the strings */
|
||||
memset(mtp_info, 0, sizeof(struct mtp_info_t));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int mtp_finished(struct mtp_info_t* mtp_info)
|
||||
{
|
||||
(void)mtp_info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtp_scan(struct mtp_info_t* mtp_info)
|
||||
{
|
||||
wchar_t name[256];
|
||||
wchar_t manufacturer[256];
|
||||
DWORD version;
|
||||
int num = 0;
|
||||
|
||||
num = mtp_description(name, manufacturer, &version);
|
||||
|
||||
wcstombs(mtp_info->manufacturer, manufacturer, 200);
|
||||
wcstombs(mtp_info->modelname, name, 200);
|
||||
|
||||
sprintf(mtp_info->version, "%x", (unsigned int)version);
|
||||
return (num > 0) ? num : -1;
|
||||
|
||||
}
|
||||
|
||||
static void callback(unsigned int progress, unsigned int max)
|
||||
{
|
||||
int percent = (progress * 100) / max;
|
||||
|
||||
printf("[INFO] Progress: %u of %u (%d%%)\r", progress, max, percent);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
int mtp_send_firmware(struct mtp_info_t* mtp_info, unsigned char* fwbuf,
|
||||
int fwsize)
|
||||
{
|
||||
HANDLE hTempFile;
|
||||
DWORD dwRetVal;
|
||||
DWORD dwBytesWritten;
|
||||
UINT uRetVal;
|
||||
TCHAR szTempName[1024];
|
||||
TCHAR lpPathBuffer[1024];
|
||||
BOOL fSuccess;
|
||||
wchar_t *tmp;
|
||||
int ret;
|
||||
|
||||
(void)mtp_info;
|
||||
|
||||
/* Get the path for temporary files */
|
||||
dwRetVal = GetTempPath(sizeof(lpPathBuffer), lpPathBuffer);
|
||||
if (dwRetVal > sizeof(lpPathBuffer) || (dwRetVal == 0))
|
||||
{
|
||||
fprintf(stderr, "[ERR] GetTempPath failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create the temporary file */
|
||||
uRetVal = GetTempFileName(lpPathBuffer, TEXT("NKBIN"), 0, szTempName);
|
||||
if (uRetVal == 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] GetTempFileName failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now create the file */
|
||||
hTempFile = CreateFile((LPTSTR) szTempName, // file name
|
||||
GENERIC_READ | GENERIC_WRITE, // open r-w
|
||||
0, // do not share
|
||||
NULL, // default security
|
||||
CREATE_ALWAYS, // overwrite existing
|
||||
FILE_ATTRIBUTE_NORMAL,// normal file
|
||||
NULL); // no template
|
||||
if (hTempFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Could not create %s\n", szTempName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fSuccess = WriteFile(hTempFile, fwbuf, fwsize, &dwBytesWritten, NULL);
|
||||
if (!fSuccess)
|
||||
{
|
||||
fprintf(stderr, "[ERR] WriteFile failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
fSuccess = CloseHandle (hTempFile);
|
||||
if (!fSuccess)
|
||||
{
|
||||
fprintf(stderr, "[ERR] CloseHandle failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp = (LPWSTR)malloc(_tcslen(szTempName)*2+1);
|
||||
mbstowcs(tmp, (char*)szTempName, _tcslen(szTempName)*2+1);
|
||||
|
||||
fprintf(stderr, "[INFO] Sending firmware...\n");
|
||||
if (mtp_sendnk(tmp, fwsize, &callback))
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "[INFO] Firmware sent successfully\n");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "[ERR] Error occured during sending.\n");
|
||||
ret = -1;
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
if (!DeleteFile(szTempName))
|
||||
fprintf(stderr,"[WARN] Could not remove temporary file %s\n",szTempName);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int mtp_send_file(struct mtp_info_t* mtp_info, const char* filename)
|
||||
{
|
||||
wchar_t *fn;
|
||||
|
||||
fn = (LPWSTR)malloc(strlen(filename)*2+1);
|
||||
mbstowcs(fn, filename, strlen(filename)*2+1);
|
||||
|
||||
if (mtp_init(mtp_info) < 0) {
|
||||
fprintf(stderr,"[ERR] Can not init MTP\n");
|
||||
return 1;
|
||||
}
|
||||
/* Scan for attached MTP devices. */
|
||||
if (mtp_scan(mtp_info) < 0)
|
||||
{
|
||||
fprintf(stderr,"[ERR] No devices found\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Sending firmware...\n");
|
||||
if (mtp_sendnk(fn, filesize(filename), &callback))
|
||||
{
|
||||
/* keep progress on screen */
|
||||
printf("\n");
|
||||
fprintf(stderr, "[INFO] Firmware sent successfully\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[ERR] Error occured during sending.\n");
|
||||
return -1;
|
||||
}
|
||||
mtp_finished(mtp_info);
|
||||
}
|
||||
|
||||
|
||||
static int filesize(const char* filename)
|
||||
{
|
||||
struct _stat sb;
|
||||
int res;
|
||||
|
||||
res = _stat(filename, &sb);
|
||||
if(res == -1) {
|
||||
fprintf(stderr, "Error getting filesize!\n");
|
||||
return -1;
|
||||
}
|
||||
return sb.st_size;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2009, Dave Chapman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "mtp_common.h"
|
||||
|
||||
#include "../MTP_DLL/MTP_DLL.h"
|
||||
|
||||
|
||||
static int filesize(const char* filename);
|
||||
|
||||
|
||||
int mtp_init(struct mtp_info_t* mtp_info)
|
||||
{
|
||||
/* Fill the info struct with zeros - mainly for the strings */
|
||||
memset(mtp_info, 0, sizeof(struct mtp_info_t));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int mtp_finished(struct mtp_info_t* mtp_info)
|
||||
{
|
||||
(void)mtp_info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtp_scan(struct mtp_info_t* mtp_info)
|
||||
{
|
||||
wchar_t name[256];
|
||||
wchar_t manufacturer[256];
|
||||
DWORD version;
|
||||
int num = 0;
|
||||
|
||||
num = mtp_description(name, manufacturer, &version);
|
||||
|
||||
wcstombs(mtp_info->manufacturer, manufacturer, 200);
|
||||
wcstombs(mtp_info->modelname, name, 200);
|
||||
|
||||
sprintf(mtp_info->version, "%x", (unsigned int)version);
|
||||
return (num > 0) ? num : -1;
|
||||
|
||||
}
|
||||
|
||||
static void callback(unsigned int progress, unsigned int max)
|
||||
{
|
||||
int percent = (progress * 100) / max;
|
||||
|
||||
printf("[INFO] Progress: %u of %u (%d%%)\r", progress, max, percent);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
int mtp_send_firmware(struct mtp_info_t* mtp_info, unsigned char* fwbuf,
|
||||
int fwsize)
|
||||
{
|
||||
HANDLE hTempFile;
|
||||
DWORD dwRetVal;
|
||||
DWORD dwBytesWritten;
|
||||
UINT uRetVal;
|
||||
TCHAR szTempName[1024];
|
||||
TCHAR lpPathBuffer[1024];
|
||||
BOOL fSuccess;
|
||||
wchar_t *tmp;
|
||||
int ret;
|
||||
|
||||
(void)mtp_info;
|
||||
|
||||
/* Get the path for temporary files */
|
||||
dwRetVal = GetTempPath(sizeof(lpPathBuffer), lpPathBuffer);
|
||||
if (dwRetVal > sizeof(lpPathBuffer) || (dwRetVal == 0))
|
||||
{
|
||||
fprintf(stderr, "[ERR] GetTempPath failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create the temporary file */
|
||||
uRetVal = GetTempFileName(lpPathBuffer, TEXT("NKBIN"), 0, szTempName);
|
||||
if (uRetVal == 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] GetTempFileName failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now create the file */
|
||||
hTempFile = CreateFile((LPTSTR) szTempName, // file name
|
||||
GENERIC_READ | GENERIC_WRITE, // open r-w
|
||||
0, // do not share
|
||||
NULL, // default security
|
||||
CREATE_ALWAYS, // overwrite existing
|
||||
FILE_ATTRIBUTE_NORMAL,// normal file
|
||||
NULL); // no template
|
||||
if (hTempFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Could not create %s\n", szTempName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fSuccess = WriteFile(hTempFile, fwbuf, fwsize, &dwBytesWritten, NULL);
|
||||
if (!fSuccess)
|
||||
{
|
||||
fprintf(stderr, "[ERR] WriteFile failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
fSuccess = CloseHandle (hTempFile);
|
||||
if (!fSuccess)
|
||||
{
|
||||
fprintf(stderr, "[ERR] CloseHandle failed (%d)\n", (int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp = (LPWSTR)malloc(_tcslen(szTempName)*2+1);
|
||||
mbstowcs(tmp, (char*)szTempName, _tcslen(szTempName)*2+1);
|
||||
|
||||
fprintf(stderr, "[INFO] Sending firmware...\n");
|
||||
if (mtp_sendnk(tmp, fwsize, &callback))
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "[INFO] Firmware sent successfully\n");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "[ERR] Error occured during sending.\n");
|
||||
ret = -1;
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
if (!DeleteFile(szTempName))
|
||||
fprintf(stderr,"[WARN] Could not remove temporary file %s\n",szTempName);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int mtp_send_file(struct mtp_info_t* mtp_info, const char* filename)
|
||||
{
|
||||
wchar_t *fn;
|
||||
|
||||
fn = (LPWSTR)malloc(strlen(filename)*2+1);
|
||||
mbstowcs(fn, filename, strlen(filename)*2+1);
|
||||
|
||||
if (mtp_init(mtp_info) < 0) {
|
||||
fprintf(stderr,"[ERR] Can not init MTP\n");
|
||||
return 1;
|
||||
}
|
||||
/* Scan for attached MTP devices. */
|
||||
if (mtp_scan(mtp_info) < 0)
|
||||
{
|
||||
fprintf(stderr,"[ERR] No devices found\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Sending firmware...\n");
|
||||
if (mtp_sendnk(fn, filesize(filename), &callback))
|
||||
{
|
||||
/* keep progress on screen */
|
||||
printf("\n");
|
||||
fprintf(stderr, "[INFO] Firmware sent successfully\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[ERR] Error occured during sending.\n");
|
||||
return -1;
|
||||
}
|
||||
mtp_finished(mtp_info);
|
||||
}
|
||||
|
||||
|
||||
static int filesize(const char* filename)
|
||||
{
|
||||
struct _stat sb;
|
||||
int res;
|
||||
|
||||
res = _stat(filename, &sb);
|
||||
if(res == -1) {
|
||||
fprintf(stderr, "Error getting filesize!\n");
|
||||
return -1;
|
||||
}
|
||||
return sb.st_size;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,87 +1,87 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <stdbool.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "MTP_DLL/MTP_DLL.h"
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: sendfirm <local filename>\n");
|
||||
}
|
||||
|
||||
int filesize(char* filename)
|
||||
{
|
||||
FILE* fd;
|
||||
int tmp;
|
||||
fd = fopen(filename, "r");
|
||||
if(fd == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error while opening %s!\n", filename);
|
||||
return -1;
|
||||
}
|
||||
fseek(fd, 0, SEEK_END);
|
||||
tmp = ftell(fd);
|
||||
fclose(fd);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void callback(unsigned int progress, unsigned int max)
|
||||
{
|
||||
unsigned int normalized = progress*1000/max;
|
||||
printf("Progress: %d.%d%%\r", normalized/10, normalized%10);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
wchar_t *tmp;
|
||||
|
||||
tmp = (LPWSTR)malloc(strlen(argv[1])*2+1);
|
||||
mbstowcs(tmp, argv[1], strlen(argv[1])*2+1);
|
||||
|
||||
wprintf(tmp);
|
||||
printf("\n");
|
||||
|
||||
fprintf(stdout, "Sending firmware...\n");
|
||||
|
||||
if(mtp_sendnk(tmp, filesize(argv[1]), &callback))
|
||||
fprintf(stdout, "Firmware sent successfully!\n");
|
||||
else
|
||||
fprintf(stdout, "Error occured during sending!\n");
|
||||
|
||||
free(tmp);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <stdbool.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "MTP_DLL/MTP_DLL.h"
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: sendfirm <local filename>\n");
|
||||
}
|
||||
|
||||
int filesize(char* filename)
|
||||
{
|
||||
FILE* fd;
|
||||
int tmp;
|
||||
fd = fopen(filename, "r");
|
||||
if(fd == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error while opening %s!\n", filename);
|
||||
return -1;
|
||||
}
|
||||
fseek(fd, 0, SEEK_END);
|
||||
tmp = ftell(fd);
|
||||
fclose(fd);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void callback(unsigned int progress, unsigned int max)
|
||||
{
|
||||
unsigned int normalized = progress*1000/max;
|
||||
printf("Progress: %d.%d%%\r", normalized/10, normalized%10);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
wchar_t *tmp;
|
||||
|
||||
tmp = (LPWSTR)malloc(strlen(argv[1])*2+1);
|
||||
mbstowcs(tmp, argv[1], strlen(argv[1])*2+1);
|
||||
|
||||
wprintf(tmp);
|
||||
printf("\n");
|
||||
|
||||
fprintf(stdout, "Sending firmware...\n");
|
||||
|
||||
if(mtp_sendnk(tmp, filesize(argv[1]), &callback))
|
||||
fprintf(stdout, "Firmware sent successfully!\n");
|
||||
else
|
||||
fprintf(stdout, "Error occured during sending!\n");
|
||||
|
||||
free(tmp);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -1,423 +1,423 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ULONG uint32_t
|
||||
#define UCHAR uint8_t
|
||||
|
||||
#define FRMT "0x%x" // "0x%x"
|
||||
#define SHFTFRMC "%s %s #%d" // "%s %s %d"
|
||||
#define SHFTFRMR "%s %s %s" // "%s %s %s"
|
||||
//#define FRMT "0x%x"
|
||||
//#define SHFTFRMC "%s %s %d"
|
||||
//#define SHFTFRMR "%s %s %s"
|
||||
|
||||
char *cond[16] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "", "nv" };
|
||||
char *cnd1[16] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", " ", "nv" };
|
||||
char *opcd[16] = {"and","eor","sub","rsb","add","adc","sbc","rsc","tst","teq","cmp","cmn","orr","mov","bic","mvn" };
|
||||
char setc[32] = {0,115,0,115,0,115,0,115,0,115,0,115,0,115,0,115,0, 0 ,0, 0 ,0, 0 ,0, 0 ,0,115,0,115,0,115,0,115 };
|
||||
char *regs[16] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" };
|
||||
|
||||
char *shfts[4] = { "lsl", "lsr", "asr", "ror" };
|
||||
|
||||
/*
|
||||
31-28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
Cond 0 0 I ---Opcode--- S |----Rn----- ----Rd----- --------Operand 2-------- Data Processing /PSR Transfer
|
||||
Cond 0 0 0 0 | 0 0 A S |----Rd----- ----Rn----- ---Rs---- 1 0 0 1 --Rm--- Multiply
|
||||
Cond 0 0 0 0 | 1 U A S |---RdHi---- ---RdLo---- ---Rn---- 1 0 0 1 --Rm--- Multiply Long
|
||||
Cond 0 0 0 1 | 0 B 0 0 |----Rn----- ----Rd----- 0 0 0 0 1 0 0 1 --Rm--- Single Data Swap
|
||||
Cond 0 0 0 1 | 0 0 1 0 |1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 --Rn--- Branch and Exchange
|
||||
Cond 0 0 0 P | U 0 W L |----Rn----- ----Rd----- 0 0 0 0 1 S H 1 --Rm--- Halfword Data Transfer: register offset
|
||||
Cond 0 0 0 P | U 1 W L |----Rn----- ----Rd----- --Offset- 1 S H 1 -Offset Halfword Data Transfer: immediate offset
|
||||
Cond 0 1 I P | U B W L |----Rn----- ----Rd----- --------Offset----------- Single Data Transfer
|
||||
Cond 0 1 1 1 | x x x x |x x x x x x x x x x x x x x x 1 x x x x Undefined
|
||||
Cond 1 0 0 P | U S W L |----Rn----- -----------Register List------------- Block Data Transfer
|
||||
Cond 1 0 1 L | -------------------------Offset------------------------------ Branch
|
||||
Cond 1 1 0 P | U N W L |----Rn----- ----CRd---- ---CP#--- -----Offset---- Coprocessor Data Transfer
|
||||
Cond 1 1 1 0 | --CP Opc---|----CRn---- ----CRd---- ---CP#--- -CP-- 0 --CRm-- Coprocessor Data Operation
|
||||
Cond 1 1 1 0 | CP Opc L |----CRn---- ----Rd----- ---CP#--- -CP-- 1 --CRm-- Coprocessor Register Transfer
|
||||
Cond 1 1 1 1 | x x x x |x x x x x x x x x x x x x x x x x x x x Software Interrupt
|
||||
|
||||
0x04200000
|
||||
0001 0 0 0 0 0 1 1 0 6 e 1 1 1 0 1 8
|
||||
================================================================================
|
||||
Cond 0 1 I P | U B W L |----Rn----- ----Rd----- --------Offset----------- Single Data Transfer
|
||||
|
||||
|
||||
EQ 0 Z set equal
|
||||
NE 1 Z clear not equal
|
||||
CS 2 C set unsigned higher or same
|
||||
CC 3 C clear unsigned lower
|
||||
MI 4 N set negative
|
||||
PL 5 N clear positive or zero
|
||||
VS 6 V set overflow
|
||||
VC 7 V clear no overflow
|
||||
HI 8 C set and Z clear unsigned higher
|
||||
LS 9 C clear or Z set unsigned lower or same
|
||||
GE A N equals V greater or equal
|
||||
LT B N not equal to V less than
|
||||
GT C Z clear AND (N equals V) greater than
|
||||
LE D Z set OR (N not equal to V) less than or equal
|
||||
AL E (ignored) always
|
||||
|
||||
AND 0 operand1 AND operand2
|
||||
EOR 1 operand1 EOR operand2
|
||||
SUB 2 operand1 - operand2
|
||||
RSB 3 operand2 - operand1
|
||||
ADD 4 operand1 + operand2
|
||||
ADC 5 operand1 + operand2 + carry
|
||||
SBC 6 operand1 - operand2 + carry - 1
|
||||
RSC 7 operand2 - operand1 + carry - 1
|
||||
TST 8 AND, but result is not written
|
||||
TEQ 9 as EOR, but result is not written
|
||||
CMP A as SUB, but result is not written
|
||||
CMN B as ADD, but result is not written
|
||||
ORR C operand1 OR operand2
|
||||
MOV D operand2 (operand1 is ignored)
|
||||
BIC E operand1 AND NOT operand2 (Bit clear)
|
||||
MVN F NOT operand2 (operand1 is ignored)
|
||||
*/
|
||||
|
||||
void multiply_stg(char *stg, ULONG val)
|
||||
{
|
||||
if((val&0xc00000) == 0) // simple mul
|
||||
{
|
||||
if(val & 0x100000) // set condition flags
|
||||
if(val & 0x200000) sprintf(stg+strlen(stg), "mla%ss ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "mul%ss ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x200000) sprintf(stg+strlen(stg), "mla%s ", cnd1[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "mul%s ", cnd1[val>>28]);
|
||||
|
||||
if(val & 0x200000) // accumulate
|
||||
sprintf(stg+strlen(stg), "%s, %s, %s, %s", regs[(val>>16)&15], regs[(val>>0)&15], regs[(val>>8)&15], regs[(val>>12)&15]);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, %s, %s", regs[(val>>16)&15], regs[(val>>0)&15], regs[(val>>8)&15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(val & 0x100000) // set condition flags
|
||||
if(val & 0x200000) // accumulate
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smlal%ss ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umlal%ss ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smull%ss ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umull%ss ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x200000)
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smlal%s ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umlal%s ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smull%s ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umull%s ", cond[val>>28]);
|
||||
|
||||
sprintf(stg+strlen(stg), "%s, %s, %s, %s", regs[(val>>12)&15], regs[(val>>16)&15], regs[(val>>0)&15], regs[(val>>8)&15]);
|
||||
}
|
||||
}
|
||||
|
||||
void halfword_stg(char *stg, ULONG val)
|
||||
{
|
||||
ULONG off = ((val>>4) & 0xf0) + (val & 0x0f);
|
||||
|
||||
if(val & 0x100000) sprintf(stg+strlen(stg), "ldr%s", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "str%s", cond[val>>28]);
|
||||
|
||||
switch((val>>5) & 3) // SWP, HW, SB, SH
|
||||
{
|
||||
case 0: sprintf(stg+strlen(stg), "error: SWP"); break;
|
||||
case 1: sprintf(stg+strlen(stg), "h "); break;
|
||||
case 2: sprintf(stg+strlen(stg), "sb "); break;
|
||||
case 3: sprintf(stg+strlen(stg), "sh "); break;
|
||||
}
|
||||
|
||||
if(val & 0x400000) // immidiate offset
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' on post indexed");
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s], "FRMT, regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s], -"FRMT, regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, %s]!", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -%s]!", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, %s]", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -%s]", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' on post indexed");
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s], %s", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s], -%s", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
}
|
||||
|
||||
void branch_stg(char *stg, ULONG val, ULONG pos)
|
||||
{
|
||||
ULONG off = pos + (((int32_t)val << 8) >> 6) + 8;
|
||||
|
||||
if((val & 0x0ffffff0) == 0x012fff10) // bx instruction
|
||||
{ sprintf(stg+strlen(stg), "bx%s %s", cond[val>>28], regs[val&15]); }
|
||||
else
|
||||
{
|
||||
if(((val>>24)&15) == 10) sprintf(stg+strlen(stg), "b%s ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "bl%s ", cond[val>>28]);
|
||||
|
||||
sprintf(stg+strlen(stg), "0x%x", off);
|
||||
}
|
||||
}
|
||||
|
||||
void opcode_stg(char *stg, ULONG val, ULONG off)
|
||||
{
|
||||
ULONG des, op1;
|
||||
char op2[80];
|
||||
char *st = stg + strlen(stg);
|
||||
|
||||
if(((val & 0x0ffffff0) == 0x012fff10) && (val & 16))
|
||||
{ branch_stg(stg, val, off); return; }
|
||||
else if(((val & 0x0f000000) == 0x00000000) && ((val & 0xf0) == 0x90))
|
||||
{ multiply_stg(stg, val); return; }
|
||||
else if(((val & 0x0f000000) <= 0x01000000) && ((val & 0x90) == 0x90) && ((val & 0xf0) > 0x90) && ((val & 0x01200000) != 0x00200000))
|
||||
{ halfword_stg(stg, val); return; }
|
||||
|
||||
sprintf(stg+strlen(stg), "%s%s%s ", opcd[(val>>21) & 15], cond[val>>28], setc[(val>>20) & 31]?"s":" ");
|
||||
|
||||
des = (val>>12) & 15;
|
||||
op1 = (val>>16) & 15;
|
||||
|
||||
if(val & 0x2000000) // immidiate
|
||||
{
|
||||
off = (ULONG)((uint64_t)(val&0xff) << (32 - 2 * ((val >> 8) & 15))) | ((val&0xff) >> 2 * ((val >> 8) & 15));
|
||||
sprintf(op2, FRMT" ", off);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(val & 16) // shift type
|
||||
sprintf(op2, SHFTFRMR, regs[val&15], shfts[(val>>5)&3], regs[(val>>8)&15]);
|
||||
else
|
||||
if((val>>7) & 31)
|
||||
sprintf(op2, SHFTFRMC, regs[val&15], shfts[(val>>5)&3], (val>>7) & 31);
|
||||
else
|
||||
sprintf(op2, "%s ", regs[val&15]);
|
||||
}
|
||||
|
||||
switch((val>>21) & 15)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 12:
|
||||
case 14: sprintf(stg+strlen(stg), "%s, %s, %s", regs[des], regs[op1], op2); break;
|
||||
|
||||
case 8: case 9: case 10:
|
||||
case 11: if(val & 0x100000) // set status
|
||||
sprintf(stg+strlen(stg), "%s, %s", regs[op1], op2); // standard TEQ,TST,CMP,CMN
|
||||
else
|
||||
{ //special MRS/MSR opcodes
|
||||
if((((val>>23) & 31) == 2) && ((val & 0x3f0fff) == 0x0f0000))
|
||||
{ sprintf(st, "mrs%s %s, %s", cnd1[val>>28], regs[des], val&0x400000?"SPSR_xx":"CPSR"); }
|
||||
else
|
||||
if((((val>>23) & 31) == 2) && ((val & 0x30fff0) == 0x20f000))
|
||||
{ sprintf(st, "msr%s %s, %s", cnd1[val>>28], val&0x400000?"SPSR_xx":"CPSR", regs[val&15]); }
|
||||
else
|
||||
if((((val>>23) & 31) == 6) && ((val & 0x30f000) == 0x20f000))
|
||||
{ sprintf(st, "msr%s %s, %s", cnd1[val>>28], val&0x400000?"SPSR_xx":"CPSR_cf", op2); }
|
||||
else
|
||||
if((((val>>23) & 31) == 2) && ((val & 0x300ff0) == 0x000090))
|
||||
{ sprintf(st, "swp%s%s %s, %s, [%s]", val&0x400000?"b":"", cnd1[val>>28], regs[(val>>12)&15], regs[val&15], regs[(val>>16)&15]); }
|
||||
else
|
||||
{ sprintf(stg+strlen(stg), "??????????????"); }
|
||||
} break;
|
||||
case 13:
|
||||
case 15: sprintf(stg+strlen(stg), "%s, %s", regs[des], op2); break;
|
||||
}
|
||||
}
|
||||
|
||||
void opcode_cop(char *stg, ULONG val, ULONG off)
|
||||
{
|
||||
char* op;
|
||||
int opcode1 = (val >> 21) & 0x7;
|
||||
int CRn = (val >> 16) & 0xf;
|
||||
int Rd = (val >> 12) & 0xf;
|
||||
int cp_num = (val >> 8) & 0xf;
|
||||
int opcode2 = (val >> 5) & 0x7;
|
||||
int CRm = val & 0xf;
|
||||
|
||||
|
||||
// ee073f5e mcr 15, 0, r3, cr7, cr14, {2}
|
||||
|
||||
if (val & (1<<4)) {
|
||||
if (val & (1<<20)) {
|
||||
op = "mrc";
|
||||
} else {
|
||||
op = "mcr";
|
||||
}
|
||||
opcode1 = (val >> 21) & 0x7;
|
||||
CRn = (val >> 16) & 0xf;
|
||||
Rd = (val >> 12) & 0xf;
|
||||
cp_num = (val >> 8) & 0xf;
|
||||
opcode2 = (val >> 5) & 0x7;
|
||||
CRm = val & 0xf;
|
||||
|
||||
sprintf(stg+strlen(stg), "%s%s %d, %d, r%d, cr%d, cr%d, {%d}", op, cnd1[val>>28], cp_num, opcode1, Rd, CRn, CRm, opcode2);
|
||||
} else {
|
||||
op = "cdp";
|
||||
|
||||
opcode1 = (val >> 20) & 0xf;
|
||||
CRn = (val >> 16) & 0xf;
|
||||
Rd = (val >> 12) & 0xf;
|
||||
cp_num = (val >> 8) & 0xf;
|
||||
opcode2 = (val >> 5) & 0x7;
|
||||
CRm = val & 0xf;
|
||||
|
||||
sprintf(stg+strlen(stg), "%s%s %d, %d, cr%d, cr%d, cr%d, {%d}", op, cnd1[val>>28], cp_num, opcode1, Rd, CRn, CRm, opcode2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void single_data(char *stg, ULONG val)
|
||||
{
|
||||
char op2[80];
|
||||
|
||||
if(((val & 0x0e000000) == 0x06000000) && (val & 16))
|
||||
{ sprintf(stg+strlen(stg), "undef%s", cond[val>>28]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(val & 0x400000)
|
||||
if(val & 0x100000) sprintf(stg+strlen(stg), "ldr%sb ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "str%sb ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x100000) sprintf(stg+strlen(stg), "ldr%s ", cnd1[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "str%s ", cnd1[val>>28]);
|
||||
|
||||
if(val & 0x2000000) {// reg offset
|
||||
if(val & 16) // shift type
|
||||
sprintf(op2, "error: reg defined shift");
|
||||
else
|
||||
if((val>>7) & 31)
|
||||
sprintf(op2, SHFTFRMC, regs[val&15], shfts[(val>>5)&3], (val>>7) & 31);
|
||||
else
|
||||
sprintf(op2, "%s", regs[val&15]);
|
||||
}
|
||||
|
||||
if(val & 0x2000000) // reg offset
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x800000) // up offset (+)
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "%s, [%s, %s]!", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, [%s, %s]", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "%s, [%s, -%s]!", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, [%s, -%s]", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' set");
|
||||
else
|
||||
if(val & 0x800000) // up offset (+)
|
||||
sprintf(stg+strlen(stg), "%s, [%s], %s", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, [%s], -%s", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x800000) // up offset (+)
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]!", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]!", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' set");
|
||||
else
|
||||
if(val & 0x800000) // up offset (+)
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s], "FRMT, regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s], -"FRMT, regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
}
|
||||
|
||||
void block_data(char *stg, ULONG val)
|
||||
{
|
||||
char lst[80];
|
||||
int i;
|
||||
|
||||
strcpy(lst, "{");
|
||||
for(i=0; i<16; i++)
|
||||
if(val & (1<<i))
|
||||
sprintf(lst+strlen(lst), "%s, ", regs[i]);
|
||||
if(strlen(lst)>2)
|
||||
strcpy(lst+strlen(lst)-2, "}");
|
||||
else
|
||||
strcpy(lst+strlen(lst), "}");
|
||||
|
||||
if(val & 0x400000) // load psr or force user mode
|
||||
strcpy(lst+strlen(lst), "^");
|
||||
|
||||
|
||||
if(val & 0x100000) // load
|
||||
if(val & 0x1000000) // pre offset
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "ldm%sib ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "ldm%sdb ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "ldm%sia ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "ldm%sda ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x1000000)
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "stm%sib ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "stm%sdb ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "stm%sia ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "stm%sda ", cond[val>>28]);
|
||||
|
||||
switch((val>>21)&3)
|
||||
{
|
||||
case 0: sprintf(stg+strlen(stg), "%s, %s", regs[(val>>16)&15], lst); break;
|
||||
case 1: sprintf(stg+strlen(stg), "%s!, %s", regs[(val>>16)&15], lst); break;
|
||||
case 2: sprintf(stg+strlen(stg), "%s, %s", regs[(val>>16)&15], lst); break;
|
||||
case 3: sprintf(stg+strlen(stg), "%s!, %s", regs[(val>>16)&15], lst); break;
|
||||
}
|
||||
}
|
||||
|
||||
void dis_asm(ULONG off, ULONG val, char *stg)
|
||||
{
|
||||
sprintf(stg, "%6x: %08x ", off, val);
|
||||
|
||||
switch((val >> 24) & 15)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: opcode_stg(stg, val, off); break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7: single_data(stg, val); break;
|
||||
case 8:
|
||||
case 9: block_data(stg, val); break;
|
||||
case 10:
|
||||
case 11: branch_stg(stg, val, off); break;
|
||||
case 12:
|
||||
case 13: sprintf(stg+strlen(stg), "cop%s", cnd1[val>>28]); break;
|
||||
case 14: opcode_cop(stg, val, off); break;
|
||||
case 15: sprintf(stg+strlen(stg), "swi%s", cnd1[val>>28]); break;
|
||||
}
|
||||
}
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ULONG uint32_t
|
||||
#define UCHAR uint8_t
|
||||
|
||||
#define FRMT "0x%x" // "0x%x"
|
||||
#define SHFTFRMC "%s %s #%d" // "%s %s %d"
|
||||
#define SHFTFRMR "%s %s %s" // "%s %s %s"
|
||||
//#define FRMT "0x%x"
|
||||
//#define SHFTFRMC "%s %s %d"
|
||||
//#define SHFTFRMR "%s %s %s"
|
||||
|
||||
char *cond[16] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "", "nv" };
|
||||
char *cnd1[16] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", " ", "nv" };
|
||||
char *opcd[16] = {"and","eor","sub","rsb","add","adc","sbc","rsc","tst","teq","cmp","cmn","orr","mov","bic","mvn" };
|
||||
char setc[32] = {0,115,0,115,0,115,0,115,0,115,0,115,0,115,0,115,0, 0 ,0, 0 ,0, 0 ,0, 0 ,0,115,0,115,0,115,0,115 };
|
||||
char *regs[16] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" };
|
||||
|
||||
char *shfts[4] = { "lsl", "lsr", "asr", "ror" };
|
||||
|
||||
/*
|
||||
31-28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
Cond 0 0 I ---Opcode--- S |----Rn----- ----Rd----- --------Operand 2-------- Data Processing /PSR Transfer
|
||||
Cond 0 0 0 0 | 0 0 A S |----Rd----- ----Rn----- ---Rs---- 1 0 0 1 --Rm--- Multiply
|
||||
Cond 0 0 0 0 | 1 U A S |---RdHi---- ---RdLo---- ---Rn---- 1 0 0 1 --Rm--- Multiply Long
|
||||
Cond 0 0 0 1 | 0 B 0 0 |----Rn----- ----Rd----- 0 0 0 0 1 0 0 1 --Rm--- Single Data Swap
|
||||
Cond 0 0 0 1 | 0 0 1 0 |1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 --Rn--- Branch and Exchange
|
||||
Cond 0 0 0 P | U 0 W L |----Rn----- ----Rd----- 0 0 0 0 1 S H 1 --Rm--- Halfword Data Transfer: register offset
|
||||
Cond 0 0 0 P | U 1 W L |----Rn----- ----Rd----- --Offset- 1 S H 1 -Offset Halfword Data Transfer: immediate offset
|
||||
Cond 0 1 I P | U B W L |----Rn----- ----Rd----- --------Offset----------- Single Data Transfer
|
||||
Cond 0 1 1 1 | x x x x |x x x x x x x x x x x x x x x 1 x x x x Undefined
|
||||
Cond 1 0 0 P | U S W L |----Rn----- -----------Register List------------- Block Data Transfer
|
||||
Cond 1 0 1 L | -------------------------Offset------------------------------ Branch
|
||||
Cond 1 1 0 P | U N W L |----Rn----- ----CRd---- ---CP#--- -----Offset---- Coprocessor Data Transfer
|
||||
Cond 1 1 1 0 | --CP Opc---|----CRn---- ----CRd---- ---CP#--- -CP-- 0 --CRm-- Coprocessor Data Operation
|
||||
Cond 1 1 1 0 | CP Opc L |----CRn---- ----Rd----- ---CP#--- -CP-- 1 --CRm-- Coprocessor Register Transfer
|
||||
Cond 1 1 1 1 | x x x x |x x x x x x x x x x x x x x x x x x x x Software Interrupt
|
||||
|
||||
0x04200000
|
||||
0001 0 0 0 0 0 1 1 0 6 e 1 1 1 0 1 8
|
||||
================================================================================
|
||||
Cond 0 1 I P | U B W L |----Rn----- ----Rd----- --------Offset----------- Single Data Transfer
|
||||
|
||||
|
||||
EQ 0 Z set equal
|
||||
NE 1 Z clear not equal
|
||||
CS 2 C set unsigned higher or same
|
||||
CC 3 C clear unsigned lower
|
||||
MI 4 N set negative
|
||||
PL 5 N clear positive or zero
|
||||
VS 6 V set overflow
|
||||
VC 7 V clear no overflow
|
||||
HI 8 C set and Z clear unsigned higher
|
||||
LS 9 C clear or Z set unsigned lower or same
|
||||
GE A N equals V greater or equal
|
||||
LT B N not equal to V less than
|
||||
GT C Z clear AND (N equals V) greater than
|
||||
LE D Z set OR (N not equal to V) less than or equal
|
||||
AL E (ignored) always
|
||||
|
||||
AND 0 operand1 AND operand2
|
||||
EOR 1 operand1 EOR operand2
|
||||
SUB 2 operand1 - operand2
|
||||
RSB 3 operand2 - operand1
|
||||
ADD 4 operand1 + operand2
|
||||
ADC 5 operand1 + operand2 + carry
|
||||
SBC 6 operand1 - operand2 + carry - 1
|
||||
RSC 7 operand2 - operand1 + carry - 1
|
||||
TST 8 AND, but result is not written
|
||||
TEQ 9 as EOR, but result is not written
|
||||
CMP A as SUB, but result is not written
|
||||
CMN B as ADD, but result is not written
|
||||
ORR C operand1 OR operand2
|
||||
MOV D operand2 (operand1 is ignored)
|
||||
BIC E operand1 AND NOT operand2 (Bit clear)
|
||||
MVN F NOT operand2 (operand1 is ignored)
|
||||
*/
|
||||
|
||||
void multiply_stg(char *stg, ULONG val)
|
||||
{
|
||||
if((val&0xc00000) == 0) // simple mul
|
||||
{
|
||||
if(val & 0x100000) // set condition flags
|
||||
if(val & 0x200000) sprintf(stg+strlen(stg), "mla%ss ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "mul%ss ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x200000) sprintf(stg+strlen(stg), "mla%s ", cnd1[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "mul%s ", cnd1[val>>28]);
|
||||
|
||||
if(val & 0x200000) // accumulate
|
||||
sprintf(stg+strlen(stg), "%s, %s, %s, %s", regs[(val>>16)&15], regs[(val>>0)&15], regs[(val>>8)&15], regs[(val>>12)&15]);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, %s, %s", regs[(val>>16)&15], regs[(val>>0)&15], regs[(val>>8)&15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(val & 0x100000) // set condition flags
|
||||
if(val & 0x200000) // accumulate
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smlal%ss ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umlal%ss ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smull%ss ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umull%ss ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x200000)
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smlal%s ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umlal%s ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x400000) sprintf(stg+strlen(stg), "smull%s ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "umull%s ", cond[val>>28]);
|
||||
|
||||
sprintf(stg+strlen(stg), "%s, %s, %s, %s", regs[(val>>12)&15], regs[(val>>16)&15], regs[(val>>0)&15], regs[(val>>8)&15]);
|
||||
}
|
||||
}
|
||||
|
||||
void halfword_stg(char *stg, ULONG val)
|
||||
{
|
||||
ULONG off = ((val>>4) & 0xf0) + (val & 0x0f);
|
||||
|
||||
if(val & 0x100000) sprintf(stg+strlen(stg), "ldr%s", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "str%s", cond[val>>28]);
|
||||
|
||||
switch((val>>5) & 3) // SWP, HW, SB, SH
|
||||
{
|
||||
case 0: sprintf(stg+strlen(stg), "error: SWP"); break;
|
||||
case 1: sprintf(stg+strlen(stg), "h "); break;
|
||||
case 2: sprintf(stg+strlen(stg), "sb "); break;
|
||||
case 3: sprintf(stg+strlen(stg), "sh "); break;
|
||||
}
|
||||
|
||||
if(val & 0x400000) // immidiate offset
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' on post indexed");
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s], "FRMT, regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s], -"FRMT, regs[(val>>12)&15], regs[(val>>16)&15], off);
|
||||
else
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, %s]!", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -%s]!", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s, %s]", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s, -%s]", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' on post indexed");
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "%s, [%s], %s", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s], -%s", regs[(val>>12)&15], regs[(val>>16)&15], regs[val&15]);
|
||||
}
|
||||
|
||||
void branch_stg(char *stg, ULONG val, ULONG pos)
|
||||
{
|
||||
ULONG off = pos + (((int32_t)val << 8) >> 6) + 8;
|
||||
|
||||
if((val & 0x0ffffff0) == 0x012fff10) // bx instruction
|
||||
{ sprintf(stg+strlen(stg), "bx%s %s", cond[val>>28], regs[val&15]); }
|
||||
else
|
||||
{
|
||||
if(((val>>24)&15) == 10) sprintf(stg+strlen(stg), "b%s ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "bl%s ", cond[val>>28]);
|
||||
|
||||
sprintf(stg+strlen(stg), "0x%x", off);
|
||||
}
|
||||
}
|
||||
|
||||
void opcode_stg(char *stg, ULONG val, ULONG off)
|
||||
{
|
||||
ULONG des, op1;
|
||||
char op2[80];
|
||||
char *st = stg + strlen(stg);
|
||||
|
||||
if(((val & 0x0ffffff0) == 0x012fff10) && (val & 16))
|
||||
{ branch_stg(stg, val, off); return; }
|
||||
else if(((val & 0x0f000000) == 0x00000000) && ((val & 0xf0) == 0x90))
|
||||
{ multiply_stg(stg, val); return; }
|
||||
else if(((val & 0x0f000000) <= 0x01000000) && ((val & 0x90) == 0x90) && ((val & 0xf0) > 0x90) && ((val & 0x01200000) != 0x00200000))
|
||||
{ halfword_stg(stg, val); return; }
|
||||
|
||||
sprintf(stg+strlen(stg), "%s%s%s ", opcd[(val>>21) & 15], cond[val>>28], setc[(val>>20) & 31]?"s":" ");
|
||||
|
||||
des = (val>>12) & 15;
|
||||
op1 = (val>>16) & 15;
|
||||
|
||||
if(val & 0x2000000) // immidiate
|
||||
{
|
||||
off = (ULONG)((uint64_t)(val&0xff) << (32 - 2 * ((val >> 8) & 15))) | ((val&0xff) >> 2 * ((val >> 8) & 15));
|
||||
sprintf(op2, FRMT" ", off);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(val & 16) // shift type
|
||||
sprintf(op2, SHFTFRMR, regs[val&15], shfts[(val>>5)&3], regs[(val>>8)&15]);
|
||||
else
|
||||
if((val>>7) & 31)
|
||||
sprintf(op2, SHFTFRMC, regs[val&15], shfts[(val>>5)&3], (val>>7) & 31);
|
||||
else
|
||||
sprintf(op2, "%s ", regs[val&15]);
|
||||
}
|
||||
|
||||
switch((val>>21) & 15)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 12:
|
||||
case 14: sprintf(stg+strlen(stg), "%s, %s, %s", regs[des], regs[op1], op2); break;
|
||||
|
||||
case 8: case 9: case 10:
|
||||
case 11: if(val & 0x100000) // set status
|
||||
sprintf(stg+strlen(stg), "%s, %s", regs[op1], op2); // standard TEQ,TST,CMP,CMN
|
||||
else
|
||||
{ //special MRS/MSR opcodes
|
||||
if((((val>>23) & 31) == 2) && ((val & 0x3f0fff) == 0x0f0000))
|
||||
{ sprintf(st, "mrs%s %s, %s", cnd1[val>>28], regs[des], val&0x400000?"SPSR_xx":"CPSR"); }
|
||||
else
|
||||
if((((val>>23) & 31) == 2) && ((val & 0x30fff0) == 0x20f000))
|
||||
{ sprintf(st, "msr%s %s, %s", cnd1[val>>28], val&0x400000?"SPSR_xx":"CPSR", regs[val&15]); }
|
||||
else
|
||||
if((((val>>23) & 31) == 6) && ((val & 0x30f000) == 0x20f000))
|
||||
{ sprintf(st, "msr%s %s, %s", cnd1[val>>28], val&0x400000?"SPSR_xx":"CPSR_cf", op2); }
|
||||
else
|
||||
if((((val>>23) & 31) == 2) && ((val & 0x300ff0) == 0x000090))
|
||||
{ sprintf(st, "swp%s%s %s, %s, [%s]", val&0x400000?"b":"", cnd1[val>>28], regs[(val>>12)&15], regs[val&15], regs[(val>>16)&15]); }
|
||||
else
|
||||
{ sprintf(stg+strlen(stg), "??????????????"); }
|
||||
} break;
|
||||
case 13:
|
||||
case 15: sprintf(stg+strlen(stg), "%s, %s", regs[des], op2); break;
|
||||
}
|
||||
}
|
||||
|
||||
void opcode_cop(char *stg, ULONG val, ULONG off)
|
||||
{
|
||||
char* op;
|
||||
int opcode1 = (val >> 21) & 0x7;
|
||||
int CRn = (val >> 16) & 0xf;
|
||||
int Rd = (val >> 12) & 0xf;
|
||||
int cp_num = (val >> 8) & 0xf;
|
||||
int opcode2 = (val >> 5) & 0x7;
|
||||
int CRm = val & 0xf;
|
||||
|
||||
|
||||
// ee073f5e mcr 15, 0, r3, cr7, cr14, {2}
|
||||
|
||||
if (val & (1<<4)) {
|
||||
if (val & (1<<20)) {
|
||||
op = "mrc";
|
||||
} else {
|
||||
op = "mcr";
|
||||
}
|
||||
opcode1 = (val >> 21) & 0x7;
|
||||
CRn = (val >> 16) & 0xf;
|
||||
Rd = (val >> 12) & 0xf;
|
||||
cp_num = (val >> 8) & 0xf;
|
||||
opcode2 = (val >> 5) & 0x7;
|
||||
CRm = val & 0xf;
|
||||
|
||||
sprintf(stg+strlen(stg), "%s%s %d, %d, r%d, cr%d, cr%d, {%d}", op, cnd1[val>>28], cp_num, opcode1, Rd, CRn, CRm, opcode2);
|
||||
} else {
|
||||
op = "cdp";
|
||||
|
||||
opcode1 = (val >> 20) & 0xf;
|
||||
CRn = (val >> 16) & 0xf;
|
||||
Rd = (val >> 12) & 0xf;
|
||||
cp_num = (val >> 8) & 0xf;
|
||||
opcode2 = (val >> 5) & 0x7;
|
||||
CRm = val & 0xf;
|
||||
|
||||
sprintf(stg+strlen(stg), "%s%s %d, %d, cr%d, cr%d, cr%d, {%d}", op, cnd1[val>>28], cp_num, opcode1, Rd, CRn, CRm, opcode2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void single_data(char *stg, ULONG val)
|
||||
{
|
||||
char op2[80];
|
||||
|
||||
if(((val & 0x0e000000) == 0x06000000) && (val & 16))
|
||||
{ sprintf(stg+strlen(stg), "undef%s", cond[val>>28]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(val & 0x400000)
|
||||
if(val & 0x100000) sprintf(stg+strlen(stg), "ldr%sb ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "str%sb ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x100000) sprintf(stg+strlen(stg), "ldr%s ", cnd1[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "str%s ", cnd1[val>>28]);
|
||||
|
||||
if(val & 0x2000000) {// reg offset
|
||||
if(val & 16) // shift type
|
||||
sprintf(op2, "error: reg defined shift");
|
||||
else
|
||||
if((val>>7) & 31)
|
||||
sprintf(op2, SHFTFRMC, regs[val&15], shfts[(val>>5)&3], (val>>7) & 31);
|
||||
else
|
||||
sprintf(op2, "%s", regs[val&15]);
|
||||
}
|
||||
|
||||
if(val & 0x2000000) // reg offset
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x800000) // up offset (+)
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "%s, [%s, %s]!", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, [%s, %s]", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "%s, [%s, -%s]!", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, [%s, -%s]", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' set");
|
||||
else
|
||||
if(val & 0x800000) // up offset (+)
|
||||
sprintf(stg+strlen(stg), "%s, [%s], %s", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
sprintf(stg+strlen(stg), "%s, [%s], -%s", regs[(val>>12)&15], regs[(val>>16)&15], op2);
|
||||
else
|
||||
if(val & 0x1000000) // pre index
|
||||
if(val & 0x800000) // up offset (+)
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]!", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, "FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]!", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]!", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s, -"FRMT"]", regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0x200000) // write back
|
||||
sprintf(stg+strlen(stg), "error 'write back' set");
|
||||
else
|
||||
if(val & 0x800000) // up offset (+)
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s], "FRMT, regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
else
|
||||
if(val & 0xfff) sprintf(stg+strlen(stg), "%s, [%s], -"FRMT, regs[(val>>12)&15], regs[(val>>16)&15], val & 0xfff);
|
||||
else sprintf(stg+strlen(stg), "%s, [%s]", regs[(val>>12)&15], regs[(val>>16)&15]);
|
||||
}
|
||||
|
||||
void block_data(char *stg, ULONG val)
|
||||
{
|
||||
char lst[80];
|
||||
int i;
|
||||
|
||||
strcpy(lst, "{");
|
||||
for(i=0; i<16; i++)
|
||||
if(val & (1<<i))
|
||||
sprintf(lst+strlen(lst), "%s, ", regs[i]);
|
||||
if(strlen(lst)>2)
|
||||
strcpy(lst+strlen(lst)-2, "}");
|
||||
else
|
||||
strcpy(lst+strlen(lst), "}");
|
||||
|
||||
if(val & 0x400000) // load psr or force user mode
|
||||
strcpy(lst+strlen(lst), "^");
|
||||
|
||||
|
||||
if(val & 0x100000) // load
|
||||
if(val & 0x1000000) // pre offset
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "ldm%sib ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "ldm%sdb ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "ldm%sia ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "ldm%sda ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x1000000)
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "stm%sib ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "stm%sdb ", cond[val>>28]);
|
||||
else
|
||||
if(val & 0x800000) sprintf(stg+strlen(stg), "stm%sia ", cond[val>>28]);
|
||||
else sprintf(stg+strlen(stg), "stm%sda ", cond[val>>28]);
|
||||
|
||||
switch((val>>21)&3)
|
||||
{
|
||||
case 0: sprintf(stg+strlen(stg), "%s, %s", regs[(val>>16)&15], lst); break;
|
||||
case 1: sprintf(stg+strlen(stg), "%s!, %s", regs[(val>>16)&15], lst); break;
|
||||
case 2: sprintf(stg+strlen(stg), "%s, %s", regs[(val>>16)&15], lst); break;
|
||||
case 3: sprintf(stg+strlen(stg), "%s!, %s", regs[(val>>16)&15], lst); break;
|
||||
}
|
||||
}
|
||||
|
||||
void dis_asm(ULONG off, ULONG val, char *stg)
|
||||
{
|
||||
sprintf(stg, "%6x: %08x ", off, val);
|
||||
|
||||
switch((val >> 24) & 15)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: opcode_stg(stg, val, off); break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7: single_data(stg, val); break;
|
||||
case 8:
|
||||
case 9: block_data(stg, val); break;
|
||||
case 10:
|
||||
case 11: branch_stg(stg, val, off); break;
|
||||
case 12:
|
||||
case 13: sprintf(stg+strlen(stg), "cop%s", cnd1[val>>28]); break;
|
||||
case 14: opcode_cop(stg, val, off); break;
|
||||
case 15: sprintf(stg+strlen(stg), "swi%s", cnd1[val>>28]); break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,132 +1,132 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ULONG uint32_t
|
||||
#define USHORT uint16_t
|
||||
#define UCHAR uint8_t
|
||||
|
||||
ULONG isdata[1000000]; /* each bit defines one byte as: code=0, data=1 */
|
||||
|
||||
extern void dis_asm(ULONG off, ULONG val, char *stg);
|
||||
|
||||
int static inline le2int(unsigned char* buf)
|
||||
{
|
||||
int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *in, *out;
|
||||
char *ptr, stg[256];
|
||||
unsigned char buf[4];
|
||||
ULONG pos, sz, val, loop;
|
||||
int offset, offset1;
|
||||
USHORT regid;
|
||||
|
||||
if(argc == 1 || strcmp(argv[1], "--help") == 0)
|
||||
{ printf("Usage: arm_disass [input file]\n");
|
||||
printf(" disassembles input file to 'disasm.txt'\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in = fopen(argv[1], "rb");
|
||||
if(in == NULL)
|
||||
{ printf("Cannot open %s", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
out = fopen("disasm.txt", "w");
|
||||
if(out == NULL) exit(-1);
|
||||
|
||||
fseek(in, 0, SEEK_END);
|
||||
sz = ftell(in);
|
||||
|
||||
/* first loop only sets data/code tags */
|
||||
for(loop=0; loop<2; loop++)
|
||||
{
|
||||
for(pos=0; pos<sz; pos+=4)
|
||||
{
|
||||
/* clear disassembler string start */
|
||||
memset(stg, 0, 40);
|
||||
/* read next code dword */
|
||||
fseek(in, pos, SEEK_SET);
|
||||
fread(buf, 1, 4, in);
|
||||
|
||||
val = le2int(buf);
|
||||
|
||||
/* check for data tag set: if 1 byte out of 4 is marked => assume data */
|
||||
if((isdata[pos>>5] & (0xf << (pos & 31))) || (val & 0xffff0000) == 0)
|
||||
{
|
||||
sprintf(stg, "%6x: %08x", pos, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_asm(pos, val, stg);
|
||||
|
||||
/* check for instant mov operation */
|
||||
if(memcmp(stg+17, "mov ", 4) == 0 && (ptr=strstr(stg, "0x")) != NULL)
|
||||
{
|
||||
regid = *(USHORT*)(stg+22);
|
||||
|
||||
sscanf(ptr+2, "%x", &offset);
|
||||
if(ptr[-1] == '-')
|
||||
offset = -offset;
|
||||
}
|
||||
else
|
||||
/* check for add/sub operation */
|
||||
if((ptr=strstr(stg, "0x")) != NULL
|
||||
&& (memcmp(stg+17, "add ", 4) == 0 || memcmp(stg+17, "sub ", 4) == 0))
|
||||
{
|
||||
if(regid == *(USHORT*)(stg+22) && regid == *(USHORT*)(stg+26))
|
||||
{
|
||||
sscanf(ptr+2, "%x", &offset1);
|
||||
if(ptr[-1] == '-')
|
||||
offset1 = -offset1;
|
||||
|
||||
if(memcmp(stg+17, "add ", 4) == 0) offset += offset1;
|
||||
else offset -= offset1;
|
||||
|
||||
/* add result to disassembler string */
|
||||
sprintf(stg+strlen(stg), " <- 0x%x", offset);
|
||||
}
|
||||
else
|
||||
regid = 0;
|
||||
}
|
||||
else
|
||||
regid = 0;
|
||||
|
||||
/* check for const data */
|
||||
if(memcmp(stg+26, "[pc, ", 5) == 0 && (ptr=strstr(stg, "0x")) != NULL)
|
||||
{
|
||||
sscanf(ptr+2, "%x", &offset);
|
||||
if(ptr[-1] == '-')
|
||||
offset = -offset;
|
||||
|
||||
/* add data tag */
|
||||
isdata[(pos+offset+8)>>5] |= 1 << ((pos+offset+8) & 31);
|
||||
|
||||
/* add const data to disassembler string */
|
||||
fseek(in, pos+offset+8, SEEK_SET);
|
||||
fread(&buf, 1, 4, in);
|
||||
offset = le2int(buf);
|
||||
|
||||
sprintf(stg+strlen(stg), " <- 0x%x", offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* remove trailing spaces */
|
||||
while(stg[strlen(stg)-1] == 32)
|
||||
stg[strlen(stg)-1] = 0;
|
||||
|
||||
if(loop == 1)
|
||||
fprintf(out, "%s\n", stg);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ULONG uint32_t
|
||||
#define USHORT uint16_t
|
||||
#define UCHAR uint8_t
|
||||
|
||||
ULONG isdata[1000000]; /* each bit defines one byte as: code=0, data=1 */
|
||||
|
||||
extern void dis_asm(ULONG off, ULONG val, char *stg);
|
||||
|
||||
int static inline le2int(unsigned char* buf)
|
||||
{
|
||||
int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *in, *out;
|
||||
char *ptr, stg[256];
|
||||
unsigned char buf[4];
|
||||
ULONG pos, sz, val, loop;
|
||||
int offset, offset1;
|
||||
USHORT regid;
|
||||
|
||||
if(argc == 1 || strcmp(argv[1], "--help") == 0)
|
||||
{ printf("Usage: arm_disass [input file]\n");
|
||||
printf(" disassembles input file to 'disasm.txt'\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in = fopen(argv[1], "rb");
|
||||
if(in == NULL)
|
||||
{ printf("Cannot open %s", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
out = fopen("disasm.txt", "w");
|
||||
if(out == NULL) exit(-1);
|
||||
|
||||
fseek(in, 0, SEEK_END);
|
||||
sz = ftell(in);
|
||||
|
||||
/* first loop only sets data/code tags */
|
||||
for(loop=0; loop<2; loop++)
|
||||
{
|
||||
for(pos=0; pos<sz; pos+=4)
|
||||
{
|
||||
/* clear disassembler string start */
|
||||
memset(stg, 0, 40);
|
||||
/* read next code dword */
|
||||
fseek(in, pos, SEEK_SET);
|
||||
fread(buf, 1, 4, in);
|
||||
|
||||
val = le2int(buf);
|
||||
|
||||
/* check for data tag set: if 1 byte out of 4 is marked => assume data */
|
||||
if((isdata[pos>>5] & (0xf << (pos & 31))) || (val & 0xffff0000) == 0)
|
||||
{
|
||||
sprintf(stg, "%6x: %08x", pos, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_asm(pos, val, stg);
|
||||
|
||||
/* check for instant mov operation */
|
||||
if(memcmp(stg+17, "mov ", 4) == 0 && (ptr=strstr(stg, "0x")) != NULL)
|
||||
{
|
||||
regid = *(USHORT*)(stg+22);
|
||||
|
||||
sscanf(ptr+2, "%x", &offset);
|
||||
if(ptr[-1] == '-')
|
||||
offset = -offset;
|
||||
}
|
||||
else
|
||||
/* check for add/sub operation */
|
||||
if((ptr=strstr(stg, "0x")) != NULL
|
||||
&& (memcmp(stg+17, "add ", 4) == 0 || memcmp(stg+17, "sub ", 4) == 0))
|
||||
{
|
||||
if(regid == *(USHORT*)(stg+22) && regid == *(USHORT*)(stg+26))
|
||||
{
|
||||
sscanf(ptr+2, "%x", &offset1);
|
||||
if(ptr[-1] == '-')
|
||||
offset1 = -offset1;
|
||||
|
||||
if(memcmp(stg+17, "add ", 4) == 0) offset += offset1;
|
||||
else offset -= offset1;
|
||||
|
||||
/* add result to disassembler string */
|
||||
sprintf(stg+strlen(stg), " <- 0x%x", offset);
|
||||
}
|
||||
else
|
||||
regid = 0;
|
||||
}
|
||||
else
|
||||
regid = 0;
|
||||
|
||||
/* check for const data */
|
||||
if(memcmp(stg+26, "[pc, ", 5) == 0 && (ptr=strstr(stg, "0x")) != NULL)
|
||||
{
|
||||
sscanf(ptr+2, "%x", &offset);
|
||||
if(ptr[-1] == '-')
|
||||
offset = -offset;
|
||||
|
||||
/* add data tag */
|
||||
isdata[(pos+offset+8)>>5] |= 1 << ((pos+offset+8) & 31);
|
||||
|
||||
/* add const data to disassembler string */
|
||||
fseek(in, pos+offset+8, SEEK_SET);
|
||||
fread(&buf, 1, 4, in);
|
||||
offset = le2int(buf);
|
||||
|
||||
sprintf(stg+strlen(stg), " <- 0x%x", offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* remove trailing spaces */
|
||||
while(stg[strlen(stg)-1] == 32)
|
||||
stg[strlen(stg)-1] = 0;
|
||||
|
||||
if(loop == 1)
|
||||
fprintf(out, "%s\n", stg);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,321 +1,321 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define VERSION "0.2"
|
||||
|
||||
static unsigned char* int2le(unsigned int val)
|
||||
{
|
||||
static unsigned char addr[4];
|
||||
addr[0] = val & 0xff;
|
||||
addr[1] = (val >> 8) & 0xff;
|
||||
addr[2] = (val >> 16) & 0xff;
|
||||
addr[3] = (val >> 24) & 0xff;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static unsigned int le2int(unsigned char* buf)
|
||||
{
|
||||
unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PATH_SEPARATOR "\\"
|
||||
#else
|
||||
#define PATH_SEPARATOR "/"
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define MIN(a, b) (a > b ? b : a)
|
||||
static char* replace(char* str)
|
||||
{
|
||||
static char tmp[255];
|
||||
memcpy(tmp, str, MIN(strlen(str), 255));
|
||||
char *ptr = tmp;
|
||||
while(*ptr != 0)
|
||||
{
|
||||
if(*ptr == 0x2F) /* /*/
|
||||
*ptr = 0x5C; /* \ */
|
||||
ptr++;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool is_dir(const char* name1, const char* name2)
|
||||
{
|
||||
char *name;
|
||||
DIR *directory;
|
||||
name = (char*)malloc(strlen(name1)+strlen(name2)+1);
|
||||
strcpy(name, name1);
|
||||
strcat(name, name2);
|
||||
directory = opendir(name);
|
||||
free(name);
|
||||
if(directory)
|
||||
{
|
||||
closedir(directory);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int _filesize(FILE* fd)
|
||||
{
|
||||
unsigned int tmp, oldpos;
|
||||
oldpos = ftell(fd);
|
||||
fseek(fd, 0, SEEK_END);
|
||||
tmp = ftell(fd);
|
||||
fseek(fd, oldpos, SEEK_SET);
|
||||
return tmp;
|
||||
}
|
||||
#define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
|
||||
{ \
|
||||
closedir(indir_handle); \
|
||||
if(filesize > 0) \
|
||||
free(buffer); \
|
||||
fprintf(stderr, "[ERR] Error writing to file\n"); \
|
||||
return; \
|
||||
}
|
||||
static void merge_hxf(const char* indir, FILE* outfile, const char* add)
|
||||
{
|
||||
DIR *indir_handle;
|
||||
struct dirent *dirs;
|
||||
char dir[255];
|
||||
strcpy(dir, indir);
|
||||
strcat(dir, add);
|
||||
|
||||
if((indir_handle = opendir(dir)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Error opening dir %s\n", indir);
|
||||
return;
|
||||
}
|
||||
|
||||
while((dirs = readdir(indir_handle)) != NULL)
|
||||
{
|
||||
if(strcmp(dirs->d_name, "..") != 0 &&
|
||||
strcmp(dirs->d_name, ".") != 0)
|
||||
{
|
||||
fprintf(stderr, "[INFO] %s\%s\n", add, dirs->d_name);
|
||||
if(is_dir(dir, dirs->d_name))
|
||||
{
|
||||
char dir2[255];
|
||||
strcpy(dir2, add);
|
||||
strcat(dir2, dirs->d_name);
|
||||
strcat(dir2, PATH_SEPARATOR);
|
||||
merge_hxf(indir, outfile, dir2);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *filehandle;
|
||||
unsigned char *buffer;
|
||||
char file[255];
|
||||
unsigned int filesize;
|
||||
strcpy(file, dir);
|
||||
strcat(file, dirs->d_name);
|
||||
if((filehandle = fopen(file, "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", file);
|
||||
closedir(indir_handle);
|
||||
return;
|
||||
}
|
||||
filesize = _filesize(filehandle);
|
||||
if(filesize > 0)
|
||||
{
|
||||
buffer = (unsigned char*)malloc(filesize);
|
||||
if(buffer == NULL)
|
||||
{
|
||||
fclose(filehandle);
|
||||
closedir(indir_handle);
|
||||
fprintf(stderr, "[ERR] Cannot allocate memory\n");
|
||||
return;
|
||||
}
|
||||
if(fread(buffer, filesize, 1, filehandle) != 1)
|
||||
{
|
||||
fclose(filehandle);
|
||||
closedir(indir_handle);
|
||||
free(buffer);
|
||||
fprintf(stderr, "[ERR] Cannot read from %s%s%s\n", add, PATH_SEPARATOR, dirs->d_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fclose(filehandle);
|
||||
|
||||
if(strlen(add)>0)
|
||||
{
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
WRITE(int2le(dirs->d_namlen+strlen(add)), 4);
|
||||
#else
|
||||
WRITE(int2le(strlen(dirs->d_name)+strlen(add)), 4);
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
WRITE(replace((char*)add), strlen(add)-1);
|
||||
#else
|
||||
WRITE(add, strlen(add)-1);
|
||||
#endif
|
||||
WRITE(PATH_SEPARATOR, 1);
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
WRITE(dirs->d_name, dirs->d_namlen);
|
||||
#else
|
||||
WRITE(dirs->d_name, strlen(dirs->d_name));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
WRITE(int2le(dirs->d_namlen), 4);
|
||||
WRITE(dirs->d_name, dirs->d_namlen);
|
||||
#else
|
||||
WRITE(int2le(strlen(dirs->d_name)), 4);
|
||||
WRITE(dirs->d_name, strlen(dirs->d_name));
|
||||
#endif
|
||||
}
|
||||
WRITE(int2le(filesize), 4);
|
||||
if(filesize>0)
|
||||
{
|
||||
WRITE(buffer, filesize);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(indir_handle);
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Usage: hxfmerge.exe [INPUT_DIR] [FW]\n\n");
|
||||
fprintf(stderr, "Example: hxfmerge.exe VX747_extracted\\ VX747.HXF\n\n");
|
||||
#else
|
||||
fprintf(stderr, "Usage: HXFmerge [INPUT_DIR] [FW]\n\n");
|
||||
fprintf(stderr, "Example: HXFmerge VX747_extracted/ VX747.HXF\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int checksum(FILE *file)
|
||||
{
|
||||
int oldpos = ftell(file);
|
||||
int ret=0, i, filesize = _filesize(file)-0x40;
|
||||
unsigned char *buf;
|
||||
|
||||
buf = (unsigned char*)malloc(filesize);
|
||||
|
||||
if(buf == NULL)
|
||||
{
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while allocating memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(file, 0x40, SEEK_SET);
|
||||
if(fread(buf, filesize, 1, file) != 1)
|
||||
{
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while reading from file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Computing checksum...");
|
||||
|
||||
for(i = 0; i < filesize; i+=4)
|
||||
ret += le2int(&buf[i]);
|
||||
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
|
||||
fprintf(stderr, " Done!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *outfile;
|
||||
|
||||
fprintf(stderr, "HXFmerge v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
|
||||
fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
|
||||
fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
|
||||
|
||||
if(argc != 3)
|
||||
{
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(strcmp((char*)(argv[1]+strlen(argv[1])-1), "\\") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Input path must end with a \\\n");
|
||||
#else
|
||||
if(strcmp((char*)(argv[1]+strlen(argv[1])-1), "/") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Input path must end with a /\n");
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
if((outfile = fopen(argv[2], "wb+")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
fseek(outfile, 0x40, SEEK_SET);
|
||||
|
||||
merge_hxf(argv[1], outfile, "");
|
||||
|
||||
fflush(outfile);
|
||||
|
||||
fprintf(stderr, "[INFO] Filling header...\n");
|
||||
|
||||
#undef WRITE
|
||||
#define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot write to %s\n", argv[1]); \
|
||||
fclose(outfile); \
|
||||
return 4; \
|
||||
}
|
||||
fflush(outfile);
|
||||
fseek(outfile, 0, SEEK_SET);
|
||||
WRITE("WADF0100200804111437", 20);
|
||||
WRITE(int2le(_filesize(outfile)), 4);
|
||||
WRITE(int2le(checksum(outfile)), 4);
|
||||
WRITE(int2le(0), 4);
|
||||
WRITE("Chinachip PMP firmware V1.0\0\0\0\0\0", 32);
|
||||
fclose(outfile);
|
||||
|
||||
fprintf(stderr, "[INFO] Done!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define VERSION "0.2"
|
||||
|
||||
static unsigned char* int2le(unsigned int val)
|
||||
{
|
||||
static unsigned char addr[4];
|
||||
addr[0] = val & 0xff;
|
||||
addr[1] = (val >> 8) & 0xff;
|
||||
addr[2] = (val >> 16) & 0xff;
|
||||
addr[3] = (val >> 24) & 0xff;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static unsigned int le2int(unsigned char* buf)
|
||||
{
|
||||
unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PATH_SEPARATOR "\\"
|
||||
#else
|
||||
#define PATH_SEPARATOR "/"
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define MIN(a, b) (a > b ? b : a)
|
||||
static char* replace(char* str)
|
||||
{
|
||||
static char tmp[255];
|
||||
memcpy(tmp, str, MIN(strlen(str), 255));
|
||||
char *ptr = tmp;
|
||||
while(*ptr != 0)
|
||||
{
|
||||
if(*ptr == 0x2F) /* /*/
|
||||
*ptr = 0x5C; /* \ */
|
||||
ptr++;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool is_dir(const char* name1, const char* name2)
|
||||
{
|
||||
char *name;
|
||||
DIR *directory;
|
||||
name = (char*)malloc(strlen(name1)+strlen(name2)+1);
|
||||
strcpy(name, name1);
|
||||
strcat(name, name2);
|
||||
directory = opendir(name);
|
||||
free(name);
|
||||
if(directory)
|
||||
{
|
||||
closedir(directory);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int _filesize(FILE* fd)
|
||||
{
|
||||
unsigned int tmp, oldpos;
|
||||
oldpos = ftell(fd);
|
||||
fseek(fd, 0, SEEK_END);
|
||||
tmp = ftell(fd);
|
||||
fseek(fd, oldpos, SEEK_SET);
|
||||
return tmp;
|
||||
}
|
||||
#define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
|
||||
{ \
|
||||
closedir(indir_handle); \
|
||||
if(filesize > 0) \
|
||||
free(buffer); \
|
||||
fprintf(stderr, "[ERR] Error writing to file\n"); \
|
||||
return; \
|
||||
}
|
||||
static void merge_hxf(const char* indir, FILE* outfile, const char* add)
|
||||
{
|
||||
DIR *indir_handle;
|
||||
struct dirent *dirs;
|
||||
char dir[255];
|
||||
strcpy(dir, indir);
|
||||
strcat(dir, add);
|
||||
|
||||
if((indir_handle = opendir(dir)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Error opening dir %s\n", indir);
|
||||
return;
|
||||
}
|
||||
|
||||
while((dirs = readdir(indir_handle)) != NULL)
|
||||
{
|
||||
if(strcmp(dirs->d_name, "..") != 0 &&
|
||||
strcmp(dirs->d_name, ".") != 0)
|
||||
{
|
||||
fprintf(stderr, "[INFO] %s\%s\n", add, dirs->d_name);
|
||||
if(is_dir(dir, dirs->d_name))
|
||||
{
|
||||
char dir2[255];
|
||||
strcpy(dir2, add);
|
||||
strcat(dir2, dirs->d_name);
|
||||
strcat(dir2, PATH_SEPARATOR);
|
||||
merge_hxf(indir, outfile, dir2);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *filehandle;
|
||||
unsigned char *buffer;
|
||||
char file[255];
|
||||
unsigned int filesize;
|
||||
strcpy(file, dir);
|
||||
strcat(file, dirs->d_name);
|
||||
if((filehandle = fopen(file, "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", file);
|
||||
closedir(indir_handle);
|
||||
return;
|
||||
}
|
||||
filesize = _filesize(filehandle);
|
||||
if(filesize > 0)
|
||||
{
|
||||
buffer = (unsigned char*)malloc(filesize);
|
||||
if(buffer == NULL)
|
||||
{
|
||||
fclose(filehandle);
|
||||
closedir(indir_handle);
|
||||
fprintf(stderr, "[ERR] Cannot allocate memory\n");
|
||||
return;
|
||||
}
|
||||
if(fread(buffer, filesize, 1, filehandle) != 1)
|
||||
{
|
||||
fclose(filehandle);
|
||||
closedir(indir_handle);
|
||||
free(buffer);
|
||||
fprintf(stderr, "[ERR] Cannot read from %s%s%s\n", add, PATH_SEPARATOR, dirs->d_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fclose(filehandle);
|
||||
|
||||
if(strlen(add)>0)
|
||||
{
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
WRITE(int2le(dirs->d_namlen+strlen(add)), 4);
|
||||
#else
|
||||
WRITE(int2le(strlen(dirs->d_name)+strlen(add)), 4);
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
WRITE(replace((char*)add), strlen(add)-1);
|
||||
#else
|
||||
WRITE(add, strlen(add)-1);
|
||||
#endif
|
||||
WRITE(PATH_SEPARATOR, 1);
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
WRITE(dirs->d_name, dirs->d_namlen);
|
||||
#else
|
||||
WRITE(dirs->d_name, strlen(dirs->d_name));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
WRITE(int2le(dirs->d_namlen), 4);
|
||||
WRITE(dirs->d_name, dirs->d_namlen);
|
||||
#else
|
||||
WRITE(int2le(strlen(dirs->d_name)), 4);
|
||||
WRITE(dirs->d_name, strlen(dirs->d_name));
|
||||
#endif
|
||||
}
|
||||
WRITE(int2le(filesize), 4);
|
||||
if(filesize>0)
|
||||
{
|
||||
WRITE(buffer, filesize);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(indir_handle);
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Usage: hxfmerge.exe [INPUT_DIR] [FW]\n\n");
|
||||
fprintf(stderr, "Example: hxfmerge.exe VX747_extracted\\ VX747.HXF\n\n");
|
||||
#else
|
||||
fprintf(stderr, "Usage: HXFmerge [INPUT_DIR] [FW]\n\n");
|
||||
fprintf(stderr, "Example: HXFmerge VX747_extracted/ VX747.HXF\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int checksum(FILE *file)
|
||||
{
|
||||
int oldpos = ftell(file);
|
||||
int ret=0, i, filesize = _filesize(file)-0x40;
|
||||
unsigned char *buf;
|
||||
|
||||
buf = (unsigned char*)malloc(filesize);
|
||||
|
||||
if(buf == NULL)
|
||||
{
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while allocating memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(file, 0x40, SEEK_SET);
|
||||
if(fread(buf, filesize, 1, file) != 1)
|
||||
{
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while reading from file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Computing checksum...");
|
||||
|
||||
for(i = 0; i < filesize; i+=4)
|
||||
ret += le2int(&buf[i]);
|
||||
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
|
||||
fprintf(stderr, " Done!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *outfile;
|
||||
|
||||
fprintf(stderr, "HXFmerge v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
|
||||
fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
|
||||
fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
|
||||
|
||||
if(argc != 3)
|
||||
{
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(strcmp((char*)(argv[1]+strlen(argv[1])-1), "\\") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Input path must end with a \\\n");
|
||||
#else
|
||||
if(strcmp((char*)(argv[1]+strlen(argv[1])-1), "/") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Input path must end with a /\n");
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
if((outfile = fopen(argv[2], "wb+")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
fseek(outfile, 0x40, SEEK_SET);
|
||||
|
||||
merge_hxf(argv[1], outfile, "");
|
||||
|
||||
fflush(outfile);
|
||||
|
||||
fprintf(stderr, "[INFO] Filling header...\n");
|
||||
|
||||
#undef WRITE
|
||||
#define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot write to %s\n", argv[1]); \
|
||||
fclose(outfile); \
|
||||
return 4; \
|
||||
}
|
||||
fflush(outfile);
|
||||
fseek(outfile, 0, SEEK_SET);
|
||||
WRITE("WADF0100200804111437", 20);
|
||||
WRITE(int2le(_filesize(outfile)), 4);
|
||||
WRITE(int2le(checksum(outfile)), 4);
|
||||
WRITE(int2le(0), 4);
|
||||
WRITE("Chinachip PMP firmware V1.0\0\0\0\0\0", 32);
|
||||
fclose(outfile);
|
||||
|
||||
fprintf(stderr, "[INFO] Done!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,242 +1,242 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define VERSION "0.1"
|
||||
|
||||
static unsigned char* int2le(unsigned int val)
|
||||
{
|
||||
static unsigned char addr[4];
|
||||
addr[0] = val & 0xff;
|
||||
addr[1] = (val >> 8) & 0xff;
|
||||
addr[2] = (val >> 16) & 0xff;
|
||||
addr[3] = (val >> 24) & 0xff;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static unsigned int le2int(unsigned char* buf)
|
||||
{
|
||||
unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
unsigned int _filesize(FILE* fd)
|
||||
{
|
||||
unsigned int tmp, oldpos;
|
||||
oldpos = ftell(fd);
|
||||
fseek(fd, 0, SEEK_END);
|
||||
tmp = ftell(fd);
|
||||
fseek(fd, oldpos, SEEK_SET);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Usage: hxfreplace.exe [IN_FW] [OUT_FW] [BIN_FILE]\n\n");
|
||||
fprintf(stderr, "Example: hxfreplace.exe VX747.HXF out.hxf ccpmp.bin\n\n");
|
||||
#else
|
||||
fprintf(stderr, "Usage: HXFreplace [IN_FW] [OUT_FW] [BIN_FILE]\n\n");
|
||||
fprintf(stderr, "Example: HXFreplace VX747.HXF out.hxf ccpmp.bin\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int checksum(FILE *file)
|
||||
{
|
||||
int oldpos = ftell(file);
|
||||
int ret=0, i, filesize = _filesize(file)-0x40;
|
||||
unsigned char *buf;
|
||||
|
||||
buf = (unsigned char*)malloc(filesize);
|
||||
|
||||
if(buf == NULL)
|
||||
{
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while allocating memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(file, 0x40, SEEK_SET);
|
||||
if(fread(buf, filesize, 1, file) != 1)
|
||||
{
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while reading from file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Computing checksum...");
|
||||
|
||||
for(i = 0; i < filesize; i+=4)
|
||||
ret += le2int(&buf[i]);
|
||||
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
|
||||
fprintf(stderr, " Done!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *infile, *outfile, *fw;
|
||||
|
||||
fprintf(stderr, "HXFreplace v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
|
||||
fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
|
||||
fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
|
||||
|
||||
if(argc != 4)
|
||||
{
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if((infile = fopen(argv[1], "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if(fseek(infile, 0x40, SEEK_SET) != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot seek to 0x40\n");
|
||||
fclose(infile);
|
||||
return 3;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Searching for ccpmp.bin...\n");
|
||||
|
||||
int found = -1;
|
||||
int filenamesize;
|
||||
char *filename;
|
||||
unsigned char tmp[4];
|
||||
|
||||
#define READ(x, len) if(fread(x, len, 1, infile) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot read from %s\n", argv[1]); \
|
||||
fclose(infile); \
|
||||
return 4; \
|
||||
}
|
||||
while(found < 0)
|
||||
{
|
||||
READ(&tmp[0], 4);
|
||||
filenamesize = le2int(tmp);
|
||||
filename = (char*)malloc(filenamesize);
|
||||
READ(filename, filenamesize);
|
||||
if(strcmp(filename, "ccpmp.bin") == 0)
|
||||
found = ftell(infile);
|
||||
else
|
||||
{
|
||||
READ(&tmp[0], 4);
|
||||
fseek(infile, le2int(tmp), SEEK_CUR);
|
||||
}
|
||||
free(filename);
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Found ccpmp.bin at 0x%x\n", found);
|
||||
|
||||
if((outfile = fopen(argv[2], "wb+")) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[2]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
#define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot write to %s\n", argv[2]); \
|
||||
fclose(outfile); \
|
||||
if(fw != NULL) \
|
||||
fclose(fw); \
|
||||
return 5; \
|
||||
}
|
||||
|
||||
unsigned char* buffer;
|
||||
|
||||
buffer = (unsigned char*)malloc(found);
|
||||
fseek(infile, 0, SEEK_SET);
|
||||
READ(buffer, found);
|
||||
WRITE(buffer, found);
|
||||
free(buffer);
|
||||
|
||||
if((fw = fopen(argv[3], "rb")) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[3]);
|
||||
}
|
||||
|
||||
int fw_filesize = _filesize(fw);
|
||||
|
||||
#define READ2(x, len) if(fread(x, len, 1, fw) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot read from %s\n", argv[3]); \
|
||||
fclose(infile); \
|
||||
fclose(outfile); \
|
||||
return 6; \
|
||||
}
|
||||
buffer = (unsigned char*)malloc(fw_filesize);
|
||||
READ2(buffer, fw_filesize);
|
||||
fputc(0x20, outfile); /* Padding */
|
||||
WRITE(int2le(fw_filesize), 4);
|
||||
WRITE(buffer, fw_filesize);
|
||||
free(buffer);
|
||||
fclose(fw);
|
||||
fw = NULL;
|
||||
|
||||
fseek(infile, found+1, SEEK_SET);
|
||||
READ(&tmp, 4);
|
||||
if(fseek(infile, le2int(&tmp[0]), SEEK_CUR) != 0)
|
||||
{
|
||||
fprintf(stderr, "[INFO] Cannot seek into %s\n", argv[1]);
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
return 7;
|
||||
}
|
||||
found = ftell(infile);
|
||||
|
||||
int other_size = _filesize(infile) - found;
|
||||
buffer = (unsigned char*)malloc(other_size);
|
||||
READ(buffer, other_size);
|
||||
WRITE(buffer, other_size);
|
||||
free(buffer);
|
||||
fclose(infile);
|
||||
|
||||
fflush(outfile);
|
||||
fseek(outfile, 0x14, SEEK_SET);
|
||||
WRITE(int2le(_filesize(outfile)), 4);
|
||||
WRITE(int2le(checksum(outfile)), 4);
|
||||
fclose(outfile);
|
||||
|
||||
fprintf(stderr, "[INFO] Done!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define VERSION "0.1"
|
||||
|
||||
static unsigned char* int2le(unsigned int val)
|
||||
{
|
||||
static unsigned char addr[4];
|
||||
addr[0] = val & 0xff;
|
||||
addr[1] = (val >> 8) & 0xff;
|
||||
addr[2] = (val >> 16) & 0xff;
|
||||
addr[3] = (val >> 24) & 0xff;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static unsigned int le2int(unsigned char* buf)
|
||||
{
|
||||
unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
unsigned int _filesize(FILE* fd)
|
||||
{
|
||||
unsigned int tmp, oldpos;
|
||||
oldpos = ftell(fd);
|
||||
fseek(fd, 0, SEEK_END);
|
||||
tmp = ftell(fd);
|
||||
fseek(fd, oldpos, SEEK_SET);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Usage: hxfreplace.exe [IN_FW] [OUT_FW] [BIN_FILE]\n\n");
|
||||
fprintf(stderr, "Example: hxfreplace.exe VX747.HXF out.hxf ccpmp.bin\n\n");
|
||||
#else
|
||||
fprintf(stderr, "Usage: HXFreplace [IN_FW] [OUT_FW] [BIN_FILE]\n\n");
|
||||
fprintf(stderr, "Example: HXFreplace VX747.HXF out.hxf ccpmp.bin\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int checksum(FILE *file)
|
||||
{
|
||||
int oldpos = ftell(file);
|
||||
int ret=0, i, filesize = _filesize(file)-0x40;
|
||||
unsigned char *buf;
|
||||
|
||||
buf = (unsigned char*)malloc(filesize);
|
||||
|
||||
if(buf == NULL)
|
||||
{
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while allocating memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(file, 0x40, SEEK_SET);
|
||||
if(fread(buf, filesize, 1, file) != 1)
|
||||
{
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
fprintf(stderr, "[ERR] Error while reading from file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Computing checksum...");
|
||||
|
||||
for(i = 0; i < filesize; i+=4)
|
||||
ret += le2int(&buf[i]);
|
||||
|
||||
free(buf);
|
||||
fseek(file, oldpos, SEEK_SET);
|
||||
|
||||
fprintf(stderr, " Done!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *infile, *outfile, *fw;
|
||||
|
||||
fprintf(stderr, "HXFreplace v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
|
||||
fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
|
||||
fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
|
||||
|
||||
if(argc != 4)
|
||||
{
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if((infile = fopen(argv[1], "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if(fseek(infile, 0x40, SEEK_SET) != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot seek to 0x40\n");
|
||||
fclose(infile);
|
||||
return 3;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Searching for ccpmp.bin...\n");
|
||||
|
||||
int found = -1;
|
||||
int filenamesize;
|
||||
char *filename;
|
||||
unsigned char tmp[4];
|
||||
|
||||
#define READ(x, len) if(fread(x, len, 1, infile) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot read from %s\n", argv[1]); \
|
||||
fclose(infile); \
|
||||
return 4; \
|
||||
}
|
||||
while(found < 0)
|
||||
{
|
||||
READ(&tmp[0], 4);
|
||||
filenamesize = le2int(tmp);
|
||||
filename = (char*)malloc(filenamesize);
|
||||
READ(filename, filenamesize);
|
||||
if(strcmp(filename, "ccpmp.bin") == 0)
|
||||
found = ftell(infile);
|
||||
else
|
||||
{
|
||||
READ(&tmp[0], 4);
|
||||
fseek(infile, le2int(tmp), SEEK_CUR);
|
||||
}
|
||||
free(filename);
|
||||
}
|
||||
|
||||
fprintf(stderr, "[INFO] Found ccpmp.bin at 0x%x\n", found);
|
||||
|
||||
if((outfile = fopen(argv[2], "wb+")) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[2]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
#define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot write to %s\n", argv[2]); \
|
||||
fclose(outfile); \
|
||||
if(fw != NULL) \
|
||||
fclose(fw); \
|
||||
return 5; \
|
||||
}
|
||||
|
||||
unsigned char* buffer;
|
||||
|
||||
buffer = (unsigned char*)malloc(found);
|
||||
fseek(infile, 0, SEEK_SET);
|
||||
READ(buffer, found);
|
||||
WRITE(buffer, found);
|
||||
free(buffer);
|
||||
|
||||
if((fw = fopen(argv[3], "rb")) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[3]);
|
||||
}
|
||||
|
||||
int fw_filesize = _filesize(fw);
|
||||
|
||||
#define READ2(x, len) if(fread(x, len, 1, fw) != 1) \
|
||||
{ \
|
||||
fprintf(stderr, "[ERR] Cannot read from %s\n", argv[3]); \
|
||||
fclose(infile); \
|
||||
fclose(outfile); \
|
||||
return 6; \
|
||||
}
|
||||
buffer = (unsigned char*)malloc(fw_filesize);
|
||||
READ2(buffer, fw_filesize);
|
||||
fputc(0x20, outfile); /* Padding */
|
||||
WRITE(int2le(fw_filesize), 4);
|
||||
WRITE(buffer, fw_filesize);
|
||||
free(buffer);
|
||||
fclose(fw);
|
||||
fw = NULL;
|
||||
|
||||
fseek(infile, found+1, SEEK_SET);
|
||||
READ(&tmp, 4);
|
||||
if(fseek(infile, le2int(&tmp[0]), SEEK_CUR) != 0)
|
||||
{
|
||||
fprintf(stderr, "[INFO] Cannot seek into %s\n", argv[1]);
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
return 7;
|
||||
}
|
||||
found = ftell(infile);
|
||||
|
||||
int other_size = _filesize(infile) - found;
|
||||
buffer = (unsigned char*)malloc(other_size);
|
||||
READ(buffer, other_size);
|
||||
WRITE(buffer, other_size);
|
||||
free(buffer);
|
||||
fclose(infile);
|
||||
|
||||
fflush(outfile);
|
||||
fseek(outfile, 0x14, SEEK_SET);
|
||||
WRITE(int2le(_filesize(outfile)), 4);
|
||||
WRITE(int2le(checksum(outfile)), 4);
|
||||
fclose(outfile);
|
||||
|
||||
fprintf(stderr, "[INFO] Done!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,321 +1,321 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define VERSION "0.2"
|
||||
|
||||
struct header{
|
||||
char main_header[20];
|
||||
unsigned int size;
|
||||
unsigned int checksum;
|
||||
unsigned int unknown;
|
||||
char other_header[32];
|
||||
};
|
||||
|
||||
static char* basepath(char* path)
|
||||
{
|
||||
static char tmp[255];
|
||||
char *ptr, *ptr2, *ptr3;
|
||||
ptr = path;
|
||||
ptr2 = (char*)tmp;
|
||||
#ifdef _WIN32
|
||||
ptr3 = strrchr(path, 0x5C);
|
||||
#else
|
||||
ptr3 = strrchr(path, 0x2F);
|
||||
#endif
|
||||
while((int)ptr < (int)ptr3)
|
||||
{
|
||||
*ptr2 = *ptr;
|
||||
ptr++;
|
||||
ptr2++;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
*ptr2 = 0x5C;
|
||||
#else
|
||||
*ptr2 = 0x2F;
|
||||
#endif
|
||||
ptr2++;
|
||||
*ptr2 = 0;
|
||||
return (char*)tmp;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static void replace(char* str)
|
||||
{
|
||||
char *ptr = str;
|
||||
while(*ptr != 0)
|
||||
{
|
||||
if(*ptr == 0x5C) /* \ */
|
||||
*ptr = 0x2F; /* / */
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int le2int(unsigned char* buf)
|
||||
{
|
||||
unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PATH_SEPARATOR '\\'
|
||||
#else
|
||||
#define PATH_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
static unsigned int __mkdir(const char *path)
|
||||
{
|
||||
char opath[256];
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
strncpy(opath, path, sizeof(opath));
|
||||
len = strlen(opath);
|
||||
if(opath[len - 1] == PATH_SEPARATOR)
|
||||
opath[len - 1] = '\0';
|
||||
for(p = opath; *p; p++)
|
||||
if(*p == PATH_SEPARATOR)
|
||||
{
|
||||
*p = '\0';
|
||||
if(access(opath, F_OK))
|
||||
#ifdef _WIN32
|
||||
mkdir(opath);
|
||||
#else
|
||||
mkdir(opath, S_IRWXU);
|
||||
#endif
|
||||
*p = PATH_SEPARATOR;
|
||||
}
|
||||
if(access(opath, F_OK))
|
||||
#ifdef _WIN32
|
||||
return mkdir(opath);
|
||||
#else
|
||||
return mkdir(opath, S_IRWXU);
|
||||
#endif
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool dir_exists(const char *dir)
|
||||
{
|
||||
struct stat buf;
|
||||
memset(&buf, 0, sizeof(struct stat));
|
||||
printf("start: %s\n", dir);
|
||||
char *dir_cpy = (char*)malloc(strlen(dir));
|
||||
strcpy(dir_cpy, dir);
|
||||
printf("%s\n", dir_cpy);
|
||||
int tmp = (int)dir_cpy;
|
||||
while(*dir_cpy != 0)
|
||||
{
|
||||
dir_cpy++;
|
||||
if(*dir_cpy == PATH_SEPARATOR && *(dir_cpy+1) == 0)
|
||||
*dir_cpy = 0;
|
||||
}
|
||||
printf("while_done\n");
|
||||
dir_cpy = (char*)tmp;
|
||||
printf("statting %s...\n", dir_cpy);
|
||||
tmp = stat(dir_cpy, &buf);
|
||||
printf("chk_dir(%s) = %d\n", dir_cpy, tmp);
|
||||
free(dir_cpy);
|
||||
return tmp == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool file_exists(const char *file)
|
||||
{
|
||||
struct stat buf;
|
||||
return stat(file, &buf) == 0;
|
||||
}
|
||||
|
||||
|
||||
static int split_hxf(const unsigned char* infile, unsigned int size, const char* outpath)
|
||||
{
|
||||
FILE *outfile;
|
||||
char *filename;
|
||||
unsigned int filenamesize, filesize;
|
||||
while(size > 0)
|
||||
{
|
||||
filenamesize = le2int((unsigned char*)infile);
|
||||
infile += 4;
|
||||
size -= 4;
|
||||
if(size > 0)
|
||||
{
|
||||
filename = (char*)calloc(1, filenamesize+1+strlen(outpath));
|
||||
memcpy(filename, outpath, strlen(outpath));
|
||||
memcpy(&filename[strlen(outpath)], infile, filenamesize);
|
||||
#ifndef _WIN32
|
||||
replace(filename);
|
||||
#endif
|
||||
infile += filenamesize + 1; /* + padding */
|
||||
size -= filenamesize + 1;
|
||||
|
||||
filesize = le2int((unsigned char*)infile);
|
||||
infile += 4;
|
||||
size -= 4;
|
||||
#if 0
|
||||
if(!dir_exists(basepath(filename)))
|
||||
#endif
|
||||
{
|
||||
printf("[INFO] %s\n", basepath(filename));
|
||||
if(__mkdir(basepath(filename)) != 0)
|
||||
{
|
||||
#if 0
|
||||
fprintf(stderr, "[ERR] Error creating directory %s\n", basepath(filename));
|
||||
return -3;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(!file_exists(filename))
|
||||
{
|
||||
printf("[INFO] %s: %d bytes\n", filename, filesize);
|
||||
if((outfile = fopen(filename, "wb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Error opening file %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
if(filesize>0)
|
||||
{
|
||||
if(fwrite(infile, filesize, 1, outfile) != 1)
|
||||
{
|
||||
fclose(outfile);
|
||||
fprintf(stderr, "[ERR] Error writing to file %s\n", filename);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
infile += filesize;
|
||||
size -= filesize;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Usage: hxfsplit.exe [FW] [OUTPUT_DIR]\n\n");
|
||||
fprintf(stderr, "Example: hxfsplit.exe VX747.HXF VX747_extracted\\\n\n");
|
||||
#else
|
||||
fprintf(stderr, "Usage: HXFsplit [FW] [OUTPUT_DIR]\n\n");
|
||||
fprintf(stderr, "Example: HXFsplit VX747.HXF VX747_extracted/\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *infile;
|
||||
struct header hdr;
|
||||
unsigned char *inbuffer;
|
||||
|
||||
fprintf(stderr, "HXFsplit v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
|
||||
fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
|
||||
fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
|
||||
|
||||
if(argc != 3)
|
||||
{
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(strcmp((char*)(argv[2]+strlen(argv[2])-1), "\\") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Output path must end with a \\\n");
|
||||
#else
|
||||
if(strcmp((char*)(argv[2]+strlen(argv[2])-1), "/") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Output path must end with a /\n");
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
if((infile = fopen(argv[1], "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[1]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if((inbuffer = (unsigned char*)malloc(sizeof(struct header))) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Error allocating %d bytes buffer\n", sizeof(struct header));
|
||||
return 4;
|
||||
}
|
||||
|
||||
if(fread(inbuffer, sizeof(struct header), 1, infile) != 1)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "Cannot read header of %s\n", argv[1]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
memcpy(hdr.main_header, inbuffer, 20);
|
||||
hdr.size = le2int(&inbuffer[20]);
|
||||
hdr.checksum = le2int(&inbuffer[24]);
|
||||
hdr.unknown = le2int(&inbuffer[28]);
|
||||
memcpy(hdr.other_header, &inbuffer[32], 32);
|
||||
free(inbuffer);
|
||||
|
||||
if(strcmp(hdr.other_header, "Chinachip PMP firmware V1.0") != 0)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Header doesn't match\n");
|
||||
return 6;
|
||||
}
|
||||
|
||||
if((inbuffer = (unsigned char*)malloc(hdr.size)) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Error allocating %d bytes buffer\n", hdr.size);
|
||||
return 7;
|
||||
}
|
||||
|
||||
fseek(infile, sizeof(struct header), SEEK_SET);
|
||||
|
||||
if(fread(inbuffer, hdr.size-sizeof(struct header), 1, infile) != 1)
|
||||
{
|
||||
fclose(infile);
|
||||
free(inbuffer);
|
||||
fprintf(stderr, "[ERR] Cannot read file in buffer\n");
|
||||
return 8;
|
||||
}
|
||||
|
||||
fclose(infile);
|
||||
|
||||
split_hxf(inbuffer, hdr.size-sizeof(struct header), argv[2]);
|
||||
|
||||
free(inbuffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define VERSION "0.2"
|
||||
|
||||
struct header{
|
||||
char main_header[20];
|
||||
unsigned int size;
|
||||
unsigned int checksum;
|
||||
unsigned int unknown;
|
||||
char other_header[32];
|
||||
};
|
||||
|
||||
static char* basepath(char* path)
|
||||
{
|
||||
static char tmp[255];
|
||||
char *ptr, *ptr2, *ptr3;
|
||||
ptr = path;
|
||||
ptr2 = (char*)tmp;
|
||||
#ifdef _WIN32
|
||||
ptr3 = strrchr(path, 0x5C);
|
||||
#else
|
||||
ptr3 = strrchr(path, 0x2F);
|
||||
#endif
|
||||
while((int)ptr < (int)ptr3)
|
||||
{
|
||||
*ptr2 = *ptr;
|
||||
ptr++;
|
||||
ptr2++;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
*ptr2 = 0x5C;
|
||||
#else
|
||||
*ptr2 = 0x2F;
|
||||
#endif
|
||||
ptr2++;
|
||||
*ptr2 = 0;
|
||||
return (char*)tmp;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static void replace(char* str)
|
||||
{
|
||||
char *ptr = str;
|
||||
while(*ptr != 0)
|
||||
{
|
||||
if(*ptr == 0x5C) /* \ */
|
||||
*ptr = 0x2F; /* / */
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int le2int(unsigned char* buf)
|
||||
{
|
||||
unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PATH_SEPARATOR '\\'
|
||||
#else
|
||||
#define PATH_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
static unsigned int __mkdir(const char *path)
|
||||
{
|
||||
char opath[256];
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
strncpy(opath, path, sizeof(opath));
|
||||
len = strlen(opath);
|
||||
if(opath[len - 1] == PATH_SEPARATOR)
|
||||
opath[len - 1] = '\0';
|
||||
for(p = opath; *p; p++)
|
||||
if(*p == PATH_SEPARATOR)
|
||||
{
|
||||
*p = '\0';
|
||||
if(access(opath, F_OK))
|
||||
#ifdef _WIN32
|
||||
mkdir(opath);
|
||||
#else
|
||||
mkdir(opath, S_IRWXU);
|
||||
#endif
|
||||
*p = PATH_SEPARATOR;
|
||||
}
|
||||
if(access(opath, F_OK))
|
||||
#ifdef _WIN32
|
||||
return mkdir(opath);
|
||||
#else
|
||||
return mkdir(opath, S_IRWXU);
|
||||
#endif
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool dir_exists(const char *dir)
|
||||
{
|
||||
struct stat buf;
|
||||
memset(&buf, 0, sizeof(struct stat));
|
||||
printf("start: %s\n", dir);
|
||||
char *dir_cpy = (char*)malloc(strlen(dir));
|
||||
strcpy(dir_cpy, dir);
|
||||
printf("%s\n", dir_cpy);
|
||||
int tmp = (int)dir_cpy;
|
||||
while(*dir_cpy != 0)
|
||||
{
|
||||
dir_cpy++;
|
||||
if(*dir_cpy == PATH_SEPARATOR && *(dir_cpy+1) == 0)
|
||||
*dir_cpy = 0;
|
||||
}
|
||||
printf("while_done\n");
|
||||
dir_cpy = (char*)tmp;
|
||||
printf("statting %s...\n", dir_cpy);
|
||||
tmp = stat(dir_cpy, &buf);
|
||||
printf("chk_dir(%s) = %d\n", dir_cpy, tmp);
|
||||
free(dir_cpy);
|
||||
return tmp == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool file_exists(const char *file)
|
||||
{
|
||||
struct stat buf;
|
||||
return stat(file, &buf) == 0;
|
||||
}
|
||||
|
||||
|
||||
static int split_hxf(const unsigned char* infile, unsigned int size, const char* outpath)
|
||||
{
|
||||
FILE *outfile;
|
||||
char *filename;
|
||||
unsigned int filenamesize, filesize;
|
||||
while(size > 0)
|
||||
{
|
||||
filenamesize = le2int((unsigned char*)infile);
|
||||
infile += 4;
|
||||
size -= 4;
|
||||
if(size > 0)
|
||||
{
|
||||
filename = (char*)calloc(1, filenamesize+1+strlen(outpath));
|
||||
memcpy(filename, outpath, strlen(outpath));
|
||||
memcpy(&filename[strlen(outpath)], infile, filenamesize);
|
||||
#ifndef _WIN32
|
||||
replace(filename);
|
||||
#endif
|
||||
infile += filenamesize + 1; /* + padding */
|
||||
size -= filenamesize + 1;
|
||||
|
||||
filesize = le2int((unsigned char*)infile);
|
||||
infile += 4;
|
||||
size -= 4;
|
||||
#if 0
|
||||
if(!dir_exists(basepath(filename)))
|
||||
#endif
|
||||
{
|
||||
printf("[INFO] %s\n", basepath(filename));
|
||||
if(__mkdir(basepath(filename)) != 0)
|
||||
{
|
||||
#if 0
|
||||
fprintf(stderr, "[ERR] Error creating directory %s\n", basepath(filename));
|
||||
return -3;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(!file_exists(filename))
|
||||
{
|
||||
printf("[INFO] %s: %d bytes\n", filename, filesize);
|
||||
if((outfile = fopen(filename, "wb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Error opening file %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
if(filesize>0)
|
||||
{
|
||||
if(fwrite(infile, filesize, 1, outfile) != 1)
|
||||
{
|
||||
fclose(outfile);
|
||||
fprintf(stderr, "[ERR] Error writing to file %s\n", filename);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
infile += filesize;
|
||||
size -= filesize;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Usage: hxfsplit.exe [FW] [OUTPUT_DIR]\n\n");
|
||||
fprintf(stderr, "Example: hxfsplit.exe VX747.HXF VX747_extracted\\\n\n");
|
||||
#else
|
||||
fprintf(stderr, "Usage: HXFsplit [FW] [OUTPUT_DIR]\n\n");
|
||||
fprintf(stderr, "Example: HXFsplit VX747.HXF VX747_extracted/\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *infile;
|
||||
struct header hdr;
|
||||
unsigned char *inbuffer;
|
||||
|
||||
fprintf(stderr, "HXFsplit v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
|
||||
fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
|
||||
fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
|
||||
|
||||
if(argc != 3)
|
||||
{
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(strcmp((char*)(argv[2]+strlen(argv[2])-1), "\\") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Output path must end with a \\\n");
|
||||
#else
|
||||
if(strcmp((char*)(argv[2]+strlen(argv[2])-1), "/") != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Output path must end with a /\n");
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
if((infile = fopen(argv[1], "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "[ERR] Cannot open %s\n", argv[1]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if((inbuffer = (unsigned char*)malloc(sizeof(struct header))) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Error allocating %d bytes buffer\n", sizeof(struct header));
|
||||
return 4;
|
||||
}
|
||||
|
||||
if(fread(inbuffer, sizeof(struct header), 1, infile) != 1)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "Cannot read header of %s\n", argv[1]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
memcpy(hdr.main_header, inbuffer, 20);
|
||||
hdr.size = le2int(&inbuffer[20]);
|
||||
hdr.checksum = le2int(&inbuffer[24]);
|
||||
hdr.unknown = le2int(&inbuffer[28]);
|
||||
memcpy(hdr.other_header, &inbuffer[32], 32);
|
||||
free(inbuffer);
|
||||
|
||||
if(strcmp(hdr.other_header, "Chinachip PMP firmware V1.0") != 0)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Header doesn't match\n");
|
||||
return 6;
|
||||
}
|
||||
|
||||
if((inbuffer = (unsigned char*)malloc(hdr.size)) == NULL)
|
||||
{
|
||||
fclose(infile);
|
||||
fprintf(stderr, "[ERR] Error allocating %d bytes buffer\n", hdr.size);
|
||||
return 7;
|
||||
}
|
||||
|
||||
fseek(infile, sizeof(struct header), SEEK_SET);
|
||||
|
||||
if(fread(inbuffer, hdr.size-sizeof(struct header), 1, infile) != 1)
|
||||
{
|
||||
fclose(infile);
|
||||
free(inbuffer);
|
||||
fprintf(stderr, "[ERR] Cannot read file in buffer\n");
|
||||
return 8;
|
||||
}
|
||||
|
||||
fclose(infile);
|
||||
|
||||
split_hxf(inbuffer, hdr.size-sizeof(struct header), argv[2]);
|
||||
|
||||
free(inbuffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue