IBM1130: Pickup the latest utils from ibm1130software.zip from ibm1130.org

- ibm1130software.zip was contained within ibm1130.zip from ibm1130.org
- Tabs converted to spaces
This commit is contained in:
Mark Pizzolato 2017-05-08 09:28:50 -07:00
parent 2c6c8f4ef8
commit 58f6e7d2db
9 changed files with 3936 additions and 1319 deletions

File diff suppressed because it is too large Load diff

View file

@ -36,10 +36,25 @@
typedef enum {R_ABSOLUTE = 0, R_RELATIVE = 1, R_LIBF = 2, R_CALL = 3} RELOC;
typedef enum {PACKED, UNPACKED} PACKMODE;
#define CARDTYPE_COREIMAGE 0x00
#define CARDTYPE_ABS 0x01
#define CARDTYPE_REL 0x02
#define CARDTYPE_LIB 0x03
#define CARDTYPE_SUB 0x04
#define CARDTYPE_ISSL 0x05
#define CARDTYPE_ISSC 0x06
#define CARDTYPE_ILS 0x07
#define CARDTYPE_END 0x0F
#define CARDTYPE_ENDC 0x80
#define CARDTYPE_81 0x81
#define CARDTYPE_DATA 0x0A
BOOL verbose = FALSE;
BOOL phid = FALSE;
BOOL sort = FALSE;
unsigned short card[80], buf[54], cardtype;
unsigned short card[80], buf[54];
// bindump - dump a binary (card format) deck to verify sbrks, etc
@ -63,8 +78,11 @@ void show_iss (void);
void show_end (void);
void sort_phases (char *fname);
void trim (char *s);
void unpack (unsigned short *card, unsigned short *buf);
void unpack (unsigned short *icard, unsigned short *obuf, int nwords);
void pack (unsigned short *ocard, unsigned short *ibuf);
void verify_checksum(unsigned short *buf);
int type_of_card(unsigned short *buf, PACKMODE packed);
char *card_type_name (unsigned short cardtype);
int main (int argc, char **argv)
{
@ -99,6 +117,7 @@ int main (int argc, char **argv)
if (*arg != '-')
process(arg);
}
return 0;
}
@ -188,6 +207,12 @@ void sort_phases (char *fname)
ncards = len / 160;
if (ncards <= 0) {
fprintf(stderr, "%s: can't sort, empty deck\n");
fclose(fd);
return;
}
if ((deck = (struct tag_card *) malloc(ncards*sizeof(struct tag_card))) == NULL) {
fprintf(stderr, "%s: can't sort, insufficient memory\n");
fclose(fd);
@ -203,32 +228,40 @@ void sort_phases (char *fname)
return;
}
unpack(deck[i].card, buf);
deck[i].seq = seq++;
deck[i].phid = phid;
deck[i].seq = seq++; // store current sequence
deck[i].phid = phid; // store current phase ID
cardtype = type_of_card(deck[i].card, PACKED);
switch (cardtype) {
case CARDTYPE_ABS: // start of deck is same as sector break
saw_sbrk = TRUE; // (though I don't ever expect to get a REL deck)
break;
case CARDTYPE_DATA:
if (saw_sbrk) {
unpack(deck[i].card, buf, 0);
verify_checksum(buf);
cardtype = (buf[2] >> 8) & 0xFF;
if (cardtype == 1 || cardtype == 2) { // start of deck is same as sector break
saw_sbrk = TRUE;
}
else if (cardtype == 0) {
fprintf(stderr, "%s is a core image deck\n");
free(deck);
fclose(fd);
return;
}
else if (cardtype == 0x0A && saw_sbrk) {
phid = (int) (signed short) buf[10];
if (phid < 0)
phid = -phid;
deck[i].phid = phid; // this belongs to the new phase
deck[i-1].phid = phid; // as does previous card
deck[i-1].phid = phid; // as does previous card (START or SBRK card)
saw_sbrk = FALSE;
}
break;
case CARDTYPE_END:
break;
default:
fprintf(stderr, "%s is a %s deck, can't sort\n", card_type_name(cardtype));
free(deck);
fclose(fd);
return;
}
}
fclose(fd);
@ -238,8 +271,18 @@ void sort_phases (char *fname)
_setmode(_fileno(stdout), _O_BINARY); // set standard output to binary mode
#endif
for (i = 0; i < ncards; i++) // write to stdout
fxwrite(deck[i].card, sizeof(card[0]), 80, stdout);
for (i = 0; i < ncards; i++) { // write to stdout
cardtype = type_of_card(deck[i].card, PACKED);
if (cardtype != CARDTYPE_END || (i == (ncards-1))) // don't write embedded END cards
fxwrite(deck[i].card, sizeof(deck[i].card[0]), 80, stdout);
}
if (cardtype != CARDTYPE_END) { // fudge an end card
memset(buf, 0, sizeof(buf));
buf[2] = CARDTYPE_END;
pack(card, buf);
fxwrite(card, sizeof(card[0]), 80, stdout);
}
free(deck);
}
@ -247,8 +290,8 @@ void sort_phases (char *fname)
void dump_phids (char *fname)
{
FILE *fp;
BOOL first = TRUE;
BOOL saw_sbrk = TRUE, neg;
BOOL saw_sbrk = FALSE, neg;
unsigned short cardtype;
short id;
if ((fp = fopen(fname, "rb")) == NULL) {
@ -259,33 +302,23 @@ void dump_phids (char *fname)
printf("\n%s:\n", fname);
while (fxread(card, sizeof(card[0]), 80, fp) > 0) {
unpack(card, buf);
verify_checksum(buf);
cardtype = type_of_card(card, PACKED);
cardtype = (buf[2] >> 8) & 0xFF;
if (cardtype == 1 && ! first) { // sector break
saw_sbrk = TRUE;
continue;
if (saw_sbrk && cardtype != CARDTYPE_DATA) {
printf("DECK STRUCTURE ERROR: ABS/SBRK card was followed by %s, not DATA", card_type_name(cardtype));
}
else {
switch (cardtype) {
case 0x00:
printf(" This is a core image deck\n");
goto done;
break;
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x0F:
case CARDTYPE_ABS: // beginning of absolute deck, or SBRK card (which spoofs an ABS start card)
saw_sbrk = TRUE;
break;
case 0x0A:
if (saw_sbrk) {
case CARDTYPE_END:
break;
case CARDTYPE_DATA:
if (saw_sbrk) { // first data card after a SBRK or new deck has the phase ID
unpack(card, buf, 11);
id = buf[10];
if (id < 0)
id = -id, neg = TRUE;
@ -296,13 +329,20 @@ void dump_phids (char *fname)
}
break;
case CARDTYPE_COREIMAGE:
case CARDTYPE_REL:
case CARDTYPE_LIB:
case CARDTYPE_SUB:
case CARDTYPE_ISSL:
case CARDTYPE_ISSC:
case CARDTYPE_ILS:
printf("%s module not expected in a system load deck\n", card_type_name(cardtype));
break;
default:
show_raw("??? ");
}
}
done:
first = FALSE;
}
fclose(fp);
}
@ -311,6 +351,7 @@ void dump_data (char *fname)
{
FILE *fp;
BOOL first = TRUE;
unsigned short cardtype;
char str[80];
int i;
@ -322,10 +363,10 @@ void dump_data (char *fname)
printf("\n%s:\n", fname);
while (fxread(card, sizeof(card[0]), 80, fp) > 0) {
unpack(card, buf);
unpack(card, buf, 0);
verify_checksum(buf);
cardtype = (buf[2] >> 8) & 0xFF;
cardtype = type_of_card(buf, UNPACKED);
if (cardtype == 1 && ! first) { // sector break
for (i = 4; i < 72; i++)
@ -338,54 +379,54 @@ void dump_data (char *fname)
}
else {
switch (cardtype) {
case 0x00:
case CARDTYPE_COREIMAGE:
if (first)
show_raw("CORE");
if (verbose)
show_core();
break;
case 0x01:
case CARDTYPE_ABS:
show_raw("ABS ");
show_main();
break;
case 0x02:
case CARDTYPE_REL:
show_raw("REL ");
show_main();
break;
case 0x03:
case CARDTYPE_LIB:
show_raw("LIB ");
show_sub();
break;
case 0x04:
case CARDTYPE_SUB:
show_raw("SUB ");
show_sub();
break;
case 0x05:
case CARDTYPE_ISSL:
show_raw("ISSL");
show_iss();
break;
case 0x06:
case CARDTYPE_ISSC:
show_raw("ISSC");
show_iss();
break;
case 0x07:
case CARDTYPE_ILS:
show_raw("ILS ");
show_ils();
break;
case 0x0F:
case CARDTYPE_END:
show_raw("END ");
show_end();
break;
case 0x80:
case CARDTYPE_ENDC:
show_raw("ENDC");
show_endc();
break;
case 0x81:
case CARDTYPE_81:
show_raw("81 ");
show_81();
break;
case 0x0A:
case CARDTYPE_DATA:
if (verbose)
show_data();
break;
@ -584,20 +625,40 @@ void bail (char *msg)
exit(1);
}
void unpack (unsigned short *icard, unsigned short *obuf)
// unpack nwords of data from card image icard into buffer obuf
void unpack (unsigned short *icard, unsigned short *obuf, int nwords)
{
int i, j;
unsigned short wd1, wd2, wd3, wd4;
for (i = j = 0; i < 54; i += 3, j += 4) {
wd1 = icard[j];
wd2 = icard[j+1];
wd3 = icard[j+2];
wd4 = icard[j+3];
if (nwords <= 0 || nwords > 54) nwords = 54; // the default is to unpack all 54 words
obuf[i ] = (wd1 & 0xFFF0) | ((wd2 >> 12) & 0x000F);
obuf[i+1] = ((wd2 << 4) & 0xFF00) | ((wd3 >> 8) & 0x00FF);
obuf[i+2] = ((wd3 << 8) & 0xF000) | ((wd4 >> 4) & 0x0FFF);
for (i = j = 0; i < nwords; i++) {
wd1 = icard[j++];
wd2 = icard[j++];
wd3 = icard[j++];
wd4 = icard[j++];
obuf[i] = (wd1 & 0xFFF0) | ((wd2 >> 12) & 0x000F);
if (++i >= nwords) break;
obuf[i] = ((wd2 << 4) & 0xFF00) | ((wd3 >> 8) & 0x00FF);
if (++i >= nwords) break;
obuf[i] = ((wd3 << 8) & 0xF000) | ((wd4 >> 4) & 0x0FFF);
}
}
// pack - pack 54 words of data in ibuf into card image icard
void pack (unsigned short *ocard, unsigned short *ibuf)
{
int i, j;
for (i = j = 0; i < 54; i += 3, j += 4) {
ocard[j ] = ( ibuf[i] & 0xFFF0);
ocard[j+1] = ((ibuf[i] << 12) & 0xF000) | ((ibuf[i+1] >> 4) & 0x0FF0);
ocard[j+2] = ((ibuf[i+1] << 8) & 0xFF00) | ((ibuf[i+2] >> 8) & 0x00F0);
ocard[j+3] = ((ibuf[i+2] << 4) & 0xFFF0);
}
}
@ -752,4 +813,35 @@ char *getname (unsigned short *ptr)
return str;
}
int type_of_card (unsigned short *buf, PACKMODE packed)
{
unsigned short unp[3];
// card type is the 3rd unpacked word on the card
if (packed == PACKED) {
unpack(buf, unp, 3); // unpack the first 3 words only
buf = unp;
}
return (buf[2] >> 8) & 0xFF;
}
char * card_type_name (unsigned short cardtype)
{
switch (cardtype) {
case CARDTYPE_COREIMAGE: return "core image";
case CARDTYPE_ABS: return "absolute";
case CARDTYPE_REL: return "relative";
case CARDTYPE_LIB: return "LIB";
case CARDTYPE_SUB: return "SUB";
case CARDTYPE_ISSL: return "ISSL";
case CARDTYPE_ISSC: return "ISSC";
case CARDTYPE_ILS: return "ILS";
case CARDTYPE_END: return "END";
case CARDTYPE_ENDC: return "ENDC";
case CARDTYPE_81: return "81";
case CARDTYPE_DATA: return "data";
}
return "unknown";
}

1547
Ibm1130/utils/disklist.c Normal file

File diff suppressed because it is too large Load diff

178
Ibm1130/utils/disklist.mak Normal file
View file

@ -0,0 +1,178 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "disklist.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/disklist.exe $(OUTDIR)/disklist.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"disklist.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"disklist.bsc"
BSC32_SBRS= \
$(INTDIR)/disklist.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/disklist.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no\
/PDB:$(OUTDIR)/"disklist.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"disklist.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/disklist.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/disklist.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/disklist.exe $(OUTDIR)/disklist.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"disklist.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"disklist.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"disklist.bsc"
BSC32_SBRS= \
$(INTDIR)/disklist.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/disklist.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes\
/PDB:$(OUTDIR)/"disklist.pdb" /DEBUG /MACHINE:I386\
/OUT:$(OUTDIR)/"disklist.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/disklist.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/disklist.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\disklist.c
$(INTDIR)/disklist.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
DEP_UTIL_=\
.\util_io.h
$(INTDIR)/util_io.obj : $(SOURCE) $(DEP_UTIL_) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

View file

@ -21,7 +21,8 @@ IOLIB_SRC = util_io.c
#
all : ${BIN}asm1130 ${BIN}bindump ${BIN}checkdisk \
${BIN}diskview ${BIN}mkboot ${BIN}viewdeck
${BIN}diskview ${BIN}mkboot ${BIN}viewdeck \
${BIN}disklist ${BIN}punches
#
# Individual builds
@ -36,6 +37,9 @@ ${BIN}bindump : bindump.c ${IOLIB_DEP}
${BIN}checkdisk : checkdisk.c ${IOLIB_DEP}
${CC} checkdisk.c ${IOLIB_SRC} -o $@
${BIN}disklist : disklist.c ${IOLIB_DEP}
${CC} disklist.c ${IOLIB_SRC} -o $@
${BIN}diskview : diskview.c ${IOLIB_DEP}
${CC} diskview.c ${IOLIB_SRC} -o $@
@ -45,3 +49,5 @@ ${BIN}mkboot : mkboot.c ${IOLIB_DEP}
${BIN}viewdeck : viewdeck.c ${IOLIB_DEP}
${CC} viewdeck.c ${IOLIB_SRC} -o $@
${BIN}punches : punches.c ${IOLIB_DEP}
${CC} punches.c ${IOLIB_SRC} -o $@

337
Ibm1130/utils/punches.c Normal file
View file

@ -0,0 +1,337 @@
/*
* punches - convert beteen IBM1130 simulator binary card image format and ascii text lists of punch numbers
*
* Usage:
* punches -b [infile [outfile]]
* Converts from ascii to binary. Reads stdin/writes stdout if infile/outfile not specified
*
* punches -a [infile [outfile]]
* Converts from binary to ascii.
*
* The ASCII format consists of an arbitrary number of card images. Each card image consists of
* a line with the word "start", followed by 80 lines each containing the punch data for one card
* column, followe by a line with the word "end".
*
* A column specification line consists of the word "blank", for a column with no punches,
* or an arbitrary number of integer row names separated by hyphens. The row names are 12, 11, 0, 1, 2, ..., 9.
*
* The character #, * or ; terminates an input line and the remainder of the line is ignored as a comment.
* Blank lines are ignored and may occur at any place in the input file.
*
* A typical card specification might look like this:
start
* This is a comment line
12-1-2
blank
5 # this is a comment after the data for column 3
4
2
blank
blank
11-5
2-6-3
. \
. | not all lines shown. Exactly 80 data lines are required
. /
blank
12-0-2-6-7-8
end
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util_io.h"
#ifdef WIN32 // for Windows binary file mode setting
# include <io.h>
# include <fcntl.h>
#endif
#define TRUE 1
#define FALSE 0
typedef int BOOL;
#define BETWEEN(v,a,b) (((v) >= (a)) && ((v) <= (b)))
BOOL failed = FALSE;
int ncards = 0;
void tobinary (char *fnin, char *fnout);
void toascii (char *fnin, char *fnout);
void bail (char *msg);
int main (int argc, char **argv)
{
enum {MODE_UNKNOWN, MODE_TOBINARY, MODE_TOASCII} mode = MODE_UNKNOWN;
int i;
char *arg, *fnin = NULL, *fnout = NULL;
static char usestr[] = "Usage: punches -b|-a [infile [outfile]]";
for (i = 1; i < argc; i++) {
arg = argv[i];
if (*arg == '-') {
arg++;
while (*arg) {
switch (*arg++) {
case 'b':
mode = MODE_TOBINARY;
break;
case 'a':
mode = MODE_TOASCII;
break;
default:
bail(usestr);
}
}
}
else if (fnin == NULL)
fnin = arg;
else if (fnout == NULL)
fnout = arg;
else
bail(usestr);
}
util_io_init(); // check CPU for big/little endianness
if (mode == MODE_TOBINARY)
tobinary(fnin, fnout);
else if (mode == MODE_TOASCII)
toascii(fnin, fnout);
else
bail(usestr);
if (failed) {
if (fnin != NULL) { // if there was an error, delete output file if possible
unlink(fnout);
fprintf(stderr, "Output file \"%s\" deleted\n", fnout);
exit(1);
}
else
bail("Output file is incorrect");
}
else // if no error, tell how many cards we converted
fprintf(stderr, "* %d card%s converted\n", ncards, (ncards == 1) ? "" : "s");
return 0;
}
// alltrim - remove string's leading and trailing whitespace
char *alltrim (char *str)
{
char *c, *e;
for (c = str; *c && *c <= ' '; c++) // skip over leading whitespace
;
if (c > str) // if there was some, copy string down over it
strcpy(str, c);
for (e = str-1, c = str; *c; c++) // find last non-white character
if (*c > ' ')
e = c;
e[1] = '\0'; // terminate string immediately after last nonwhite character
return str; // return pointer to string
}
void tobinary (char *fnin, char *fnout)
{
FILE *fin, *fout;
BOOL gotnum;
int col, v, lineno = 0;
char str[256], *c;
unsigned short buf[80], punches;
static unsigned short punchval[13] = {
0x2000, 0x1000, 0x0800, 0x0400, 0x0200, // 0, 1, 2, 3, 4
0x0100, 0x0080, 0x0040, 0x0020, 0x0010, // 5, 6, 7, 8, 9
0x0000, // there is no 10 punch
0x4000, 0x8000}; // 11 and 12.
if (fnin == NULL) {
fin = stdin;
}
else if ((fin = fopen(fnin, "r")) == NULL) {
perror(fnin);
exit(1);
}
if (fnout == NULL) {
fout = stdout;
#ifdef WIN32
_setmode(_fileno(stdout), _O_BINARY);
#endif
}
else if ((fout = fopen(fnout, "wb")) == NULL) {
perror(fnout);
exit(1);
}
col = 0; // we are starting between cards, expect start as first data line
while (fgets(str, sizeof(str), fin) != NULL && ! failed) {
alltrim(str); // trim leading/trailing blanks (including newline)
lineno++; // count input line
if (*str == ';' || *str == '#'|| *str == '*' || ! *str)
continue; // ignore comment or blank line
if (strnicmp(str, "start", 5) == 0) { // start marks new card, proceed to column 1 (strnicmp so trailing comment is ignored)
if (col == 0)
col = 1;
else {
fprintf(stderr, "\"start\" encountered where column %d was expected, at line %d\n", lineno);
failed = TRUE;
}
}
else if (strnicmp(str, "end", 3) == 0) { // end is expected as 81'st data line
if (col == 81) {
fxwrite(buf, 2, 80, fout); // write binary card image to output file
ncards++; // increment card count
col = 0; // reset, expect start next
}
else {
fprintf(stderr, "\"end\" encountered where ");
if (col == 0)
fprintf(stderr, "\"start\"");
else
fprintf(stderr, "column %d", col);
fprintf(stderr, " was expected, at line %d\n", lineno);
failed = TRUE;
}
}
else if (BETWEEN(col, 1, 80)) { // for column 1 to 80, we expect a data line
if (strnicmp(str, "blank", 5) == 0) { // blank indicates an unpunched column
buf[col-1] = 0;
col++;
}
else {
punches = 0; // prepare to parse a data line. Punches is output binary value for column
v = 0; // v is current punch number
gotnum = FALSE; // gotnum indicates we've seen a punch number
for (c = str; ! failed; c++) {
if (BETWEEN(*c, '0', '9')) { // this is a digit, accumulate into current punch number
v = v*10 + *c - '0';
gotnum = TRUE; // note that we've seen a value
}
else if (*c == '-' || *c == '\0') { // at - separator or at end of string
if (gotnum && BETWEEN(v, 0, 12) && v != 10)
punches |= punchval[v]; // add correct bit to column binary value
else { // error if number not seen or punch number not 0..9, 11, or 12
fprintf(stderr, "Invalid punch value %d at line %d\n", v, lineno);
failed = TRUE;
break;
}
if (*c == '\0') { // at end of string store value and advance column count
buf[col-1] = punches;
col++;
break;
}
else {
v = 0; // at separator, reset for next punch value
gotnum = FALSE;
}
}
else if (*c == '#' || *c == ';' || *c == '*') {
break; // terminate line parsing at comment character
}
else { // invalid character
fprintf(stderr, "Unexpected character '%c' at line %d\n", *c, lineno);
failed = TRUE;
break;
}
}
}
}
else { // we expected start or end when not expecting column data
fprintf(stderr, "\"%s\" encountered where \"%s\" was expected, at line %d\n", str,
(col == 0) ? "start" : "end", lineno);
failed = TRUE;
}
}
fclose(fin);
fclose(fout);
}
void toascii (char *fnin, char *fnout)
{
FILE *fin, *fout;
unsigned short buf[80], mask;
int nread, col, row;
BOOL first;
static char *punchname[] = {"12", "11", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
if (fnin == NULL) {
fin = stdin; // no input file named, read from stdin
#ifdef WIN32
_setmode(_fileno(stdin), _O_BINARY); // (on Windows, must set binary mode)
#endif
}
else if ((fin = fopen(fnin, "rb")) == NULL) { // open named input file
perror(fnin);
exit(1);
}
if (fnout == NULL) { // no output file named, write to stdout
fout = stdout;
}
else if ((fout = fopen(fnout, "wb")) == NULL) { // open named output file
perror(fnout);
exit(1);
}
// write comment with input file name
fprintf(fout, "* converted from %s\n", (fnin == NULL) ? "<stdin>" : fnin);
while ((nread = fxread(buf, 2, 80, fin)) == 80) { // pull cards from binary file
ncards++; // increment card count
fprintf(fout, "**** card %d\nstart\n", ncards); // write comment with card number and start statement
for (col = 0; col < 80; col++) { // dump 80 columns
if (buf[col] == 0) {
fprintf(fout, "blank\n"); // no punches this column
}
else if (buf[col] & 0x000F) { // if low bits are set it is not a valid IBM1130 card image
fprintf(stderr, "Input file is not an IBM 1130 card image, low bits set found at card image %d\n", ncards);
failed = TRUE;
break;
}
else {
first = TRUE; // scan the 12 punch bits
for (mask = 0x8000, row = 0; row < 12; row++, mask >>= 1) {
if (buf[col] & mask) { // output name of punch row for each bit set (12, 10, 0, ..., 9)
fprintf(fout, "%s%s", first ? "" : "-", punchname[row]);
first = FALSE; // next punch will need a hyphen
}
}
putc('\n', fout);
}
}
fprintf(fout, "end\n");
}
if (nread != 0) { // oops, file wasn't a multiple of 160 bytes in length
fprintf(stderr, "Input file invalid or contained a partial card image\n");
failed = TRUE;
}
fclose(fin);
fclose(fout);
}
void bail (char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}

176
Ibm1130/utils/punches.mak Normal file
View file

@ -0,0 +1,176 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "punches.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/punches.exe $(OUTDIR)/punches.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /ML /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /ML /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /ML /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"punches.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"punches.bsc"
BSC32_SBRS= \
$(INTDIR)/punches.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/punches.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no\
/PDB:$(OUTDIR)/"punches.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"punches.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/punches.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/punches.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/punches.exe $(OUTDIR)/punches.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /ML /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /ML /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /ML /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"punches.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"punches.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"punches.bsc"
BSC32_SBRS= \
$(INTDIR)/punches.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/punches.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes\
/PDB:$(OUTDIR)/"punches.pdb" /DEBUG /MACHINE:I386 /OUT:$(OUTDIR)/"punches.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/punches.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/punches.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\punches.c
$(INTDIR)/punches.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
DEP_UTIL_=\
.\util_io.h
$(INTDIR)/util_io.obj : $(SOURCE) $(DEP_UTIL_) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

155
Ibm1130/utils/util_io.c Normal file
View file

@ -0,0 +1,155 @@
// util_io - I/O routines from simh package -- "endian-independent"
// borrowed from scp.c, with this copyright notice:
// use fxread and fxwrite instead of fread and fwrite
/*
Copyright (c) 1993-2002, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
*/
/* Endian independent binary I/O package
For consistency, all binary data read and written by the simulator
is stored in little endian data order. That is, in a multi-byte
data item, the bytes are written out right to left, low order byte
to high order byte. On a big endian host, data is read and written
from high byte to low byte. Consequently, data written on a little
endian system must be byte reversed to be usable on a big endian
system, and vice versa.
These routines are analogs of the standard C runtime routines
fread and fwrite. If the host is little endian, or the data items
are size char, then the calls are passed directly to fread or
fwrite. Otherwise, these routines perform the necessary byte swaps
using an intermediate buffer.
*/
#include <stdio.h>
#include "util_io.h"
#define int32 int
#define FLIP_SIZE 1024 /* make the flip buffer smaller for these utilities */
static int sim_end = 1; /* 1 = little-endian */
static unsigned char sim_flip[FLIP_SIZE];
static int end_tested = 0;
void util_io_init (void)
{
union {int32 i; char c[sizeof (int32)]; } end_test;
end_test.i = 1; /* test endian-ness */
sim_end = end_test.c[0];
end_tested = 1;
}
size_t fxread (void *bptr, size_t size, size_t count, FILE *fptr)
{
size_t c, j, nelem, nbuf, lcnt, total;
int32 i, k;
unsigned char *sptr, *dptr;
if (! end_tested)
util_io_init();
if (sim_end || (size == sizeof(char)))
return fread(bptr, size, count, fptr);
if ((size == 0) || (count == 0))
return 0;
nelem = FLIP_SIZE / size; /* elements in buffer */
nbuf = count / nelem; /* number buffers */
lcnt = count % nelem; /* count in last buf */
if (lcnt)
++nbuf;
else
lcnt = nelem;
total = 0;
dptr = bptr; /* init output ptr */
for (i = nbuf; i > 0; i--) {
if ((c = fread(sim_flip, size, (i == 1) ? lcnt : nelem, fptr)) == 0)
return total;
total += c;
for (j = 0, sptr = sim_flip; j < c; j++) {
for (k = size - 1; k >= 0; k--)
*(dptr + k) = *sptr++;
dptr += size;
}
}
return total;
}
size_t fxwrite (void *bptr, size_t size, size_t count, FILE *fptr)
{
size_t c, j, nelem, nbuf, lcnt, total;
int32 i, k;
unsigned char *sptr, *dptr;
if (! end_tested)
util_io_init();
if (sim_end || (size == sizeof(char)))
return fwrite(bptr, size, count, fptr);
if ((size == 0) || (count == 0))
return 0;
nelem = FLIP_SIZE / size; /* elements in buffer */
nbuf = count / nelem; /* number buffers */
lcnt = count % nelem; /* count in last buf */
if (lcnt)
++nbuf;
else
lcnt = nelem;
total = 0;
sptr = bptr; /* init input ptr */
for (i = nbuf; i > 0; i--) {
c = (i == 1) ? lcnt : nelem;
for (j = 0, dptr = sim_flip; j < c; j++) {
for (k = size - 1; k >= 0; k--)
*(dptr + k) = *sptr++;
dptr += size;
}
if ((c = fwrite(sim_flip, size, c, fptr)) == 0)
return total;
total += c;
}
return total;
}

10
Ibm1130/utils/util_io.h Normal file
View file

@ -0,0 +1,10 @@
// util_io.h - definitions for simulator io routines
#ifndef FILE
# include <stdio.h>
#endif
void util_io_init(void);
size_t fxread (void *bptr, size_t size, size_t count, FILE *fptr);
size_t fxwrite (void *bptr, size_t size, size_t count, FILE *fptr);