init files

This commit is contained in:
AArt1256 2025-11-13 19:07:39 +03:00
commit 8197a022bd
1409 changed files with 139317 additions and 0 deletions

View file

@ -0,0 +1,161 @@
; ByteBoozer Decruncher /HCL May.2003
; B2 Decruncher December 2014
; call: Y = AddrLo
; X = AddrHi
;Variables.. #Bytes
zp_base = $02 ; -
bits = zp_base ;1
put = zp_base+2 ;2
#macro GetNextBit() {.(
asl bits
bne DgEnd
jsr GetNewBits
DgEnd
.)}
#macro GetLen() {.(
lda #1
GlLoop
.GetNextBit()
bcc GlEnd
.GetNextBit()
rol
bpl GlLoop
GlEnd
.)}
Decrunch
sty Get1+1
sty Get2+1
sty Get3+1
stx Get1+2
stx Get2+2
stx Get3+2
ldx #0
jsr GetNewBits
sty put-1,x
cpx #2
bcc *-7
lda #$80
sta bits
DLoop
.GetNextBit()
bcs Match
Literal
; Literal run.. get length.
.GetLen()
sta LLen+1
ldy #0
LLoop
Get3 lda $feed,x
inx
bne *+5
jsr GnbInc
L1 sta (put),y
iny
LLen cpy #0
bne LLoop
clc
tya
adc put
sta put
bcc *+4
inc put+1
iny
beq DLoop
; Has to continue with a match..
Match
; Match.. get length.
.GetLen()
sta MLen+1
; Length 255 -> EOF
cmp #$ff
beq End
; Get num bits
cmp #2
lda #0
rol
.GetNextBit()
rol
.GetNextBit()
rol
tay
lda Tab,y
beq M8
; Get bits < 8
M_1 .GetNextBit()
rol
bcs M_1
bmi MShort
M8
; Get byte
eor #$ff
tay
Get2 lda $feed,x
inx
bne *+5
jsr GnbInc
jmp Mdone
MShort
ldy #$ff
Mdone
;clc
adc put
sta MLda+1
tya
adc put+1
sta MLda+2
ldy #$ff
MLoop iny
MLda lda $beef,y
sta (put),y
MLen cpy #0
bne MLoop
;sec
tya
adc put
sta put
bcc *+4
inc put+1
jmp DLoop
End rts
GetNewBits
Get1 ldy $feed,x
sty bits
rol bits
inx
bne GnbEnd
GnbInc inc Get1+2
inc Get2+2
inc Get3+2
GnbEnd
rts
Tab
; Short offsets
.byte %11011111 ; 3
.byte %11111011 ; 6
.byte %00000000 ; 8
.byte %10000000 ; 10
; Long offsets
.byte %11101111 ; 4
.byte %11111101 ; 7
.byte %10000000 ; 10
.byte %11110000 ; 13

9
loader/tools/b2/Makefile Normal file
View file

@ -0,0 +1,9 @@
CC = gcc
OBJECTS = \
file.c \
cruncher.c \
bb.c
all: $(OBJECTS)
$(CC) -O3 $(OBJECTS) -o b2.exe

77
loader/tools/b2/bb.c Normal file
View file

@ -0,0 +1,77 @@
#include "bb.h"
#include "file.h"
#include "cruncher.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[])
{
File myFile;
File myBBFile;
char* fileName;
bool isExecutable = false;
bool isRelocated = false;
uint address = 0;
if((argc != 2 && argc != 4) ||
(strcmp(argv[1], "-h") == 0) ||
(strcmp(argv[1], "-help") == 0)){
printf("Usage: b2 [-[c|e|r] xxxx] <filename>\n");
printf(" -c: Make executable with start address xxxx.\n");
printf(" -e: Same as -c :P.\n");
printf(" -r: Relocate file to hex address xxxx.\n");
return 0;
}
if(argc == 2) {
fileName = argv[1];
} else {
int i;
char *s = argv[2];
fileName = argv[3];
if((strcmp(argv[1], "-c") == 0) ||
(strcmp(argv[1], "-e") == 0))
isExecutable = true;
else if(strcmp(argv[1], "-r") == 0)
isRelocated = true;
else {
printf("Don't understand, aborting.\n");
return -1;
}
if(strlen(s) != 4){
printf("Don't understand, aborting.\n");
return -1;
}
for(i = 0; i < 4; ++i){
byte c;
if(s[i] >= '0' && s[i] <= '9') c = s[i] - '0';
if(s[i] >= 'a' && s[i] <= 'f') c = s[i] - 'a' + 10;
if(s[i] >= 'A' && s[i] <= 'F') c = s[i] - 'A' + 10;
address *= 16;
address += c;
}
}
if(!readFile(&myFile, fileName)) {
printf("Error (B-1): Open file \"%s\", aborting.\n", fileName);
return -1;
}
if(!crunch(&myFile, &myBBFile, address, isExecutable, isRelocated)) {
freeFile(&myFile);
return -1;
}
if(!writeFile(&myBBFile, myFile.name)) {
printf("Error (B-2): Write file \"%s\", aborting.\n", myBBFile.name);
}
printf("B2: \"%s\" -> \"%s\"\n", myFile.name, myBBFile.name);
freeFile(&myFile);
freeFile(&myBBFile);
return 0;
}

19
loader/tools/b2/bb.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef _bb_h_
#define _bb_h_
#ifndef NULL
#define NULL ((void*)0)
#endif
#ifndef byte
typedef unsigned char byte;
#endif
#ifndef uint
typedef unsigned int uint;
#endif
typedef enum { false = 0, true = 1 } bool;
#define memSize 65536
#endif // _bb_h_

747
loader/tools/b2/cruncher.c Normal file
View file

@ -0,0 +1,747 @@
#include "cruncher.h"
#include <stdio.h>
#include <stdlib.h>
#define log(format, ...)
//#define log(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
#define NUM_BITS_SHORT_0 3
#define NUM_BITS_SHORT_1 6
#define NUM_BITS_SHORT_2 8
#define NUM_BITS_SHORT_3 10
#define NUM_BITS_LONG_0 4
#define NUM_BITS_LONG_1 7
#define NUM_BITS_LONG_2 10
#define NUM_BITS_LONG_3 13
#define LEN_SHORT_0 (1 << NUM_BITS_SHORT_0)
#define LEN_SHORT_1 (1 << NUM_BITS_SHORT_1)
#define LEN_SHORT_2 (1 << NUM_BITS_SHORT_2)
#define LEN_SHORT_3 (1 << NUM_BITS_SHORT_3)
#define LEN_LONG_0 (1 << NUM_BITS_LONG_0)
#define LEN_LONG_1 (1 << NUM_BITS_LONG_1)
#define LEN_LONG_2 (1 << NUM_BITS_LONG_2)
#define LEN_LONG_3 (1 << NUM_BITS_LONG_3)
#define COND_SHORT_0(o) ((o) >= 0 && (o) < LEN_SHORT_0)
#define COND_SHORT_1(o) ((o) >= LEN_SHORT_0 && (o) < LEN_SHORT_1)
#define COND_SHORT_2(o) ((o) >= LEN_SHORT_1 && (o) < LEN_SHORT_2)
#define COND_SHORT_3(o) ((o) >= LEN_SHORT_2 && (o) < LEN_SHORT_3)
#define COND_LONG_0(o) ((o) >= 0 && (o) < LEN_LONG_0)
#define COND_LONG_1(o) ((o) >= LEN_LONG_0 && (o) < LEN_LONG_1)
#define COND_LONG_2(o) ((o) >= LEN_LONG_1 && (o) < LEN_LONG_2)
#define COND_LONG_3(o) ((o) >= LEN_LONG_2 && (o) < LEN_LONG_3)
#define MAX_OFFSET LEN_LONG_3
#define MAX_OFFSET_SHORT LEN_SHORT_3
#define DECRUNCHER_LENGTH 0xd5
byte decrCode[DECRUNCHER_LENGTH] = {
0x0b, 0x08, 0x00, 0x00, 0x9e, 0x32, 0x30, 0x36, 0x31, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x34, 0x85,
0x01, 0xa2, 0xb7, 0xbd, 0x1e, 0x08, 0x95, 0x0f, 0xca, 0xd0, 0xf8, 0x4c, 0x10, 0x00, 0xbd, 0xd6,
0x07, 0x9d, 0x00, 0xff, 0xe8, 0xd0, 0xf7, 0xc6, 0x12, 0xc6, 0x15, 0xa5, 0x12, 0xc9, 0x07, 0xb0,
0xed, 0x20, 0xa0, 0x00, 0xb0, 0x17, 0x20, 0x8e, 0x00, 0x85, 0x36, 0xa0, 0x00, 0x20, 0xad, 0x00,
0x91, 0x77, 0xc8, 0xc0, 0x00, 0xd0, 0xf6, 0x20, 0x83, 0x00, 0xc8, 0xf0, 0xe4, 0x20, 0x8e, 0x00,
0xaa, 0xe8, 0xf0, 0x71, 0x86, 0x7b, 0xa9, 0x00, 0xe0, 0x03, 0x2a, 0x20, 0x9b, 0x00, 0x20, 0x9b,
0x00, 0xaa, 0xb5, 0xbf, 0xf0, 0x07, 0x20, 0x9b, 0x00, 0xb0, 0xfb, 0x30, 0x07, 0x49, 0xff, 0xa8,
0x20, 0xad, 0x00, 0xae, 0xa0, 0xff, 0x65, 0x77, 0x85, 0x74, 0x98, 0x65, 0x78, 0x85, 0x75, 0xa0,
0x00, 0xb9, 0xad, 0xde, 0x99, 0x00, 0x00, 0xc8, 0xc0, 0x00, 0xd0, 0xf5, 0x20, 0x83, 0x00, 0xd0,
0xa0, 0x18, 0x98, 0x65, 0x77, 0x85, 0x77, 0x90, 0x02, 0xe6, 0x78, 0x60, 0xa9, 0x01, 0x20, 0xa0,
0x00, 0x90, 0x05, 0x20, 0x9b, 0x00, 0x10, 0xf6, 0x60, 0x20, 0xa0, 0x00, 0x2a, 0x60, 0x06, 0xbe,
0xd0, 0x08, 0x48, 0x20, 0xad, 0x00, 0x2a, 0x85, 0xbe, 0x68, 0x60, 0xad, 0xed, 0xfe, 0xe6, 0xae,
0xd0, 0x02, 0xe6, 0xaf, 0x60, 0xa9, 0x37, 0x85, 0x01, 0x4c, 0x00, 0x00, 0x80, 0xdf, 0xfb, 0x00,
0x80, 0xef, 0xfd, 0x80, 0xf0
};
byte *ibuf;
byte *obuf;
uint ibufSize;
int get; //points to ibuf[]
uint put; //points to obuf[]
typedef struct {
uint cost;
uint next;
uint litLen;
uint offset;
} node;
typedef struct {
byte value;
byte valueAfter;
uint length;
} RLEInfo;
node *context;
uint *link;
RLEInfo *rleInfo;
uint first[65536];
uint last[65536];
byte curByte;
byte curCnt;
uint curIndex;
void wBit(uint bit) {
if(curCnt == 0) {
obuf[curIndex] = curByte;
curIndex = put;
curCnt = 8;
curByte = 0;
put++;
}
curByte <<= 1;
curByte |= (bit & 1);
curCnt--;
}
void wFlush() {
while(curCnt != 0) {
curByte <<= 1;
curCnt--;
}
obuf[curIndex] = curByte;
}
void wByte(uint b) {
obuf[put] = b;
put++;
}
void wBytes(uint get, uint len) {
uint i;
for(i = 0; i < len; i++) {
wByte(ibuf[get]);
get++;
}
}
void wLength(uint len) {
// if(len == 0) return; // Should never happen
byte bit = 0x80;
while((len & bit) == 0) {
bit >>= 1;
}
while(bit > 1) {
wBit(1);
bit >>= 1;
wBit(((len & bit) == 0) ? 0 : 1);
}
if(len < 0x80) {
wBit(0);
}
}
void wOffset(uint offset, uint len) {
uint i = 0;
uint n = 0;
uint b;
if(len == 1) {
if(COND_SHORT_0(offset)) {
i = 0;
n = NUM_BITS_SHORT_0;
}
if(COND_SHORT_1(offset)) {
i = 1;
n = NUM_BITS_SHORT_1;
}
if(COND_SHORT_2(offset)) {
i = 2;
n = NUM_BITS_SHORT_2;
}
if(COND_SHORT_3(offset)) {
i = 3;
n = NUM_BITS_SHORT_3;
}
} else {
if(COND_LONG_0(offset)) {
i = 0;
n = NUM_BITS_LONG_0;
}
if(COND_LONG_1(offset)) {
i = 1;
n = NUM_BITS_LONG_1;
}
if(COND_LONG_2(offset)) {
i = 2;
n = NUM_BITS_LONG_2;
}
if(COND_LONG_3(offset)) {
i = 3;
n = NUM_BITS_LONG_3;
}
}
// First write number of bits
wBit(((i & 2) == 0) ? 0 : 1);
wBit(((i & 1) == 0) ? 0 : 1);
if(n >= 8) { // Offset is 2 bytes
// Then write the bits less than 8
b = 1 << n;
while(b > 0x100) {
b >>= 1;
wBit(((b & offset) == 0) ? 0 : 1);
};
// Finally write a whole byte, if necessary
wByte((offset & 255) ^ 255); // Inverted(!)
offset >>= 8;
} else { // Offset is 1 byte
// Then write the bits less than 8
b = 1 << n;
while(b > 1) {
b >>= 1;
wBit(((b & offset) == 0) ? 1 : 0); // Inverted(!)
};
}
}
/*
* Cost functions
*/
uint costOfLength(uint len) {
if(len == 1) return 1;
if(len >= 2 && len <= 3) return 3;
if(len >= 4 && len <= 7) return 5;
if(len >= 8 && len <= 15) return 7;
if(len >= 16 && len <= 31) return 9;
if(len >= 32 && len <= 63) return 11;
if(len >= 64 && len <= 127) return 13;
if(len >= 128 && len <= 255) return 14;
printf("costOfLength got wrong value: %i\n", len);
return 10000;
}
uint costOfOffset(uint offset, uint len) {
if(len == 1) {
if(COND_SHORT_0(offset)) return NUM_BITS_SHORT_0;
if(COND_SHORT_1(offset)) return NUM_BITS_SHORT_1;
if(COND_SHORT_2(offset)) return NUM_BITS_SHORT_2;
if(COND_SHORT_3(offset)) return NUM_BITS_SHORT_3;
} else {
if(COND_LONG_0(offset)) return NUM_BITS_LONG_0;
if(COND_LONG_1(offset)) return NUM_BITS_LONG_1;
if(COND_LONG_2(offset)) return NUM_BITS_LONG_2;
if(COND_LONG_3(offset)) return NUM_BITS_LONG_3;
}
printf("costOfOffset got wrong offset: %i\n", offset);
return 10000;
}
uint calculateCostOfMatch(uint len, uint offset) {
uint cost = 1; // Copy-bit
cost += costOfLength(len - 1);
cost += 2; // NumOffsetBits
cost += costOfOffset(offset - 1, len - 1);
return cost;
}
uint calculateCostOfLiteral(uint oldCost, uint litLen) {
uint newCost = oldCost + 8;
// FIXME, what if litLen > 255?
//
// FIXME, cost model for literals does not work.
// Quick wins on short matches are prioritized before
// a longer literal run, which in the end results in a
// worse result.
// Most obvious on files hard to crunch.
switch(litLen) {
case 1:
case 128:
newCost++;
break;
case 2:
case 4:
case 8:
case 16:
case 32:
case 64:
newCost += 2;
break;
default:
break;
}
return newCost;
}
void setupHelpStructures() {
uint i;
// Setup RLE-info
get = ibufSize - 1;
while (get > 0) {
byte cur = ibuf[get];
if (cur == ibuf[get-1]) {
uint len = 2;
while ((get >= len) &&
(cur == ibuf[get-len])) {
len++;
}
rleInfo[get].length = len;
if (get >= len) {
rleInfo[get].valueAfter = ibuf[get-len];
} else {
rleInfo[get].valueAfter = cur; // Avoid accessing ibuf[-1]
}
get -= len;
} else {
get--;
}
}
// Setup Linked list
for (i = 0; i < 65536; i++) {
first[i] = 0;
last[i] = 0;
}
get = ibufSize - 1;
uint cur = ibuf[get];
while (get > 0) {
cur = ((cur << 8) | ibuf[get-1]) & 65535;
if (first[cur] == 0) {
first[cur] = last[cur] = get;
} else {
link[last[cur]] = get;
last[cur] = get;
}
if (rleInfo[get].length == 0) { // No RLE-match here..
get--;
} else { // if RLE-match..
get -= (rleInfo[get].length - 1);
}
}
}
void findMatches() {
typedef struct match {
uint length;
uint offset;
} match;
match matches[256];
node lastNode;
uint i;
get = ibufSize - 1;
uint cur = ibuf[get];
lastNode.cost = 0;
lastNode.next = 0;
lastNode.litLen = 0;
while (get >= 0) {
// Clear matches for current position
for (i = 0; i < 256; i++) {
matches[i].length = 0;
matches[i].offset = 0;
}
cur = (cur << 8) & 65535; // Table65536 lookup
if (get > 0) cur |= ibuf[get-1];
int scn = first[cur];
scn = link[scn];
uint longestMatch = 0;
if (rleInfo[get].length == 0) { // No RLE-match here..
// Scan until start of file, or max offset
while (((get - scn) <= MAX_OFFSET) &&
(scn > 0) &&
(longestMatch < 255)) {
// Ok, we have a match of length 2
// ..or longer, but max 255 or file start
uint len = 2;
while ((len < 255) &&
(scn >= len) &&
(ibuf[scn - len] == ibuf[get - len])) {
++len;
}
// Calc offset
uint offset = get - scn;
// Store match only if it's the longest so far
if(len > longestMatch) {
longestMatch = len;
// Store the match only if first (= best) of this length
while(len >= 2 && matches[len].length == 0) {
// If len == 2, check against short offset!!
if ((len > 2) ||
((len == 2) && (offset <= MAX_OFFSET_SHORT))) {
matches[len].length = len;
matches[len].offset = get - scn;
}
len--;
};
}
scn = link[scn]; // Table65535 lookup
};
first[cur] = link[first[cur]]; // Waste first entry
} else { // if RLE-match..
uint rleLen = rleInfo[get].length;
byte rleValAfter = rleInfo[get].valueAfter;
// First match with self-RLE, which is always
// one byte shorter than the RLE itself.
uint len = rleLen - 1;
if (len > 1) {
if (len > 255) len = 255;
longestMatch = len;
// Store the match
while(len >= 2) {
matches[len].length = len;
matches[len].offset = 1;
len--;
};
}
// Search for more RLE-matches..
// Scan until start of file, or max offset
while (((get - scn) <= MAX_OFFSET) &&
(scn > 0) &&
(longestMatch < 255)) {
// Check for longer matches with same value and after..
// FIXME, that is not what it does, is it?!
if ((rleInfo[scn].length > longestMatch) &&
(rleLen > longestMatch)) {
uint offset = get - scn;
len = rleInfo[scn].length;
if (len > rleLen)
len = rleLen;
if ((len > 2) ||
((len == 2) && (offset <= MAX_OFFSET_SHORT))) {
matches[len].length = len;
matches[len].offset = offset;
longestMatch = len;
}
}
// Check for matches beyond the RLE..
if ((rleInfo[scn].length >= rleLen) &&
(rleInfo[scn].valueAfter == rleValAfter)) {
// Here is a match that goes beyond the RLE..
// Find out correct offset to use valueAfter..
// Then search further to see if more bytes equal.
len = rleLen;
uint offset = get - scn + (rleInfo[scn].length - rleLen);
if (offset <= MAX_OFFSET) {
while ((len < 255) &&
(get >= (offset + len)) &&
(ibuf[get - (offset + len)] == ibuf[get - len])) {
++len;
}
if (len > longestMatch){
longestMatch = len;
// Store the match only if first (= best) of this length
while(len >= 2 && matches[len].length == 0) {
// If len == 2, check against short offset!!
if ((len > 2) ||
((len == 2) && (offset <= MAX_OFFSET_SHORT))) {
matches[len].length = len;
matches[len].offset = offset;
}
len--;
}; //while
}
}
}
scn = link[scn]; // Table65535 lookup
}
if (rleInfo[get].length > 2) {
// Expand RLE to next position
rleInfo[get-1].length = rleInfo[get].length - 1;
rleInfo[get-1].value = rleInfo[get].value;
rleInfo[get-1].valueAfter = rleInfo[get].valueAfter;
} else {
// End of RLE, advance link.
first[cur] = link[first[cur]]; // Waste first entry
}
}
// Now we have all matches from this position..
// ..visit all nodes reached by the matches.
for (i = 255; i > 0; i--) {
// Find all matches we stored
uint len = matches[i].length;
uint offset = matches[i].offset;
if (len != 0) {
uint targetI = get - len + 1;
node* target = &context[targetI];
// Calculate cost for this jump
uint currentCost = lastNode.cost;
currentCost += calculateCostOfMatch(len, offset);
// If this match is first or cheapest way to get here
// then update node
if (target->cost == 0 ||
target->cost > currentCost) {
target->cost = currentCost;
target->next = get + 1;
target->litLen = 0;
target->offset = offset;
}
}
}
// Calc the cost for this node if using one more literal
uint litLen = lastNode.litLen + 1;
uint litCost = calculateCostOfLiteral(lastNode.cost, litLen);
// If literal run is first or cheapest way to get here
// then update node
node* this = &context[get];
if (this->cost == 0 ||
this->cost >= litCost) {
this->cost = litCost;
this->next = get + 1;
this->litLen = litLen;
}
lastNode.cost = this->cost;
lastNode.next = this->next;
lastNode.litLen = this->litLen;
// Loop to the next position
get--;
};
}
// Returns margin
int writeOutput() {
uint i;
put = 0;
curByte = 0;
curCnt = 8;
curIndex = put;
put++;
int maxDiff = 0;
bool needCopyBit = true;
for (i = 0; i < ibufSize;) {
uint link = context[i].next;
uint cost = context[i].cost;
uint litLen = context[i].litLen;
uint offset = context[i].offset;
if (litLen == 0) {
// Put Match
uint len = link - i;
log("$%04x: Mat(%i, %i)\n", i, len, offset);
if(needCopyBit) {
wBit(1);
}
wLength(len - 1);
wOffset(offset - 1, len - 1);
i = link;
needCopyBit = true;
} else {
// Put LiteralRun
needCopyBit = false;
while(litLen > 0) {
uint len = litLen < 255 ? litLen : 255;
log("$%04x: Lit(%i)\n", i, len);
wBit(0);
wLength(len);
wBytes(i, len);
if (litLen == 255) {
needCopyBit = true;
}
litLen -= len;
i += len;
};
}
if ((int)(i - put) > maxDiff) {
maxDiff = i - put;
}
}
wBit(1);
wLength(0xff);
wFlush();
int margin = (maxDiff - (i - put));
return margin;
}
bool crunch(File *aSource,
File *aTarget,
uint address,
bool isExecutable,
bool isRelocated)
{
uint i;
byte *target;
ibufSize = aSource->size - 2;
ibuf = (byte*)malloc(ibufSize);
context = (node*)malloc(sizeof(node) * ibufSize);
link = (uint*)malloc(sizeof(uint) * ibufSize);
rleInfo = (RLEInfo*)malloc(sizeof(RLEInfo) * ibufSize);
// Load ibuf and clear context
for(i = 0; i < ibufSize; ++i) {
ibuf[i] = aSource->data[i + 2];
context[i].cost = 0;
link[i] = 0;
rleInfo[i].length = 0;
}
setupHelpStructures();
findMatches();
obuf = (byte*)malloc(memSize);
int margin = writeOutput();
uint packLen = put;
uint fileLen = put;
uint decrLen = 0;
if(isExecutable) {
decrLen = DECRUNCHER_LENGTH;
fileLen += decrLen + 2;
} else {
fileLen += 4;
}
aTarget->size = fileLen;
aTarget->data = (byte*)malloc(aTarget->size);
target = aTarget->data;
if(isExecutable) {
uint startAddress = 0x10000 - packLen;
uint transfAddress = fileLen + 0x6ff;
decrCode[0x1f] = transfAddress & 0xff; // Transfer from..
decrCode[0x20] = transfAddress >> 8; //
decrCode[0xbc] = startAddress & 0xff; // Depack from..
decrCode[0xbd] = startAddress >> 8; //
decrCode[0x85] = aSource->data[0]; // Depack to..
decrCode[0x86] = aSource->data[1]; //
decrCode[0xca] = address & 0xff; // Jump to..
decrCode[0xcb] = address >> 8; //
target[0] = 0x01;
target[1] = 0x08;
for(i = 0; i < decrLen; ++i) {
target[i + 2] = decrCode[i];
}
for(i = 0; i < put; ++i) {
target[i + 2 + decrLen] = obuf[i];
}
} else { // Not executable..
// Experimantal decision of start address
// uint startAddress = 0xfffa - packLen - 2;
uint startAddress = (aSource->data[1] << 8) | aSource->data[0];
startAddress += (ibufSize - packLen - 2 + margin);
if (isRelocated) {
startAddress = address - packLen - 2;
}
target[0] = startAddress & 0xff; // Load address
target[1] = startAddress >> 8;
target[2] = aSource->data[0]; // Depack to address
target[3] = aSource->data[1];
for(i = 0; i < put; ++i) {
target[i + 4] = obuf[i];
}
}
free(ibuf);
free(context);
free(link);
free(rleInfo);
return true;
}

View file

@ -0,0 +1,9 @@
#ifndef _cruncher_h_
#define _cruncher_h_
#include "bb.h"
#include "file.h"
bool crunch(File *aSource, File *aTarget, uint startAdress, uint decrFlag, bool isRelocated);
#endif // _cruncher_h_

72
loader/tools/b2/file.c Normal file
View file

@ -0,0 +1,72 @@
#include "file.h"
#include <stdlib.h>
#include <string.h>
void freeFile(File *aFile)
{
free(aFile->name);
free(aFile->data);
}
bool readFile(File *aFile, const char *fileName)
{
FILE *fp = NULL;
struct stat fileStatus;
aFile->name = (char *)strdup(fileName);
if(stat(aFile->name, &fileStatus) == -1) {
return false;
}
aFile->size = fileStatus.st_size;
fp = fopen(aFile->name, "rb");
if(fp == NULL) {
return false;
}
aFile->data = (byte *)malloc(aFile->size);
if(aFile->data == NULL) {
fclose(fp);
return false;
}
if(fread(aFile->data, 1, aFile->size, fp) != aFile->size) {
fclose(fp);
free(aFile->data);
return false;
}
fclose(fp);
return true;
}
bool writeFile(File *aFile, const char *fileName)
{
FILE *fp = NULL;
size_t length;
char *ext;
length = strlen(fileName);
aFile->name = (char *)malloc(length + 4);
if(aFile->name == NULL){
return false;
}
strncpy(aFile->name, fileName, length);
strncpy(aFile->name + length, ".b2\0", 4);
fp = fopen(aFile->name, "wb");
if(fp == NULL) {
return false;
}
if(fwrite(aFile->data, 1, aFile->size, fp) != aFile->size) {
fclose(fp);
return false;
}
fclose(fp);
return true;
}

19
loader/tools/b2/file.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef _file_h_
#define _file_h_
#include "bb.h"
#include <stdio.h>
#include <sys/stat.h>
typedef struct {
char *name;
size_t size;
byte *data;
} File;
void freeFile(File *aFile);
bool readFile(File *aFile, const char *fileName);
bool writeFile(File *aFile, const char *fileName);
#endif // _file_h_