B5500: Added EBCDIC support to sim_card.

This commit is contained in:
Richard Cornwell 2016-04-29 09:26:40 -04:00 committed by Mark Pizzolato
parent 3f4eed7517
commit f4300500e8
2 changed files with 164 additions and 178 deletions

View file

@ -249,6 +249,75 @@ const char sim_ascii_to_six[128] = {
027, 030, 031, 057, 077, 017, -1, -1 027, 030, 031, 057, 077, 017, -1, -1
}; };
static uint16 ebcdic_to_hol[256] = {
/* T0918 T91 T92 T93 T94 T95 T96 T97 0x0x */
0xB03, 0x901, 0x881, 0x841, 0x821, 0x811, 0x809, 0x805,
/* T98, T918 , T928, T938, T948, T958, T968, T978 */
0x803, 0x903, 0x883, 0x843, 0x823, 0x813, 0x80B, 0x807,
/* TE918 E91 E92 E93 E94 E95 E96 E97 0x1x */
0xD03, 0x501, 0x481, 0x441, 0x421, 0x411, 0x409, 0x405,
/* E98 E918 E928 E938 E948 E958 E968 E978 */
0x403, 0x503, 0x483, 0x443, 0x423, 0x413, 0x40B, 0x407,
/* E0918 091 092 093 094 095 096 097 0x2x */
0x703, 0x301, 0x281, 0x241, 0x221, 0x211, 0x209, 0x205,
/* 098 0918 0928 0938 0948 0958 0968 0978 */
0x203, 0x303, 0x283, 0x243, 0x223, 0x213, 0x20B, 0x207,
/* TE0918 91 92 93 94 95 96 97 0x3x */
0xF03, 0x101, 0x081, 0x041, 0x021, 0x011, 0x009, 0x005,
/* 98 918 928 938 948 958 968 978 */
0x003, 0x103, 0x083, 0x043, 0x023, 0x013, 0x00B, 0x007,
/* T091 T092 T093 T094 T095 T096 T097 0x4x */
0x000, 0xB01, 0xA81, 0xA41, 0xA21, 0xA11, 0xA09, 0xA05,
/* T098 T18 T28 T38 T48 T58 T68 T78 */
0xA03, 0x902, 0x882, 0x842, 0x822, 0x812, 0x80A, 0x806,
/* T TE91 TE92 TE93 TE94 TE95 TE96 TE97 0x5x */
0x800, 0xD01, 0xC81, 0xC41, 0xC21, 0xC11, 0xC09, 0xC05,
/* TE98 E18 E28 E38 E48 E58 E68 E78 */
0xC03, 0x502, 0x482, 0x442, 0x422, 0x412, 0x40A, 0x406,
/* E 01 E092 E093 E094 E095 E096 E097 0x6x */
0x400, 0x300, 0x681, 0x641, 0x621, 0x611, 0x609, 0x605,
/* E098 018 TE 038 048 058 068 078 */
0x603, 0x302, 0xC00, 0x242, 0x222, 0x212, 0x20A, 0x206,
/* TE0 TE091 TE092 TE093 TE094 TE095 TE096 TE097 0x7x */
0xE00, 0xF01, 0xE81, 0xE41, 0xE21, 0xE11, 0xE09, 0xE05,
/* TE098 18 28 38 48 58 68 78 */
0xE03, 0x102, 0x082, 0x042, 0x022, 0x012, 0x00A, 0x006,
/* T018 T01 T02 T03 T04 T05 T06 T07 0x8x */
0xB02, 0xB00, 0xA80, 0xA40, 0xA20, 0xA10, 0xA08, 0xA04,
/* T08 T09 T028 T038 T048 T058 T068 T078 */
0xA02, 0xA01, 0xA82, 0xA42, 0xA22, 0xA12, 0xA0A, 0xA06,
/* TE18 TE1 TE2 TE3 TE4 TE5 TE6 TE7 0x9x */
0xD02, 0xD00, 0xC80, 0xC40, 0xC20, 0xC10, 0xC08, 0xC04,
/* TE8 TE9 TE28 TE38 TE48 TE58 TE68 TE78 */
0xC02, 0xC01, 0xC82, 0xC42, 0xC22, 0xC12, 0xC0A, 0xC06,
/* E018 E01 E02 E03 E04 E05 E06 E07 0xax */
0x702, 0x700, 0x680, 0x640, 0x620, 0x610, 0x608, 0x604,
/* E08 E09 E028 E038 E048 E058 E068 E078 */
0x602, 0x601, 0x682, 0x642, 0x622, 0x612, 0x60A, 0x606,
/* TE018 TE01 TE02 TE03 TE04 TE05 TE06 TE07 0xbx */
0xF02, 0xF00, 0xE80, 0xE40, 0xE20, 0xE10, 0xE08, 0xE04,
/* TE08 TE09 TE028 TE038 TE048 TE058 TE068 TE078 */
0xE02, 0xE01, 0xE82, 0xE42, 0xE22, 0xE12, 0xE0A, 0xE06,
/* T0 T1 T2 T3 T4 T5 T6 T7 0xcx */
0xA00, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804,
/* T8 T9 T0928 T0938 T0948 T0958 T0968 T0978 */
0x802, 0x801, 0xA83, 0xA43, 0xA23, 0xA13, 0xA0B, 0xA07,
/* E0 E1 E2 E3 E4 E5 E6 E7 0xdx */
0x600, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
/* E8 E9 TE928 TE938 TE948 TE958 TE968 TE978 */
0x402, 0x401, 0xC83, 0xC43, 0xC23, 0xC13, 0xC0B, 0xC07,
/* 028 E091 02 03 04 05 06 07 0xex */
0x182, 0x701, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
/* 08 09 E0928 E0938 E0948 E0958 E0968 E0978 */
0x202, 0x201, 0x683, 0x643, 0x623, 0x613, 0x60B, 0x607,
/* 0 1 2 3 4 5 6 7 0xfx */
0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004,
/* 8 9 TE0928 TE0938 TE0948 TE0958 TE0968 TE0978 */
0x002, 0x001, 0xE83, 0xE43, 0xE23, 0xE13, 0xE0B, 0xE07
};
static uint16 hol_to_ebcdic[4096];
const uint8 sim_parity_table[64] = { const uint8 sim_parity_table[64] = {
/* 0 1 2 3 4 5 6 7 */ /* 0 1 2 3 4 5 6 7 */
0000, 0100, 0100, 0000, 0100, 0000, 0000, 0100, 0000, 0100, 0100, 0000, 0100, 0000, 0000, 0100,
@ -272,6 +341,7 @@ static struct card_formats fmts[] = {
{MODE_TEXT, "TEXT"}, {MODE_TEXT, "TEXT"},
{MODE_BCD, "BCD"}, {MODE_BCD, "BCD"},
{MODE_CBN, "CBN"}, {MODE_CBN, "CBN"},
{MODE_EBCDIC,"EBCDIC"},
{0, 0}, {0, 0},
}; };
@ -376,137 +446,15 @@ sim_hol_to_bcd(uint16 hol) {
/* Convert EBCDIC character into hollerith code */ /* Convert EBCDIC character into hollerith code */
uint16 uint16
sim_ebcdic_to_hol(uint8 ebcdic) { sim_ebcdic_to_hol(uint8 ebcdic) {
uint16 hol = 0; return ebcdic_to_hol[ebcdic];
/* Convert middle two bits first */
switch (ebcdic & 0x30) {
default:
case 0x00:
hol = 0x800;
break;
case 0x10:
hol = 0x400;
break;
case 0x20:
hol = 0x200;
break;
case 0x30:
hol = 0x000;
break;
}
/* Now convert the two two bits */
switch (ebcdic & 0xc0) {
case 0x00:
hol |= 0x001; /* Col 9 */
break;
case 0x40:
case 0xc0: /* No change */
break;
case 0x80:
/* Add in correct over punch */
switch (ebcdic & 0x30) {
default:
case 0x00:
hol = 0x200;
break;
case 0x10:
hol = 0x800;
break;
case 0x20:
hol = 0x400;
break;
case 0x30:
hol = 0x000;
break;
}
} }
/* Convert lower four bits next */
if ((ebcdic & 0xf) > 9) {
hol |= 0x2; /* Col 8 */
hol |= 0x100 >> ((ebcdic & 0xf) - 10);
} else {
hol = 0x200 >> (ebcdic & 0xf);
}
return hol;
}
/* Returns the BCD of the hollerith code or 0x7f if error */ /* Returns the BCD of the hollerith code or 0x7f if error */
uint8 uint16
sim_hol_to_ebcdic(uint16 hol) { sim_hol_to_ebcdic(uint16 hol) {
uint8 ebcdic; return hol_to_ebcdic[hol];
/* Quick check for odd punch codes */
if (hol == 0)
return 0x20;
if (hol == 0x800) /* 12 punch only */
return 0x50;
if (hol == 0x400) /* 11 punch only */
return 0x50;
if (hol == 0xA83) /* 12-0-1-8-9 */
return 0x00;
if (hol == 0x683) /* 11-0-1-8-9 */
return 0x20;
/* Convert 10,11,12 rows */
switch (hol & 0xe00) {
case 0x000: /* No punch */
ebcdic = 0xf0;
break;
case 0x200: /* 10 punch */
ebcdic = 0xe0;
break;
case 0x400: /* 11 Punch */
ebcdic = 0xd0;
break;
case 0x800: /* 12 Punch */
ebcdic = 0xc0;
break;
case 0x600: /* 11-10 Punch */
ebcdic = 0xa0;
break;
case 0xA00: /* 12-10 Punch */
ebcdic = 0x80;
break;
case 0xc00: /* 12-11 Punch */
ebcdic = 0x90;
break;
default: /* Double punch in 10,11,12 rows */
return 0xff;
}
hol &= 0x1ff; /* Mask rows 0-9 */
/* Check row 8 punched */
if (hol & 0x2) {
ebcdic += 8;
hol &= ~0x2;
}
/* Check if 9 overpunch */
if ((hol & 0x1) && (hol & 0x3fc) != 0) {
ebcdic &= 0x30;
hol &= ~ 0x1;
}
/* Convert rows 0-9 */
while (hol != 0 && (hol & 0x200) == 0) {
ebcdic++;
hol <<= 1;
}
/* Remap over punchs */
if ((ebcdic & 0xc0) == 0xc0) {
if ((ebcdic & 0xf) > 9)
ebcdic &= 0x7f;
}
/* Any more columns punched? */
if ((hol & 0x1ff) != 0)
return 0xff;
return ebcdic;
} }
@ -584,7 +532,9 @@ sim_read_card(UNIT * uptr)
/* Clear image buffer */ /* Clear image buffer */
for (col = 0; col < 80; data->image[col++] = 0); for (col = 0; col < 80; data->image[col++] = 0);
if ((uptr->flags & UNIT_MODE) == MODE_AUTO) {
mode = MODE_TEXT; /* Default is text */ mode = MODE_TEXT; /* Default is text */
/* Check buffer to see if binary card in it. */ /* Check buffer to see if binary card in it. */
for (i = 0, temp = 0; i < 160; i+=2) for (i = 0, temp = 0; i < 160; i+=2)
temp |= data->cbuff[i]; temp |= data->cbuff[i];
@ -624,6 +574,8 @@ sim_read_card(UNIT * uptr)
sim_debug(DEBUG_CARD, dptr, "invalid mode\n\r"); sim_debug(DEBUG_CARD, dptr, "invalid mode\n\r");
return SCPE_IOERR; return SCPE_IOERR;
} }
} else
mode = uptr->flags & UNIT_MODE;
switch(mode) { switch(mode) {
case MODE_TEXT: case MODE_TEXT:
@ -713,8 +665,10 @@ sim_read_card(UNIT * uptr)
case MODE_BIN: case MODE_BIN:
temp = 0; temp = 0;
sim_debug(DEBUG_CARD, dptr, "bin\r\n"); sim_debug(DEBUG_CARD, dptr, "bin\r\n");
if (size < 160)
return SCPE_IOERR;
/* Move data to buffer */ /* Move data to buffer */
for (j = i = 0; i < size;) { for (j = i = 0; i < 160;) {
temp |= data->cbuff[i]; temp |= data->cbuff[i];
data->image[j] = (data->cbuff[i++] >> 4) & 0xF; data->image[j] = (data->cbuff[i++] >> 4) & 0xF;
data->image[j++] |= ((uint16)data->cbuff[i++]) << 4; data->image[j++] |= ((uint16)data->cbuff[i++]) << 4;
@ -723,9 +677,6 @@ sim_read_card(UNIT * uptr)
if (temp & 0xF) if (temp & 0xF)
r = SCPE_IOERR; r = SCPE_IOERR;
/* If not full record, return error */
if (size != 160)
r = SCPE_IOERR;
break; break;
case MODE_CBN: case MODE_CBN:
@ -786,6 +737,19 @@ sim_read_card(UNIT * uptr)
data->image[col++] = sim_bcd_to_hol(c); data->image[col++] = sim_bcd_to_hol(c);
} }
sim_debug(DEBUG_CARD, dptr, "]\r\n"); sim_debug(DEBUG_CARD, dptr, "]\r\n");
break;
case MODE_EBCDIC:
sim_debug(DEBUG_CARD, dptr, "ebcdic\n");
if (size < 80)
return SCPE_IOERR;
/* Move data to buffer */
for (i = 0; i < 80; i++) {
temp = data->cbuff[i];
data->image[i] = ebcdic_to_hol[temp];
}
break;
} }
if (i < size) if (i < size)
data->ptr = i; data->ptr = i;
@ -891,6 +855,7 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
} }
i = 160; i = 160;
break; break;
case MODE_CBN: case MODE_CBN:
sim_debug(DEBUG_CARD, dptr, "cbn\r\n"); sim_debug(DEBUG_CARD, dptr, "cbn\r\n");
/* Fill buffer */ /* Fill buffer */
@ -905,6 +870,7 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
out[0] |= 0x80; /* Set record mark */ out[0] |= 0x80; /* Set record mark */
i = 160; i = 160;
break; break;
case MODE_BCD: case MODE_BCD:
sim_debug(DEBUG_CARD, dptr, "bcd ["); sim_debug(DEBUG_CARD, dptr, "bcd [");
for (i = 0; i < 80; i++) { for (i = 0; i < 80; i++) {
@ -921,6 +887,16 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
while (i > 0 && out[--i] == 0); while (i > 0 && out[--i] == 0);
i++; i++;
break; break;
case MODE_EBCDIC:
sim_debug(DEBUG_CARD, dptr, "ebcdic\r\n");
/* Fill buffer */
for (i = 0; i < 80; i++) {
uint16 col = data->image[i];
out[i] = 0xff & hol_to_ebcdic[col];
}
i = 80;
break;
} }
sim_fwrite(out, 1, i, fo); sim_fwrite(out, 1, i, fo);
memset(&data->image[0], 0, sizeof(data->image)); memset(&data->image[0], 0, sizeof(data->image));
@ -987,6 +963,19 @@ sim_card_attach(UNIT * uptr, char *cptr)
} else { } else {
data = (struct _card_data *)uptr->up7; data = (struct _card_data *)uptr->up7;
} }
for (i = 0; i < 4096; i++)
hol_to_ebcdic[i] = 0x100;
for (i = 0; i < 256; i++) {
uint16 temp = ebcdic_to_hol[i];
if (hol_to_ebcdic[temp] != 0x100) {
fprintf(stderr, "Translation error %02x is %03x and %03x\n",
i, temp, hol_to_ebcdic[temp]);
} else {
hol_to_ebcdic[temp] = i;
}
}
memset(&data->hol_to_ascii[0], 0xff, 4096); memset(&data->hol_to_ascii[0], 0xff, 4096);
for(i = 0; i < (sizeof(ascii_to_hol_026)/sizeof(uint16)); i++) { for(i = 0; i < (sizeof(ascii_to_hol_026)/sizeof(uint16)); i++) {
uint16 temp; uint16 temp;
@ -999,9 +988,6 @@ sim_card_attach(UNIT * uptr, char *cptr)
case MODE_029: case MODE_029:
temp = ascii_to_hol_029[i]; temp = ascii_to_hol_029[i];
break; break;
case MODE_EBCDIC:
temp = ascii_to_hol_ebcdic[i];
break;
} }
if ((temp & 0xf000) == 0) { if ((temp & 0xf000) == 0) {
data->hol_to_ascii[temp] = i; data->hol_to_ascii[temp] = i;

View file

@ -70,11 +70,11 @@
#define MODE_TEXT (2 << UNIT_V_MODE) #define MODE_TEXT (2 << UNIT_V_MODE)
#define MODE_BCD (3 << UNIT_V_MODE) #define MODE_BCD (3 << UNIT_V_MODE)
#define MODE_CBN (4 << UNIT_V_MODE) #define MODE_CBN (4 << UNIT_V_MODE)
#define MODE_EBCDIC (5 << UNIT_V_MODE)
/* Allow lower case letters */ /* Allow lower case letters */
#define MODE_LOWER (8 << UNIT_V_MODE) #define MODE_LOWER (8 << UNIT_V_MODE)
#define MODE_026 (0x10 << UNIT_V_MODE) #define MODE_026 (0x10 << UNIT_V_MODE)
#define MODE_029 (0x20 << UNIT_V_MODE) #define MODE_029 (0x20 << UNIT_V_MODE)
#define MODE_EBCDIC (0x30 << UNIT_V_MODE)
#define MODE_CHAR (0x30 << UNIT_V_MODE) #define MODE_CHAR (0x30 << UNIT_V_MODE)