rf08 disk maker
This commit is contained in:
7
utils/maker/Makefile
Normal file
7
utils/maker/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
maker: maker.c
|
||||
cc -o maker maker.c
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf maker
|
||||
7
utils/maker/dump.orig
Normal file
7
utils/maker/dump.orig
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
disk tss8_rf.dsk.orig
|
||||
dump 0 ../tss8.2/si.dump
|
||||
dump 1 ../tss8.2/fip.dump
|
||||
dump 2 ../tss8.2/init.dump
|
||||
dump 3 ../tss8.2/ts8.dump
|
||||
dump 4 ../tss8.2/ts8ii.dump
|
||||
7
utils/maker/dump.src
Normal file
7
utils/maker/dump.src
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
disk tss8_rf.dsk
|
||||
dump 0 ../tss8.2/si.src.dump
|
||||
dump 1 ../tss8.2/fip.src.dump
|
||||
dump 2 ../tss8.2/init.src.dump
|
||||
dump 3 ../tss8.2/ts8.src.dump
|
||||
dump 4 ../tss8.2/ts8ii.src.dump
|
||||
395
utils/maker/maker.c
Normal file
395
utils/maker/maker.c
Normal file
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* 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:
|
||||
*/
|
||||
8
utils/maker/script
Normal file
8
utils/maker/script
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
disk tss8_rf.dsk
|
||||
field 0 ../tss8.2/si.bin
|
||||
field 1 ../tss8.2/fip.bin
|
||||
field 2 ../tss8.2/init.bin
|
||||
field 3 ../tss8.2/ts8.bin
|
||||
#field 4 ../tss8.2/ts8ii.bin
|
||||
save
|
||||
5
utils/maker/tss8.cmd
Normal file
5
utils/maker/tss8.cmd
Normal file
@@ -0,0 +1,5 @@
|
||||
load ../tss8.2/init.bin
|
||||
set df disabled
|
||||
set rf enabled
|
||||
att rf tss8_rf.dsk
|
||||
run 24200
|
||||
Reference in New Issue
Block a user