Commit 2346af14 authored by Robert Sprowson's avatar Robert Sprowson
Browse files

Separate out the xpand tool

Xpand becomes a tool in its own right, since it only shared a header file with squeeze.

Version 5.15. Tagged as 'squeeze-5_15'
parent 2cac98fc
...@@ -14,4 +14,3 @@ ...@@ -14,4 +14,3 @@
| |
Dir <Obey$Dir> Dir <Obey$Dir>
amu_machine all COMPONENT=squeeze THROWBACK=-throwback amu_machine all COMPONENT=squeeze THROWBACK=-throwback
amu_machine all COMPONENT=xpand THROWBACK=-throwback
...@@ -14,5 +14,4 @@ ...@@ -14,5 +14,4 @@
| |
Dir <Obey$Dir> Dir <Obey$Dir>
amu_machine clean COMPONENT=squeeze amu_machine clean COMPONENT=squeeze
amu_machine clean COMPONENT=xpand
stripdepnd Makefile stripdepnd Makefile
...@@ -15,4 +15,3 @@ ...@@ -15,4 +15,3 @@
Dir <Obey$Dir> Dir <Obey$Dir>
amu_machine install COMPONENT=squeeze INSTTYPE=tool THROWBACK=-throwback INSTDIR=<Install$Dir>.Library amu_machine install COMPONENT=squeeze INSTTYPE=tool THROWBACK=-throwback INSTDIR=<Install$Dir>.Library
amu_machine install COMPONENT=squeeze INSTTYPE=app THROWBACK=-throwback INSTDIR=<Install$Dir>.Tools.Tools amu_machine install COMPONENT=squeeze INSTTYPE=app THROWBACK=-throwback INSTDIR=<Install$Dir>.Tools.Tools
amu_machine install COMPONENT=xpand INSTTYPE=tool THROWBACK=-throwback INSTDIR=<Install$Dir>.Library
...@@ -12,17 +12,12 @@ ...@@ -12,17 +12,12 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# Makefile for squeeze (a.k.a. armsqueeze) and xpand # Makefile for squeeze
# #
COMPONENT ?= squeeze COMPONENT ?= squeeze
INSTAPP = ${INSTDIR}${SEP}!Squeeze INSTAPP = ${INSTDIR}${SEP}!Squeeze
ifneq (xpand,${COMPONENT})
OBJS = squeeze unsqueeze1 unsqrm1 OBJS = squeeze unsqueeze1 unsqrm1
else
OBJS = xpand asmcall
endif
LIBS = ${CLXLIB} LIBS = ${CLXLIB}
CDEFINES = -DDEBUGGING=0 CDEFINES = -DDEBUGGING=0
INSTAPP_FILES = !Boot !Help !Run !Setup !Sprites [!Sprites11] !Sprites22 Desc Messages Templates INSTAPP_FILES = !Boot !Help !Run !Setup !Sprites [!Sprites11] !Sprites22 Desc Messages Templates
......
/* (5.14) /* (5.15)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1. * Last processed by srccommit version: 1.1.
* *
*/ */
#define Module_MajorVersion_CMHG 5.14 #define Module_MajorVersion_CMHG 5.15
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 26 Mar 2015 #define Module_Date_CMHG 27 Mar 2015
#define Module_MajorVersion "5.14" #define Module_MajorVersion "5.15"
#define Module_Version 514 #define Module_Version 515
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "26 Mar 2015" #define Module_Date "27 Mar 2015"
#define Module_ApplicationDate "26-Mar-15" #define Module_ApplicationDate "27-Mar-15"
#define Module_ComponentName "squeeze" #define Module_ComponentName "squeeze"
#define Module_ComponentPath "castle/RiscOS/Tools/Sources/squeeze" #define Module_ComponentPath "castle/RiscOS/Tools/Sources/squeeze"
#define Module_FullVersion "5.14" #define Module_FullVersion "5.15"
#define Module_HelpVersion "5.14 (26 Mar 2015)" #define Module_HelpVersion "5.15 (27 Mar 2015)"
#define Module_LibraryVersionInfo "5:14" #define Module_LibraryVersionInfo "5:15"
/* Copyright 1999 Element 14 Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Title: xpand - decompression of squeezed AIF executable images
* Author: RCC
* Copyright: (C) 1988, Acorn Computers Ltd, Cambridge, England.
* Date: 24-Mar-88
* LastEdit: 24-Mar-88
* 22Feb99: SJM: Note started to convert this to be able to run on
* Solaris. However this isn't easily possible since currently it xpands
* by running the unsqueeze code embedded in the code.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "CLX/wholefls.h"
#ifdef __riscos
#include "CLib/kernel.h"
#include "CLib/swis.h"
#else
typedef struct {
int load, exec; /* load, exec addresses */
int start, end; /* start address/length, end address/attributes */
} _kernel_osfile_block;
#endif
#ifndef __riscos
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "squeeze.h"
#include "VersionNum"
#define DATE Module_Date
/* If macro value is empty, expression rewrites to "0 * + 1" which is zero. */
#if 0 * Module_MinorVersion_CMHG + 1 == 0
# define VSN Module_MajorVersion
#else
# define VSN Module_MajorVersion " (" Module_MinorVersion ")"
#endif
#define SELF "xpand"
typedef int func(int, int, int);
#ifndef __riscos
# include "asmcall1.h"
#else
extern int asmcall_call(func *, int, int, int);
extern int *asmcall_exit;
#endif
static int debug;
static int verbose;
#undef AIFPRELUDE /* musn't rely on this constant - it's changed over time */
/*
* Veneer on file-handling.
*/
#define SAVE 0
#define WRITEINFO 1
#define READINFO 5
#define LOAD 0xff
#define FILFOUND 1
#ifdef __riscos
static void arthurise(_kernel_osfile_block *info)
{ if ((info->load == info->exec) && (info->load == 0x8000)) {
/* can we use Arthur 'FF8' filetype ? */
if (_kernel_hostos() == _kernel_ARTHUR) {
/* This is Arthur - get time of day */
int data[2];
data[0] = 3;
if (_kernel_osword(14, data) != _kernel_ERROR) {
info->exec = data[0];
info->load = 0xfffff800 + (data[1] & 0xff);
}
}
}
}
#endif
static int fileinfo(_kernel_osfile_block *info, const char *name)
{
#ifdef __riscos
if (_kernel_osfile(READINFO, name, info) != FILFOUND)
return -1;
#else
struct stat buf;
int len, ftype;
if (stat(name, &buf) != 0) return -1;
len = strlen(name);
if (len > 4 && name[len-4] == ',')
ftype = (int)strtoul(name + len - 4, NULL, 16);
else
ftype = 0xfff;
info->load = 0xfff00000 | (ftype << 8);
info->exec = buf.st_mtime * 100 / 256;
info->start = buf.st_size;
info->end = 0;
#endif
return 0;
}
static void fatalerror(const char *format, const char *name) {
fputs(SELF ": ", stderr);
fprintf(stderr, format, name);
#ifdef __riscos
{ _kernel_oserror *e = _kernel_last_oserror();
if (e != 0) fprintf(stderr, " (host error %#x: %s)", e->errnum, e->errmess);
}
#endif
fputc('\n', stderr);
exit(1);
}
#define ROR(x, n) (((x)<<(32-(n))) | (((x)>>(n)) & ((1<<(32-(n)))-1)))
static int immfield(word inst) {
int shift = (inst & 0xf00) >> 7;
int val = inst & 0xff;
return ROR(val, shift);
}
static SqueezeHeader *find_squeeze_header(int isaif, int *decompress)
{
/*
* The size of the decoded thing is stored 6 words before the
* start of the unsqueezing code (see squeeze.c).
*/
if (!isaif) {
/*
* Non-AIF images skip the first few instructions of the unsqueezing
* code; this has changed over time, so search backwards for
* MOV R0, #<imm>, which is always the first instruction
*/
while (((*decompress & 0xfffff000) != 0xe3a00000)) decompress--;
}
return (SqueezeHeader *) (decompress-SQUEEZEWORDS);
}
static int xpand(char *in, char *out)
{ _kernel_osfile_block info;
bool isaif, isdata;
int squeezedby = 0;
int size;
int *ws;
aifhdr *hdr;
char *lastb;
if (verbose)
fprintf(stderr, "-- xpanding '%s' to '%s'\n", in, out);
if (fileinfo(&info, in) == -1)
fatalerror("no file '%s'", in);
size = info.start;
ws = (int *)malloc(size + sizeof(int) + (24*1024)); /* allow space for unsqueezing */
hdr = (aifhdr *)(ws + 1);
if (wf_load(in, hdr, size) == -1)
fatalerror("can't load '%s'", in);
if ((info.load & 0xfc000000) != 0) { /* Not a valid address */
if ((info.load & 0xffffff00) == 0xfffff800) { /* Arthur absolute */
info.load = 0x8000; info.exec = 0x8000;
} else if ((info.load & 0xffffff00) != SQUEEZED) {
info.exec = info.load;
}
}
if ((size & 15) == 15 &&
((hdr->bl_decompress & ~B_OFFSET) == BL ||
(hdr->bl_decompress & ~B_OFFSET) == B)
) {
int d1, d2, d3;
lastb = (char *)hdr + size;
while (*--lastb == ' ') /* nothing */;
if (isdigit(d3 = *--lastb) &&
isdigit(d2 = *--lastb) &&
*--lastb == '.' &&
isdigit(d1 = *--lastb) &&
*--lastb == ' ' &&
*--lastb == 'c' &&
*--lastb == 'c' &&
*--lastb == 'r')
squeezedby = (d1-'0')*100+(d2-'0')*10+(d3-'0');
}
if (squeezedby == 0)
fatalerror("'%s' is not squeezed", in);
if (hdr->swi_exit == 0xef000011) /* OK, it's AIF */
isdata = NO, isaif = YES;
else if (((datahdr *)hdr)->datamagic == DATAMAGIC) /* OK, it's squeezed data */
isdata = YES, isaif = NO;
else
isdata = NO, isaif = NO;
{ int *decompress = &(((int *)hdr)[(hdr->bl_decompress & B_OFFSET) + PREFETCH]);
SqueezeHeader *h = find_squeeze_header(isaif, decompress);
int realsize = h->decodedsize;
word *lastw = (word *)lastb - 1;
if (debug)
fprintf(stderr, "decodedsize %x encodedsize %x encodedtabs %x\n"
"nshorts %x nlongs %x bytestomove %x\n"
"squeezer %d.%02d\n",
h->decodedsize, h->encodedsize, h->encodedtabs,
h->nshorts, h->nlongs, h->bytestomove,
squeezedby/100, squeezedby%100);
/* Arrange to get back control after decompression. We can't plant a
branch, since the decompression code gets shifted up store before
executing (and we'd rather not know the details). We rely on the
fact that at the end of decompression, r8 points to the base of the
decompressed image and this is followed by
SUB r8, r8, #&7c
MOV pc, r8
(for aif images) or
ADD r8, r8, #exec_address - load_address
MOV pc, r8
(otherwise)
*/
if (((int)lastb & 3) != 0 ||
*lastw != MOV_PC_R8)
fatalerror("format error in '%s'", in);
if (isaif) {
int backwards;
for (backwards = 1; backwards < 8; ++backwards) {
if (*(lastw-backwards) == (SUB_R8_R8_0 | 0x7c)) break;
}
if (backwards == 8) {
fatalerror("aif format error in '%s' (end of expansion code not found)", in);
}
*(lastw-backwards) = (SUB_R8_R8_0 | 0x80);
} else {
int execoffset = 0;
for (;; lastw--) {
word inst = *(lastw-1);
if ((inst & ~0xfff) == ADD_R8_R8_0)
execoffset += immfield(inst);
else if ((inst & ~0xfff) == SUB_R8_R8_0)
execoffset -= immfield(inst);
else
break;
}
info.exec += execoffset;
}
*lastw = LDR_PC_R8_MINUS4;
*ws = (int)(&asmcall_exit);
asmcall_call((func *)hdr, 0, 0, 0);
/*
* Just have to save it again.
*/
if (isdata) {
datahdr *d = (datahdr *)hdr;
info.load = (int)d->load;
info.exec = d->exec;
info.start = (int)(d+1);
info.end = info.start + d->size;
} else {
#ifdef __riscos
arthurise(&info);
#endif
info.start = (int)hdr;
if (isaif)
info.end = info.start + sizeof(*hdr) + realsize;
else
info.end = info.start + realsize;
}
if (wf_save(out, (void *)info.start, info.end - info.start) == -1)
fatalerror("failed to write '%s'", out);
#ifdef __riscos
_swix(OS_File, _INR(0,2), 18, out, (info.load << 12) >> 20);
#endif
return(0);
}
}
static void help(void)
{
fprintf(stderr, "\n%s vsn %s [%s] - \n", SELF, VSN, DATE);
fprintf(stderr, "takes an executable AIF image or data file compressed by\n");
fprintf(stderr, "'squeeze' and decompresses it to reproduce the original image\n");
fprintf(stderr, "(possibly with an extra 4 bytes of zeros on the end).\n\n");
fprintf(stderr, "syntax: xpand <squeezed-file> [<unsqueezed-file>]\n");
}
int main(int argc, char *argv[])
{ int j;
char *arg;
char *a = NULL;
char *b = NULL;
char c;
debug = verbose = 0;
for (j = 1; j < argc; ++j) {
arg = argv[j];
if (arg[0] == '-') {
c = arg[1];
if (('A' <= c) && (c <= 'Z')) c += ('a' - 'A');
switch (c) {
case 'h': help(); exit(0);
case 'q': ++debug; break;
case 'v': ++verbose; break;
default:
fprintf(stderr, SELF ": flag '%c' not recognised", c);
help();
exit(1);
}
} else { /* a filename */
if (a == NULL) a = arg;
else if (b == NULL) b = arg;
else {
fatalerror("too many args '%s'", arg);
}
}
}
if (a == NULL) fatalerror("need <file-to-xpand>", 0);
if (b == NULL) b = a; /* xpand it to itself */
return(xpand(a, b));
}
...@@ -16,10 +16,8 @@ if [ -n "$BUILDUSINGSUBSHELL" ]; then ...@@ -16,10 +16,8 @@ if [ -n "$BUILDUSINGSUBSHELL" ]; then
if [ $TARGET == "install" ]; then if [ $TARGET == "install" ]; then
Env/$BUILD.sh "cd $HERE && make install COMPONENT=squeeze INSTTYPE=tool INSTDIR=$INSTALLDIR/Library -I\$MAKEFILEDIR --no-print-directory" Env/$BUILD.sh "cd $HERE && make install COMPONENT=squeeze INSTTYPE=tool INSTDIR=$INSTALLDIR/Library -I\$MAKEFILEDIR --no-print-directory"
Env/$BUILD.sh "cd $HERE && make install COMPONENT=squeeze INSTTYPE=app INSTDIR=$INSTALLDIR/Tools/Tools -I\$MAKEFILEDIR --no-print-directory" Env/$BUILD.sh "cd $HERE && make install COMPONENT=squeeze INSTTYPE=app INSTDIR=$INSTALLDIR/Tools/Tools -I\$MAKEFILEDIR --no-print-directory"
Env/$BUILD.sh "cd $HERE && make install COMPONENT=xpand INSTTYPE=tool INSTDIR=$INSTALLDIR/Library -I\$MAKEFILEDIR --no-print-directory"
else else
Env/$BUILD.sh "cd $HERE && make $TARGET COMPONENT=squeeze -I\$MAKEFILEDIR --no-print-directory" Env/$BUILD.sh "cd $HERE && make $TARGET COMPONENT=squeeze -I\$MAKEFILEDIR --no-print-directory"
Env/$BUILD.sh "cd $HERE && make $TARGET COMPONENT=xpand -I\$MAKEFILEDIR --no-print-directory"
fi fi
else else
pushd ../../../../.. > /dev/null pushd ../../../../.. > /dev/null
...@@ -28,9 +26,7 @@ else ...@@ -28,9 +26,7 @@ else
if [ $TARGET == "install" ]; then if [ $TARGET == "install" ]; then
make install COMPONENT=squeeze INSTTYPE=tool INSTDIR=$INSTALLDIR/Library -I$MAKEFILEDIR --no-print-directory make install COMPONENT=squeeze INSTTYPE=tool INSTDIR=$INSTALLDIR/Library -I$MAKEFILEDIR --no-print-directory
make install COMPONENT=squeeze INSTTYPE=app INSTDIR=$INSTALLDIR/Tools/Tools -I$MAKEFILEDIR --no-print-directory make install COMPONENT=squeeze INSTTYPE=app INSTDIR=$INSTALLDIR/Tools/Tools -I$MAKEFILEDIR --no-print-directory
make install COMPONENT=xpand INSTTYPE=tool INSTDIR=$INSTALLDIR/Library -I$MAKEFILEDIR --no-print-directory
else else
make $TARGET COMPONENT=squeeze -I$MAKEFILEDIR --no-print-directory make $TARGET COMPONENT=squeeze -I$MAKEFILEDIR --no-print-directory
make $TARGET COMPONENT=xpand -I$MAKEFILEDIR --no-print-directory
fi fi
fi fi
; Copyright 1999 Element 14 Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > s.asmcall RCC 24-Mar-88
;
; This makes it possible to call code which scribbles on all the
; registers with a standard ARM procedure call, e.g. from C.
;
; If the code called also scribbles on lk, you must regain control
; by forcing it to branch to asmcall_exit.
;
; NB it relies on scribbling on memory addressed pc-relative, so it
; won't work if the code area is not writable.
;
r0 RN 0
r1 RN 1
r2 RN 2
r3 RN 3
r4 RN 4
ip RN 12
lk RN 14
pc RN 15
AREA |C$$code|, CODE, READONLY
EXPORT asmcall_call
EXPORT asmcall_exit
asmcall_savedregs
DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 11 words for registers
asmcall_call
; Enter with r0: thing to call
; r1, r2, r3: parameters for it
ADR ip, asmcall_savedregs
STMIA ip, {r4-lk}
MOV ip, r0
MOV r0, r1
MOV r1, r2
MOV r2, r3
MOV lk, pc
MOV pc, ip
asmcall_exit
NOP ; 2 spurious instructions here in case the caller
NOP ; forgets to allow for prefetch ...
ADR ip, asmcall_savedregs
LDMIA ip, {r4-lk}
MOV pc, lk
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment