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:
Rafaël Carré 2010-06-17 16:59:51 +00:00
parent 3d2b1cfa6e
commit c0bd4173aa
23 changed files with 14110 additions and 14110 deletions

View file

@ -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

View file

@ -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__ */

File diff suppressed because it is too large Load diff

View file

@ -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 Apples 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 ProFonts 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?
Heres a sample:
[ see "provsmonaco.gif" and "profomac.gif" ]
Also, each font folder in the ProFont distribution contains a file showing the fonts character set at 9 and 18 point sizes. You dont 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. Its 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, Ill 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 fonts 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 dont 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: “lets make it free though [...] just credit me for making the font in the first place, and youre good to go!” Andrews 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
“Arent 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 Apples 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 ProFonts 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?
Heres a sample:
[ see "provsmonaco.gif" and "profomac.gif" ]
Also, each font folder in the ProFont distribution contains a file showing the fonts character set at 9 and 18 point sizes. You dont 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. Its 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, Ill 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 fonts 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 dont 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: “lets make it free though [...] just credit me for making the font in the first place, and youre good to go!” Andrews 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
“Arent those instructions a little bit too complicated?”.

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -1,2 +1,2 @@
SUBDIRS = rbutilqt
SUBDIRS = rbutilqt
TEMPLATE = subdirs

View file

@ -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

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}