1
0
mirror of synced 2026-01-21 18:15:37 +00:00
2010-04-02 12:41:21 +00:00

396 lines
6.7 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* tss/8 rf08 disk maker
* brad@heeltoe.com 3/2010
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
typedef unsigned short u12;
unsigned char binfile[16*1024];
u12 fields[7][4096];
char filled[7][4096];
#define RFSIZE (1024*1024)
u12 rf[RFSIZE];
int rf_size;
int rf_fd;
#define MEMSIZE (32*1024)
int disk_load(char *filename)
{
int fd, ret;
rf_fd = open(filename, O_RDWR);
if (rf_fd < 0) {
perror(filename);
return -1;
}
ret = read(rf_fd, rf, sizeof(rf));
if (ret < 0) {
perror(filename);
} else {
rf_size = ret / 2;
printf("loaded rf disk, word size %d\n", rf_size);
ret = 0;
}
printf("rf_fd %d\n", rf_fd);
return ret;
}
int disk_save(void)
{
int ret;
printf("saving rf disk, word size %d\n", rf_size);
ret = (int)lseek(rf_fd, (off_t)0, SEEK_SET);
if (ret != 0) {
perror("seek");
return -1;
}
ret = write(rf_fd, rf, rf_size*2);
if (ret != rf_size*2) {
printf("write failed; wrote %d, ret %d\n", rf_size*2, ret);
perror("write");
return -1;
}
return 0;
}
int field_patch(int field)
{
switch (field) {
case 0:
fields[0][07600] = 0323; /* login message */
fields[0][07601] = 0331;
fields[0][07602] = 0323;
fields[0][07603] = 0324;
fields[0][07604] = 0305;
fields[0][07605] = 0315;
fields[0][07606] = 0240;
fields[0][07607] = 0311;
fields[0][07610] = 0323;
fields[0][07611] = 0240;
fields[0][07612] = 0304;
fields[0][07613] = 0317;
fields[0][07614] = 0327;
fields[0][07615] = 0316;
fields[0][07616] = 0254;
fields[0][07617] = 0240;
fields[0][07620] = 0311;
fields[0][07621] = 0316;
fields[0][07622] = 0303;
fields[0][07623] = 0256;
fields[0][07624] = 0215;
fields[0][07625] = 0212;
fields[0][07626] = 0215;
fields[0][07627] = 0212;
fields[0][07630] = 0000;
fields[0][07631] = 0323;
fields[0][07632] = 0310;
fields[0][07633] = 0301;
fields[0][07634] = 0322;
fields[0][07635] = 0311;
fields[0][07636] = 0316;
fields[0][07637] = 0307;
fields[0][07640] = 0000;
break;
case 2:
fields[2][01403] = 6; /* CORFLD */
break;
}
return 0;
}
int field_save(int field)
{
int i, offset;
printf("saving field %d\n", field);
offset = field * 4096;
for (i = 0; i < 4096; i++) {
if (filled[field][i]) {
rf[offset+i] = fields[field][i];
}
}
}
int field_unsave(int field)
{
int i, offset;
printf("extracting field %d\n", field);
offset = field * 4096;
for (i = 0; i < 4096; i++) {
fields[field][i] = rf[offset+i];
}
}
int field_load(int dstfield, char *filename)
{
int f, ch, o, binfile_size;
int rubout, newfield, state, high, low, done;
int word, csum, bad;
u12 origin, field;
f = open(filename, O_RDONLY);
if (f < 0) {
perror(filename);
return -1;
}
binfile_size = read(f, binfile, sizeof(binfile));
close(f);
if (binfile_size < 0) {
perror(filename);
return -1;
}
printf("%s: field %d, %d bytes\n", filename, dstfield, binfile_size);
done = 0;
rubout = 0;
state = 0;
csum = 0;
bad = 0;
for (o = 0; o < binfile_size && !done; o++) {
ch = binfile[o];
if (rubout) {
rubout = 0;
continue;
}
if (ch == 0377) {
rubout = 1;
continue;
}
if (ch > 0200) {
newfield = (ch & 070) >> 3;
continue;
}
switch (state) {
case 0:
/* leader */
if ((ch != 0) && (ch != 0200)) state = 1;
high = ch;
break;
case 1:
/* low byte */
low = ch;
state = 2;
break;
case 2:
/* high with test */
word = (high << 6) | low;
if (ch == 0200) {
if ((csum - word) & 07777) {
printf("%s: checksum error\n", filename);
bad++;
}
done = 1;
continue;
}
csum = csum + low + high;
if (word >= 010000) {
origin = word & 07777;
} else {
int ignore, allow;
if (field > 7 || origin >= MEMSIZE) {
printf("%s: too big\n", filename);
bad++;
}
if (0) printf("mem[%o] = %o\n", field|origin, word&07777);
ignore = 0;
allow = 1;
/* ignore RIM loader at start of init.pal */
if (dstfield == 2 && field == 0) {
ignore = 1;
allow = 0;
}
/* allow ts8 to load fields 3 & 4 */
if (dstfield == 3 && field == 4) {
ignore = 1;
allow = 1;
}
if (field != dstfield) {
if (!ignore) {
printf("%s: field %d, addr %o; not in dest field %d\n",
filename, field, origin, dstfield);
bad++;
}
}
if (allow) {
if (filled[field][origin]) {
printf("%s: field %d, addr %o; duplicate (old %04x new %04o)\n",
filename, field, origin,
fields[field][origin], word & 07777);
}
fields[field][origin] = word & 07777;
filled[field][origin]++;
}
origin = (origin + 1) & 07777;
}
field = newfield;
high = ch;
state = 1;
break;
}
}
return bad ? -1 : 0;
}
int field_dump(int srcfield, char *filename)
{
FILE *f;
int i;
f = fopen(filename, "w");
if (f == NULL) {
perror(filename);
return -1;
}
for (i = 0; i < 4096; i++) {
fprintf(f, "%d%04o %04o\n", srcfield, i, fields[srcfield][i]);
}
fclose(f);
}
int eval_scriptline(char *line)
{
char word1[256], word2[256], word3[256];
int count, fld;
count = sscanf(line, "%s %s %s", word1, word2, word3);
if (strcmp(word1, "disk") == 0) {
if (count < 2) {
fprintf(stderr, "missing disk arg\n");
return -1;
}
return disk_load(word2);
}
if (strcmp(word1, "field") == 0) {
if (count < 3) {
fprintf(stderr, "missing field arg\n");
return -1;
}
fld = atoi(word2);
if (fld < 0 || fld > 4) {
fprintf(stderr, "bad field number\n");
return -1;
}
field_load(fld, word3);
field_patch(fld);
field_save(fld);
if (fld == 3)
field_save(4);
return 0;
}
if (strcmp(word1, "dump") == 0) {
if (count < 2) {
fprintf(stderr, "missing field arg\n");
return -1;
}
fld = atoi(word2);
if (fld < 0 || fld > 4) {
fprintf(stderr, "bad field number\n");
return -1;
}
field_unsave(fld);
field_dump(fld, word3);
return 0;
}
if (strcmp(word1, "save") == 0) {
if (disk_save())
return -1;
return 0;
}
return -1;
}
int eval_scriptfile(char *filename)
{
FILE *f;
char line[1024];
f = fopen(filename, "r");
if (f == NULL) {
perror(filename);
return -1;
}
while (fgets(line, sizeof(line), f)) {
eval_scriptline(line);
}
fclose(f);
return 0;
}
main(int argc, char **argv)
{
char *scriptfile;
scriptfile = "script";
if (argc > 1)
scriptfile = argv[1];
if (eval_scriptfile(scriptfile))
exit(1);
exit(0);
}
/*
* Local Variables:
* indent-tabs-mode:nil
* c-basic-offset:4
* End:
*/