mirror of
https://github.com/DoctorWkt/unix-jun72.git
synced 2026-02-21 14:58:44 +00:00
added a.out conversion program
This commit is contained in:
224
tools/ml.c
Normal file
224
tools/ml.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Quick hack to read old unix a.out files and make
|
||||
* a simh "load file".
|
||||
*
|
||||
* Brad Parker <brad@heeltoe.com> 5/2008
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Binary loader.
|
||||
|
||||
Loader format consists of blocks, optionally preceded, separated, and
|
||||
followed by zeroes. Each block consists of:
|
||||
|
||||
001 ---
|
||||
xxx |
|
||||
lo_count |
|
||||
hi_count |
|
||||
lo_origin > count bytes
|
||||
hi_origin |
|
||||
data byte |
|
||||
: |
|
||||
data byte ---
|
||||
checksum
|
||||
|
||||
If the byte count is exactly six, the block is the last on the tape, and
|
||||
there is no checksum. If the origin is not 000001, then the origin is
|
||||
the PC at which to start the program.
|
||||
*/
|
||||
|
||||
typedef unsigned short u16;
|
||||
|
||||
struct exec {
|
||||
u16 a_magic;
|
||||
u16 a_text;
|
||||
u16 a_data;
|
||||
u16 a_bss;
|
||||
u16 a_syms;
|
||||
u16 a_entry;
|
||||
u16 a_unused;
|
||||
u16 a_flag;
|
||||
};
|
||||
|
||||
unsigned char buffer[1024];
|
||||
int checksum;
|
||||
|
||||
int verbose;
|
||||
|
||||
int
|
||||
mk_hdr(int fd, int count, int origin)
|
||||
{
|
||||
int i, ret, hc;
|
||||
|
||||
checksum = 0;
|
||||
hc = count + 6;
|
||||
|
||||
buffer[0] = 0x01;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = hc & 0xff;
|
||||
buffer[3] = hc >> 8;
|
||||
buffer[4] = origin & 0xff;
|
||||
buffer[5] = origin >> 8;
|
||||
|
||||
ret = write(fd, buffer, 6);
|
||||
if (ret != 6)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
checksum += buffer[i] & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mk_post_data(int fd)
|
||||
{
|
||||
int ret, final_checksum;
|
||||
|
||||
/* final checksum must be zero */
|
||||
final_checksum = 256 - (checksum & 0xff);
|
||||
|
||||
buffer[0] = final_checksum;
|
||||
if (verbose)
|
||||
printf("checksum %08x, final %02x\n", checksum, final_checksum);
|
||||
|
||||
ret = write(fd, buffer, 1);
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
load(int fd, char *buf, int bufsize)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
printf("load: %d bytes\n", bufsize);
|
||||
|
||||
if (bufsize < 65536) {
|
||||
mk_hdr(fd, bufsize, 0);
|
||||
|
||||
ret = write(fd, buf, bufsize);
|
||||
if (ret != bufsize)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < bufsize; i++)
|
||||
checksum += buf[i] & 0xff;
|
||||
|
||||
mk_post_data(fd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
finish(int fd, int origin)
|
||||
{
|
||||
mk_hdr(fd, 0, origin);
|
||||
}
|
||||
|
||||
int
|
||||
process_aout(int ifd, int ofd, int origin)
|
||||
{
|
||||
int ret, hdr_size;
|
||||
struct exec hdr;
|
||||
char *textblob, *datablob;
|
||||
|
||||
ret = read(ifd, (char *)&hdr, sizeof(hdr));
|
||||
if (ret != sizeof(hdr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (1) {
|
||||
printf("magic 0%o\ntext %d, data %d, bss %d, syms %d\n",
|
||||
hdr.a_magic & 0xffff,
|
||||
hdr.a_text, hdr.a_data, hdr.a_bss, hdr.a_syms);
|
||||
printf("entry %o, flag %o\n",
|
||||
hdr.a_entry,
|
||||
hdr.a_flag);
|
||||
}
|
||||
|
||||
textblob = malloc(hdr.a_text);
|
||||
datablob = malloc(hdr.a_data);
|
||||
|
||||
hdr_size = 0;
|
||||
|
||||
/* v7 header? if so, 0 is after header */
|
||||
switch (hdr.a_magic) {
|
||||
case 0407: hdr_size = 0; break;
|
||||
case 0405: hdr_size = 12; break;
|
||||
}
|
||||
|
||||
if (hdr_size) {
|
||||
/* back up */
|
||||
lseek(ifd, (off_t)-hdr_size, SEEK_CUR);
|
||||
hdr.a_text += hdr_size;
|
||||
}
|
||||
|
||||
ret = read(ifd, textblob, hdr.a_text);
|
||||
if (ret != hdr.a_text)
|
||||
return -1;
|
||||
|
||||
ret = read(ifd, datablob, hdr.a_data);
|
||||
if (ret != hdr.a_data)
|
||||
return -1;
|
||||
|
||||
load(ofd, textblob, hdr.a_text);
|
||||
load(ofd, datablob, hdr.a_data);
|
||||
|
||||
finish(ofd, origin);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
process(char *inf, char *outf)
|
||||
{
|
||||
int ifd, ofd, ret;
|
||||
int origin;
|
||||
|
||||
ofd = open(outf, O_WRONLY | O_CREAT, 0666);
|
||||
if (ofd < 0) {
|
||||
perror(outf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifd = open(inf, O_RDONLY);
|
||||
if (ifd < 0) {
|
||||
perror(inf);
|
||||
close(ofd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
origin = 0;
|
||||
|
||||
if (process_aout(ifd, ofd, origin)) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
close(ifd);
|
||||
close(ofd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *filename = "a.out";
|
||||
char *output_filename = "loadfile";
|
||||
int fd;
|
||||
|
||||
verbose = 0;
|
||||
|
||||
if (process(filename, output_filename)) {
|
||||
fprintf(stderr, "%s: failed?\n", filename);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user