mirror of
https://github.com/GerbilSoft/rom-properties.git
synced 2025-06-19 03:55:43 -04:00

Fixes the following 64-bit MSVC warnings: unice68_pack.c(243,43): warning C4244: '=': conversion from '__int64' to 'dreg_t', possible loss of data unice68_pack.c(319,28): warning C4244: '=': conversion from '__int64' to 'dreg_t', possible loss of data unice68_pack.c(325,36): warning C4244: '=': conversion from '__int64' to 'dreg_t', possible loss of data unice68_pack.c(456,40): warning C4244: '=': conversion from '__int64' to 'dreg_t', possible loss of data unice68_pack.c(488,36): warning C4244: '=': conversion from '__int64' to 'dreg_t', possible loss of data
615 lines
14 KiB
C
Vendored
615 lines
14 KiB
C
Vendored
/*
|
|
* @file ice68_pack.c
|
|
* @brief Ice Packer 2.35 (native version)
|
|
* @author http://sourceforge.net/users/benjihan
|
|
*
|
|
* Copyright (c) 1998-2016 Benjamin Gerard
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.unice68.h"
|
|
#endif
|
|
|
|
#include "unice68_private.h"
|
|
#include "unice68.h"
|
|
|
|
#ifdef HAVE_STDINT_H
|
|
# include <stdint.h>
|
|
#endif
|
|
#ifdef HAVE_ASSERT_H
|
|
# include <assert.h>
|
|
#endif
|
|
|
|
typedef uint8_t * areg_t;
|
|
typedef int dreg_t;
|
|
|
|
typedef struct {
|
|
areg_t a0,a1,a2,a3,a4,a5,a6,ax;
|
|
dreg_t d0,d1,d2,d3,d4,d5,d6,d7;
|
|
areg_t srcbuf,srcend,dstbuf,dstend;
|
|
int srclen, dstlen, dstmax;
|
|
int error, optimize, maxlength, maxgleich, maxoffset;
|
|
} all_regs_t;
|
|
|
|
#define ICE_MAGIC 0x49636521 /* 'Ice!' */
|
|
|
|
#define EQ(A,B) ((A) == (B))
|
|
#define NE(A,B) ((A) != (B))
|
|
|
|
#define GE(A,B) ((A) <= (B))
|
|
#define LE(A,B) ((A) >= (B))
|
|
#define HI(A,B) ((A) < (B))
|
|
#define LS(A,B) ((A) >= (B))
|
|
#define GT(A,B) ((A) < (B))
|
|
#define LT(A,B) ((A) > (B))
|
|
|
|
#define B_CC(CC, LABEL) if (CC) {goto LABEL;} else
|
|
#define DB_CC(CC, REG, LABEL) if (!(CC) && --REG >= 0) {goto LABEL;} else
|
|
#define DBF(REG,LABEL) DB_CC(0, REG, LABEL)
|
|
#define DBF_COUNT(REG) ( ( (REG) & 0xFFFF ) + 1 )
|
|
|
|
#define BRA(LABEL) goto LABEL
|
|
#define BEQ(A, B, LABEL) B_CC( EQ(A,B), LABEL )
|
|
#define BNE(A, B, LABEL) B_CC( NE(A,B), LABEL )
|
|
#define BHI(A, B, LABEL) B_CC( HI(A,B), LABEL )
|
|
#define BGE(A, B, LABEL) B_CC( GE(A,B), LABEL )
|
|
#define BGT(A, B, LABEL) B_CC( GT(A,B), LABEL )
|
|
#define BLS(A, B, LABEL) B_CC( LS(A,B), LABEL )
|
|
#define BLE(A, B, LABEL) B_CC( LE(A,B), LABEL )
|
|
#define BLT(A, B, LABEL) B_CC( LT(A,B), LABEL )
|
|
|
|
#define DBGE(A,B,REG,LABEL) DB_CC( GE(A,B), REG, LABEL )
|
|
|
|
|
|
static void longword_store(all_regs_t *R);
|
|
static void put_bits(all_regs_t * R);
|
|
static void make_stringlength(all_regs_t * R);
|
|
static void make_normal_bytes(all_regs_t * R);
|
|
|
|
/* Store d7.l
|
|
*/
|
|
static void longword_store(all_regs_t *R)
|
|
{
|
|
*R->a1++ = R->d7 >> 24;
|
|
*R->a1++ = R->d7 >> 16;
|
|
*R->a1++ = R->d7 >> 8;
|
|
*R->a1++ = R->d7;
|
|
}
|
|
|
|
/* Store bit field
|
|
*
|
|
* d1[d4+1] bit field
|
|
* d7: bit acu
|
|
* d6: free bit in d7 minus 1
|
|
*/
|
|
static void put_bits(all_regs_t *R)
|
|
{
|
|
assert(R->d7 >= 0 && R->d7 < 0x100);
|
|
assert(R->d4 >= 0 && R->d4 < 32);
|
|
|
|
do {
|
|
R->d7 |= (R->d1 & 1) << 8;
|
|
R->d1 >>= 1;
|
|
R->d7 >>= 1;
|
|
if (--R->d6 < 0) {
|
|
*R->a1++ = R->d7;
|
|
R->d7 = 0;
|
|
R->d6 = 7;
|
|
}
|
|
} while (--R->d4 >= 0);
|
|
}
|
|
|
|
|
|
static void make_offset_2(all_regs_t * R)
|
|
{
|
|
/* move.w d0,d1 */
|
|
R->d1 = R->d0;
|
|
/* cmpi.w #$3f,d1 */
|
|
/* ble.s offs_3f */
|
|
BLE ( 0x3f, R->d1, offs_3f );
|
|
/* subi.w #$40,d1 */
|
|
R->d1 -= 0x40;
|
|
/* moveq #9,d4 */
|
|
R->d4 = 9;
|
|
/* bset d4,d1 */
|
|
R->d1 |= 1 << R->d4;
|
|
/* bra put_bits */
|
|
goto put;
|
|
offs_3f:
|
|
/* moveq #6,d4 */
|
|
R->d4 = 6;
|
|
put:
|
|
/* bra.s put_bits */
|
|
put_bits(R);
|
|
}
|
|
|
|
static void make_offset_mehr(all_regs_t * R)
|
|
{
|
|
static const int16_t table3[6] = {
|
|
0x0000,0x0020,0x0120,
|
|
0x0606,0x0908,0x0C0D
|
|
};
|
|
/* moveq #2,d3 */
|
|
R->d3 = 2;
|
|
look_on:
|
|
/* add.w d3,d3 */
|
|
/* move.w 0(a3,d3.w),d4 */
|
|
/* lsr.w #1,d3 */
|
|
R->d4 = table3[R->d3];
|
|
|
|
/* cmp.w d4,d0 */
|
|
/* dbge d3,look_on */
|
|
DBGE ( R->d4, R->d0, R->d3, look_on );
|
|
/* sub.w d4,d0 */
|
|
R->d0 -= R->d4;
|
|
|
|
/* add.w d3,d3 */
|
|
/* move.w 6(a3,d3.w),d3 */
|
|
/* move.w d3,d4 */
|
|
R->d4 = R->d3 = table3[3+R->d3];
|
|
/* lsr.w #8,d3 */
|
|
R->d3 >>= 8;
|
|
/* moveq #-1,d1 */
|
|
/* lsl.w d3,d1 */
|
|
/* or.w d0,d1 */
|
|
R->d1 = (-1 << R->d3) | R->d0;
|
|
/* andi.w #$f,d4 */
|
|
R->d4 &= 0xf;
|
|
/* bra put_bits */
|
|
put_bits(R);
|
|
}
|
|
|
|
static void make_stringlength(all_regs_t *R)
|
|
{
|
|
static const int ta[5] = { 0x2, 0x3, 0x4, 0x6, 0xa };
|
|
static const int tb[5] = { 0x1, 0x1, 0x2, 0x3, 0xa };
|
|
int i, d4, d0;
|
|
|
|
assert(R->maxlength >= 2);
|
|
for (i=4, d0 = R->maxlength;
|
|
d0 < (d4 = ta[i]);
|
|
--i);
|
|
d0 -= d4;
|
|
assert ( i >= 0 );
|
|
assert ( i < 5 );
|
|
d4 = tb[i];
|
|
R->d1 = (-1 << d4) | d0;
|
|
R->d4 = d4 + i - 1;
|
|
put_bits(R);
|
|
}
|
|
|
|
static int ice_crunch(all_regs_t *R)
|
|
{
|
|
R->a0 = R->srcbuf;
|
|
R->d0 = R->srclen;
|
|
|
|
mainloop:
|
|
|
|
/***********************************************************************
|
|
* 1. Sequence of identical bytes are looking for pay
|
|
*/
|
|
|
|
/* lea $409(a0),a4 */
|
|
R->a4 = R->a0 + 0x409; /* a4 = End of the search range */
|
|
/* cmpa.l src_ende,a4 */
|
|
/* ble.s gleich_ok */
|
|
BLE ( R->srcend, R->a4, gleich_ok);
|
|
/* movea.l src_ende,a4 */
|
|
R->a4 = R->srcend;
|
|
|
|
gleich_ok:
|
|
/* a0 : search start
|
|
* a3 : search current
|
|
* a4 : search end
|
|
*/
|
|
|
|
/* move.l a0,a3 */
|
|
R->a3 = R->a0; /* a3 = Beginning of the search range */
|
|
/* move.b (a3)+,d0 */
|
|
R->d0 = *R->a3++; /* current byte */
|
|
|
|
/* while ( R->d0 == *R->a3++ && R->a3 < R->a4) */
|
|
/* ; */
|
|
|
|
gleich_compare:
|
|
/* cmp.b (a3)+,d0 */
|
|
/* bne.s gleich_ende */
|
|
BNE( *R->a3++, R->d0, gleich_ende );
|
|
/* cmpa.l a4,a3 */
|
|
/* blt.s gleich_compare */
|
|
BLT ( R->a4, R->a3, gleich_compare );
|
|
gleich_ende:
|
|
|
|
/* move.l a3,d1 */
|
|
/* sub.l a0,d1 */
|
|
/* subq.l #2,d1 */
|
|
/* move.l d1,maxgleich */
|
|
R->maxgleich = R->d1 = (dreg_t)(R->a3 - R->a0 - 2);
|
|
|
|
/* cmp.l #$409,d1 */
|
|
/* beq gleich_ablegen */
|
|
BEQ (0x409, R->d1, gleich_ablegen);
|
|
|
|
|
|
/*************************************************************
|
|
* 2. Search string with the greatest possible length and a small offset
|
|
*/
|
|
|
|
/* move.l a0,a3 */
|
|
/* adda.l optimize(pc),a3 */
|
|
R->a3 = R->a0 + R->optimize;
|
|
/* cmpa.l src_ende,a3 */
|
|
/* ble.s offset_ende */
|
|
BLE ( R->srcend, R->a3, offset_ende );
|
|
/* movea.l src_ende,a3 */
|
|
R->a3 = R->srcend;
|
|
|
|
offset_ende:
|
|
/* if (R->a3 > R->srcend) */
|
|
/* R->a3 = R->srcend; */
|
|
|
|
/* moveq #1,d4 */
|
|
R->d4 = 1;
|
|
/* lea 2(a0),a4 */
|
|
R->a4 = R->a0 + 2;
|
|
|
|
weiter_mit_string:
|
|
/* move.b (a0),d0 */
|
|
R->d0 = *R->a0;
|
|
/* move.b 1(a0),d1 */
|
|
R->d1 = R->a0[1];
|
|
|
|
search_string:
|
|
/* cmp.b (a4)+,d0 */
|
|
/* beq.s ein_byte_stimmt */
|
|
BEQ ( *R->a4++, R->d0, ein_byte_stimmt );
|
|
|
|
no_string:
|
|
/* cmpa.l a4,a3 */
|
|
/* bgt.s search_string */
|
|
BGT ( R->a4, R->a3, search_string );
|
|
/* bra.s string_suche_fertig */
|
|
BRA(string_suche_fertig);
|
|
|
|
ein_byte_stimmt:
|
|
/* cmp.b (a4),d1 */
|
|
/* bne.s no_string */
|
|
BNE ( *R->a4, R->d1, no_string );
|
|
|
|
/* string_start_found: */
|
|
/* move.l a4,a6 */
|
|
/* subq.w #1,a6 */
|
|
R->a6 = R->a4 - 1;
|
|
/* move.l a6,d0 */
|
|
R->ax = R->a6;
|
|
/* movea.l a0,a5 */
|
|
R->a5 = R->a0;
|
|
|
|
string_compare:
|
|
/* cmpm.b (a5)+,(a6)+ */
|
|
/* bne.s string_zu_ende */
|
|
BNE ( *R->a5++, *R->a6++, string_zu_ende);
|
|
/* cmp.l d0,a5 */
|
|
/* bhi.s string_zu_ende */
|
|
BHI( R->ax, R->a5, string_zu_ende );
|
|
/* cmpa.l a6,a3 */
|
|
/* bgt.s string_compare */
|
|
BGT ( R->a6, R->a3, string_compare );
|
|
|
|
string_zu_ende:
|
|
/* move.l a5,d1 */
|
|
/* sub.l a0,d1 */
|
|
/* subq.l #1,d1 */
|
|
R->d1 = (dreg_t)(R->a5 - R->a0 - 1);
|
|
|
|
/* move.l a6,d2 */
|
|
/* sub.l a5,d2 */
|
|
/* sub.l d1,d2 */
|
|
/* addq.l #1,d2 */
|
|
R->d2 = (dreg_t)(R->a6 - R->a5 - R->d1 + 1);
|
|
|
|
/* move.l #$409,d0 */
|
|
R->d0 = 0x409; /* max string length */
|
|
|
|
/* cmp.l d0,d4 */
|
|
/* beq.s string_suche_fertig */
|
|
BEQ ( R->d0, R->d4, string_suche_fertig );
|
|
|
|
/* cmp.l d0,d1 */
|
|
/* bls.s not_too_large */
|
|
BLS ( R->d0, R->d1, not_too_large );
|
|
|
|
/* sub.l d0,d1 */
|
|
R->d1 -= R->d0;
|
|
/* add.l d1,d2 */
|
|
R->d2 += R->d1;
|
|
|
|
/* move.l d0,d1 */
|
|
R->d1 = R->d0;
|
|
not_too_large:
|
|
|
|
/* cmp.l d1,d4 */
|
|
/* bge.s string_lohnt_nicht */
|
|
BGE( R->d1, R->d4, string_lohnt_nicht );
|
|
/* cmp.w #2,d1 */
|
|
/* bls.s shortstring */
|
|
BLS ( 2, R->d1, shortstring );
|
|
/* cmp.w #$111f,d2 */
|
|
/* bhi.s string_lohnt_nicht */
|
|
BHI ( 0x111f, R->d2, string_lohnt_nicht );
|
|
|
|
shortstring:
|
|
/* move.l d1,d4 */
|
|
/* move.w d1,maxlength */
|
|
/* move.w d2,maxoffset */
|
|
R->maxlength = R->d4 = R->d1;
|
|
R->maxoffset = R->d2;
|
|
|
|
string_lohnt_nicht:
|
|
/* cmpa.l a4,a3 */
|
|
/* bgt weiter_mit_string */
|
|
BGT ( R->a4, R->a3, weiter_mit_string );
|
|
|
|
string_suche_fertig:
|
|
/* move.l maxgleich,d0 */
|
|
R->d0 = R->maxgleich;
|
|
/* cmp.w #1,d0 */
|
|
/* ble.s nogleich */
|
|
BLE ( 1, R->d0, nogleich );
|
|
/* cmp.l d4,d0 */
|
|
/* bge.s gleich_ablegen */
|
|
BGE( R->d4, R->d0, gleich_ablegen );
|
|
|
|
nogleich:
|
|
|
|
/* move.w maxoffset(pc),d0 */
|
|
R->d0 = R->maxoffset;
|
|
/* move.w d4,d1 */
|
|
R->d1 = R->d4;
|
|
/* cmpi.w #1,d1 */
|
|
/* beq.s ein_byte_ablegen */
|
|
BEQ ( 1, R->d1, ein_byte_ablegen );
|
|
/* cmpi.w #2,d1 */
|
|
/* beq.s zwei_byte_ablegen */
|
|
BEQ ( 2, R->d1, zwei_byte_ablegen );
|
|
/* bra.s mehr_bytes_ablegen */
|
|
BRA(mehr_bytes_ablegen);
|
|
|
|
/* ====================================================================== */
|
|
|
|
ein_byte_ablegen:
|
|
/* move.b (a0)+,(a1)+ */
|
|
|
|
/* fprintf(stdout,"%04x %02x (%s:%d) / ein_byte_ablegen\n", */
|
|
/* R->a1 - R->dstbuf, */
|
|
/* *R->a0, */
|
|
/* __FUNCTION__, __LINE__); */
|
|
*R->a1++ = *R->a0++;
|
|
/* addq.l #1,d5 */
|
|
R->d5++;
|
|
/* bra.s kein_byte_ablegen */
|
|
BRA ( kein_byte_ablegen );
|
|
|
|
gleich_ablegen:
|
|
/* move.l maxgleich,d1 */
|
|
R->d1 = R->maxgleich;
|
|
/* move.w d1,maxlength */
|
|
R->maxlength = R->d1;
|
|
/* moveq #0,d0 */
|
|
R->d0 = 0;
|
|
/* subq.l #2,d1 */
|
|
/* bne.s mehr_bytes_ablegen */
|
|
if ( (R->d1 -= 2) != 0 )
|
|
goto mehr_bytes_ablegen;
|
|
|
|
zwei_byte_ablegen:
|
|
/* cmpi.w #$23f,d0 */
|
|
/* bhi.s ein_byte_ablegen */
|
|
BHI( 0x23f, R->d0, ein_byte_ablegen );
|
|
/* bsr make_normal_bytes */
|
|
make_normal_bytes(R);
|
|
/* cmpi.w #$23f,d0 */
|
|
/* bhi ein_byte_ablegen */
|
|
BHI( 0x23f, R->d0, ein_byte_ablegen );
|
|
/* bsr make_offset_2 */
|
|
make_offset_2(R);
|
|
/* bra.s drop_length */
|
|
BRA(drop_length);
|
|
|
|
mehr_bytes_ablegen:
|
|
/* bsr make_normal_bytes */
|
|
make_normal_bytes(R);
|
|
/* bsr make_offset_mehr */
|
|
make_offset_mehr(R);
|
|
|
|
drop_length:
|
|
/* bsr make_stringlength */
|
|
make_stringlength(R);
|
|
/* moveq #0,d5 */
|
|
R->d5 = 0;
|
|
/* move.w maxlength(pc),d0 */
|
|
R->d0 = R->maxlength;
|
|
/* add.w d0,a0 */
|
|
R->a0 += R->d0;
|
|
|
|
kein_byte_ablegen:
|
|
/* move.l src_ende,d0 */
|
|
/* sub.l a0,d0 */
|
|
/* subq.l #3,d0 */
|
|
/* bpl mainloop */
|
|
if ( ( R->d0 = (dreg_t)(R->srcend - R->a0 - 3) ) >= 0 )
|
|
goto mainloop;
|
|
|
|
still_packing:
|
|
/* cmp.l src_ende,a0 */
|
|
/* bge.s all_packed */
|
|
BGE ( R->srcend, R->a0, all_packed );
|
|
/* move.b (a0)+,(a1)+ */
|
|
/* fprintf(stdout,"%04x %02x (%s:%d) / still_packing\n", */
|
|
/* R->a1 - R->dstbuf, */
|
|
/* *R->a0, */
|
|
/* __FUNCTION__ , __LINE__); */
|
|
*R->a1++ = *R->a0++;
|
|
/* addq.l #1,d5 */
|
|
R->d5++;
|
|
/* bra.s still_packing */
|
|
BRA(still_packing);
|
|
|
|
all_packed:
|
|
/* bsr make_normal_bytes */
|
|
make_normal_bytes(R);
|
|
/* bset d6,d7 */
|
|
/* move.b d7,(a1)+ */
|
|
|
|
/* fprintf(stdout,"%04x %02x (%s:%d) /all_packed\n", */
|
|
/* R->a1 - R->dstbuf, */
|
|
/* R->d7 | (1 << R->d6), */
|
|
/* __FUNCTION__ , __LINE__); */
|
|
*R->a1++ = R->d7 |= (1 << R->d6);
|
|
/* sub.l packed_data(pc),a1 */
|
|
/* move.l a1,d0 */
|
|
/* move.l d0,d7 */
|
|
R->d7 = R->d0 = (dreg_t)(R->a1 - R->dstbuf);
|
|
/* move.l packed_data,a1 */
|
|
/* addq.l #4,a1 */
|
|
/* bsr longword_store */
|
|
R->a1 = R->dstbuf + 4;
|
|
longword_store(R);
|
|
/* rts */
|
|
return R->d0;
|
|
}
|
|
|
|
static void make_normal_bytes(all_regs_t * R)
|
|
{
|
|
static const int t1a[7] = { 0, 1, 2, 5, 8, 15, 270 };
|
|
|
|
static const int tib[7][2] = {
|
|
{ 0x01,0x01 }, { 0x01, 0x02 }, { 0x02, 0x04 }, { 0x02, 0x06 },
|
|
{ 0x03,0x09 }, { 0x08, 0x11 }, { 0x0f, 0x20 }
|
|
};
|
|
|
|
/* cmp.l #$810d,d5 */
|
|
/* bls.s noerror */
|
|
BLS ( 0x810d, R->d5, noerror );
|
|
|
|
/* move.w #-1,error */
|
|
/* move.l a0,src_ende */
|
|
R->error = -1;
|
|
R->srcend = R->a0;
|
|
noerror:
|
|
|
|
/* lea.l table1(pc),a3 */
|
|
/* moveq #6,d3 */
|
|
R->d3 = 6;
|
|
kleiner:
|
|
/* move.w -(a3),d4 */
|
|
|
|
assert (R->d3 >= 0);
|
|
assert (R->d3 < 7);
|
|
R->d4 = t1a[R->d3];
|
|
/* cmp.w d4,d5 */
|
|
/* dbge d3,kleiner */
|
|
DBGE ( R->d4, R->d5, R->d3, kleiner );
|
|
/* sub.w d4,d5 */
|
|
R->d5 -= R->d4;
|
|
|
|
assert (R->d3 >= 0);
|
|
assert (R->d3 < 7);
|
|
|
|
R->d2 = tib[R->d3][0];
|
|
/* moveq #-1,d1 */
|
|
/* lsl.l d2,d1 */
|
|
/* or.w d5,d1 */
|
|
R->d1 = (-1 << R->d2) | R->d5;
|
|
/* moveq #0,d5 */
|
|
R->d5 = 0;
|
|
/* move.b (a3)+,d4 */
|
|
/* ext.w d4 */
|
|
/* subq.w #1,d4 */
|
|
R->d4 = tib[R->d3][1] - 1;
|
|
/* bra put_bits */
|
|
put_bits(R);
|
|
}
|
|
|
|
int unice68_packer(void * dst, int dstsz, const void * src, int srcsz)
|
|
{
|
|
all_regs_t allregs, *R = &allregs;
|
|
|
|
|
|
/***********************************************************************
|
|
* Save parameters
|
|
*/
|
|
R->srcbuf = (areg_t) src;
|
|
R->srcend = R->srcbuf + srcsz;
|
|
R->srclen = srcsz;
|
|
R->dstbuf = (areg_t) dst;
|
|
R->dstend = R->dstbuf + dstsz;
|
|
R->dstlen = 0;
|
|
R->dstmax = dstsz;
|
|
|
|
R->a0 = R->srcbuf;
|
|
R->d0 = R->srclen;
|
|
R->a1 = R->dstbuf;
|
|
|
|
R->a2 = R->a3 = R->a4 = R->a5 = R->a6 = 0;
|
|
|
|
R->error = 0;
|
|
R->optimize = 0x1580;
|
|
R->maxlength = 0;
|
|
R->maxgleich = 0;
|
|
R->maxoffset = 0;
|
|
|
|
/***********************************************************************
|
|
* Store header
|
|
*/
|
|
|
|
/* move.l #'Ice!',d7 */
|
|
/* bsr longword_store */
|
|
/* addq.l #4,a1 */
|
|
/* move.l filesize(pc),d7 */
|
|
/* bsr longword_store */
|
|
|
|
R->d7 = ICE_MAGIC; /* Store magic id 'Ice!' */
|
|
longword_store(R);
|
|
R->a1 += 4; /* Leave space for packed length */
|
|
R->d7 = R->srclen; /* Store unpacked length */
|
|
longword_store(R);
|
|
|
|
/* moveq #0,d5 */
|
|
/* moveq #0,d7 */
|
|
/* moveq #0,d4 */
|
|
/* moveq #0,d1 */
|
|
R->d1 = R->d2 = R->d3 = R->d4 = R->d5 = R->d7 = 0;
|
|
/* moveq #7,d6 */
|
|
R->d6 = 7;
|
|
/* bsr put_bits */
|
|
|
|
/* Store one bit for picture flag */
|
|
put_bits(R);
|
|
|
|
|
|
/* Main loop */
|
|
ice_crunch(R);
|
|
|
|
if (R->error)
|
|
R->d0 = -1;
|
|
|
|
return R->d0;
|
|
}
|