196 lines
3.6 KiB
C
196 lines
3.6 KiB
C
#include "dofile.h"
|
|
#include <stdio.h>
|
|
#include "../fileio/machdr.h"
|
|
#include "../fileio/rdfile.h"
|
|
#include "../crc/crc.h"
|
|
|
|
extern int dorep;
|
|
|
|
#define RUNCHAR 0x90
|
|
|
|
static int pos_ptr;
|
|
static char codes[] =
|
|
"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
|
|
static int state;
|
|
static int savebits;
|
|
static int rep_char;
|
|
static int rep_count;
|
|
|
|
static void doheader();
|
|
static void dofork(char *fork, int size);
|
|
static void outbyte(int b);
|
|
static void finish(void);
|
|
static void outbyte1(int b);
|
|
static void out6bit(int c);
|
|
static void outchar(int c);
|
|
|
|
void
|
|
dofile (void)
|
|
{
|
|
(void)printf("(This file must be converted; you knew that already.)\n");
|
|
(void)printf("\n");
|
|
pos_ptr = 1;
|
|
state = 0;
|
|
rep_char = -1;
|
|
rep_count = 0;
|
|
outchar(':');
|
|
doheader();
|
|
dofork(data_fork, data_size);
|
|
dofork(rsrc_fork, rsrc_size);
|
|
finish();
|
|
(void)putchar(':');
|
|
(void)putchar('\n');
|
|
}
|
|
|
|
static void
|
|
doheader (void)
|
|
{
|
|
uint32_t crc;
|
|
int i, n;
|
|
|
|
crc = binhex_crcinit;
|
|
n = file_info[I_NAMEOFF];
|
|
crc = binhex_updcrc(crc, (unsigned char*)(file_info + I_NAMEOFF), n + 1);
|
|
for(i = 0; i <= n; i++) {
|
|
outbyte(file_info[I_NAMEOFF + i]);
|
|
}
|
|
n = 0;
|
|
crc = binhex_updcrc(crc, (unsigned char *)&n, 1);
|
|
outbyte(0);
|
|
crc = binhex_updcrc(crc, (unsigned char*)(file_info + I_TYPEOFF), 4);
|
|
for(i = 0; i < 4; i++) {
|
|
outbyte(file_info[I_TYPEOFF + i]);
|
|
}
|
|
crc = binhex_updcrc(crc, (unsigned char*)(file_info + I_AUTHOFF), 4);
|
|
for(i = 0; i < 4; i++) {
|
|
outbyte(file_info[I_AUTHOFF + i]);
|
|
}
|
|
crc = binhex_updcrc(crc, (unsigned char*)(file_info + I_FLAGOFF), 2);
|
|
for(i = 0; i < 2; i++) {
|
|
outbyte(file_info[I_FLAGOFF + i]);
|
|
}
|
|
crc = binhex_updcrc(crc, (unsigned char*)(file_info + I_DLENOFF), 4);
|
|
for(i = 0; i < 4; i++) {
|
|
outbyte(file_info[I_DLENOFF + i]);
|
|
}
|
|
crc = binhex_updcrc(crc, (unsigned char*)(file_info + I_RLENOFF), 4);
|
|
for(i = 0; i < 4; i++) {
|
|
outbyte(file_info[I_RLENOFF + i]);
|
|
}
|
|
outbyte((int)(crc >> 8));
|
|
outbyte((int)(crc & 0xff));
|
|
}
|
|
|
|
void
|
|
dofork (char *fork, int size)
|
|
{
|
|
uint32_t crc;
|
|
int i;
|
|
|
|
crc = binhex_updcrc(binhex_crcinit, (unsigned char*)fork, size);
|
|
for(i = 0; i < size; i++) {
|
|
outbyte(fork[i]);
|
|
}
|
|
outbyte((int)(crc >> 8));
|
|
outbyte((int)(crc & 0xff));
|
|
}
|
|
|
|
static void
|
|
outbyte (int b)
|
|
{
|
|
b &= 0xff;
|
|
if(dorep && (b == rep_char)) {
|
|
if(++rep_count == 254) {
|
|
outbyte1(RUNCHAR);
|
|
outbyte1(255);
|
|
rep_char = -1;
|
|
rep_count = 0;
|
|
}
|
|
} else {
|
|
if(rep_count > 0) {
|
|
if(rep_count > 3) {
|
|
outbyte1(RUNCHAR);
|
|
outbyte1(rep_count + 1);
|
|
} else {
|
|
while(rep_count-- > 0) {
|
|
outbyte1(rep_char);
|
|
}
|
|
}
|
|
}
|
|
outbyte1(b);
|
|
if(b == RUNCHAR) {
|
|
outbyte1(0);
|
|
rep_char = -1;
|
|
} else {
|
|
rep_char = b;
|
|
}
|
|
rep_count = 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
finish (void)
|
|
{
|
|
if(rep_count > 0) {
|
|
if(rep_count > 3) {
|
|
outbyte1(RUNCHAR);
|
|
outbyte1(rep_count + 1);
|
|
} else {
|
|
while(rep_count-- > 0) {
|
|
outbyte1(rep_char);
|
|
}
|
|
}
|
|
}
|
|
switch(state) {
|
|
case 1:
|
|
out6bit(savebits << 4);
|
|
break;
|
|
case 2:
|
|
out6bit(savebits << 2);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
outbyte1 (int b)
|
|
{
|
|
switch(state) {
|
|
case 0:
|
|
out6bit(b >> 2);
|
|
savebits = b & 0x3;
|
|
state = 1;
|
|
break;
|
|
case 1:
|
|
b |= (savebits << 8);
|
|
out6bit(b >> 4);
|
|
savebits = b & 0xf;
|
|
state = 2;
|
|
break;
|
|
case 2:
|
|
b |= (savebits << 8);
|
|
out6bit(b >> 6);
|
|
out6bit(b & 0x3f);
|
|
state = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
out6bit (int c)
|
|
{
|
|
outchar(codes[c & 0x3f]);
|
|
}
|
|
|
|
static void
|
|
outchar (int c)
|
|
{
|
|
(void)putchar(c);
|
|
if(++pos_ptr > 64) {
|
|
(void)putchar('\n');
|
|
pos_ptr = 1;
|
|
}
|
|
}
|
|
|