SIM_CARD: New interface to support stacking cards and save/restore.
This commit is contained in:
parent
a8d4fe8846
commit
8b1d058a63
2 changed files with 521 additions and 257 deletions
653
sim_card.c
653
sim_card.c
|
@ -62,12 +62,29 @@
|
||||||
and the backward translation table. Which is generated from the table.
|
and the backward translation table. Which is generated from the table.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(USE_SIM_CARD)
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "sim_defs.h"
|
#include "sim_defs.h"
|
||||||
#include "sim_card.h"
|
#include "sim_card.h"
|
||||||
|
|
||||||
|
#if defined(USE_SIM_CARD)
|
||||||
|
|
||||||
|
#define card_ctx up8
|
||||||
|
|
||||||
|
#define CARD_EOF 0x1000 /* This card is end of file card. */
|
||||||
|
#define CARD_ERR 0x2000 /* Return error for this card */
|
||||||
|
#define DECK_SIZE 1000 /* Number of cards to allocate at a time */
|
||||||
|
|
||||||
|
|
||||||
|
struct card_context
|
||||||
|
{
|
||||||
|
t_addr punch_count; /* Number of cards punched */
|
||||||
|
char cbuff[1024]; /* Read in buffer for cards */
|
||||||
|
uint8 hol_to_ascii[4096]; /* Back conversion table */
|
||||||
|
t_addr hopper_size; /* Size of hopper */
|
||||||
|
t_addr hopper_cards; /* Number of cards in hopper */
|
||||||
|
uint16 (*images)[1][80];
|
||||||
|
};
|
||||||
|
|
||||||
/* Character conversion tables */
|
/* Character conversion tables */
|
||||||
|
|
||||||
|
@ -462,7 +479,132 @@ sim_hol_to_ebcdic(uint16 hol) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int cmpcard(const char *p, const char *s) {
|
t_addr
|
||||||
|
sim_hopper_size(UNIT * uptr) {
|
||||||
|
struct card_context *data = (struct card_context *)uptr->card_ctx;
|
||||||
|
if (data == NULL)
|
||||||
|
return 0;
|
||||||
|
return data->hopper_cards;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_addr
|
||||||
|
sim_punch_count(UNIT * uptr) {
|
||||||
|
struct card_context *data = (struct card_context *)uptr->card_ctx;
|
||||||
|
if (data == NULL)
|
||||||
|
return 0;
|
||||||
|
return data->punch_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_addr
|
||||||
|
sim_card_input_hopper_count(UNIT *uptr) {
|
||||||
|
struct card_context *data = (struct card_context *)uptr->card_ctx;
|
||||||
|
uint16 col;
|
||||||
|
|
||||||
|
if (data == NULL || data->images == NULL)
|
||||||
|
return 0; /* attached? */
|
||||||
|
|
||||||
|
if (uptr->pos >= data->hopper_cards)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
col = (*data->images)[data->hopper_cards-1][0];
|
||||||
|
|
||||||
|
return (int)((data->hopper_cards - uptr->pos) - ((col & CARD_EOF) ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
t_addr
|
||||||
|
sim_card_output_hopper_count(UNIT *uptr) {
|
||||||
|
struct card_context *data = (struct card_context *)uptr->card_ctx;
|
||||||
|
|
||||||
|
if (data == NULL)
|
||||||
|
return 0; /* attached? */
|
||||||
|
|
||||||
|
return (int)data->punch_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
t_cdstat
|
||||||
|
sim_read_card(UNIT * uptr, uint16 image[80])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct card_context *data = (struct card_context *)uptr->card_ctx;
|
||||||
|
DEVICE *dptr;
|
||||||
|
uint16 (*img)[80];
|
||||||
|
t_stat r = CDSE_OK;
|
||||||
|
|
||||||
|
if (data == NULL || (uptr->flags & UNIT_ATT) == 0)
|
||||||
|
return CDSE_EMPTY; /* attached? */
|
||||||
|
if (data->hopper_cards == 0 || uptr->pos >= data->hopper_cards)
|
||||||
|
return CDSE_EMPTY;
|
||||||
|
|
||||||
|
dptr = find_dev_from_unit( uptr);
|
||||||
|
img = &(*data->images)[uptr->pos];
|
||||||
|
if (sim_deb && dptr && ((dptr)->dctrl & DEBUG_CARD)) {
|
||||||
|
if (image[0] & CARD_EOF) {
|
||||||
|
sim_debug(DEBUG_CARD, dptr, "Read hopper EOF\n");
|
||||||
|
} else if (image[0] & CARD_ERR) {
|
||||||
|
sim_debug(DEBUG_CARD, dptr, "Read hopper ERR\n");
|
||||||
|
} else {
|
||||||
|
uint8 out[81];
|
||||||
|
int ok = 1;
|
||||||
|
for (i = 0; i < 80; i++) {
|
||||||
|
out[i] = data->hol_to_ascii[(int)(*img)[i]];
|
||||||
|
if (out[i] == 0xff) {
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
sim_debug(DEBUG_CARD, dptr, "Read hopper: [");
|
||||||
|
for (i = 0; i < 80; i++) {
|
||||||
|
sim_debug(DEBUG_CARD, dptr, "%c", out[i]);
|
||||||
|
}
|
||||||
|
sim_debug(DEBUG_CARD, dptr, "]\n");
|
||||||
|
} else {
|
||||||
|
sim_debug(DEBUG_CARD, dptr, "Read hopper binary\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((*img)[0] & CARD_EOF)
|
||||||
|
r = CDSE_EOF;
|
||||||
|
else if ((*img)[0] & CARD_ERR)
|
||||||
|
r = CDSE_ERROR;
|
||||||
|
uptr->pos++;
|
||||||
|
data->punch_count++;
|
||||||
|
memcpy(image, img, 80 * sizeof(uint16));
|
||||||
|
image[0] &= 0xfff; /* Remove any CARD_EOF and CARD_ERR Flags */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if reader is at last card.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sim_card_eof(UNIT *uptr)
|
||||||
|
{
|
||||||
|
struct card_context *data = (struct card_context *)uptr->card_ctx;
|
||||||
|
uint16 col;
|
||||||
|
|
||||||
|
if (data == NULL || data->images == NULL)
|
||||||
|
return SCPE_UNATT; /* attached? */
|
||||||
|
|
||||||
|
if (uptr->pos >= data->hopper_cards)
|
||||||
|
return SCPE_UNATT;
|
||||||
|
|
||||||
|
col = (*data->images)[uptr->pos][0];
|
||||||
|
|
||||||
|
if (col & CARD_EOF)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct _card_buffer {
|
||||||
|
char buffer[8192+500]; /* Buffer data */
|
||||||
|
int len; /* Amount of data in buffer */
|
||||||
|
int size; /* Size of last card read */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _cmpcard(const char *p, const char *s) {
|
||||||
int i;
|
int i;
|
||||||
if (p[0] != '~')
|
if (p[0] != '~')
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -473,87 +615,34 @@ static int cmpcard(const char *p, const char *s) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
t_stat
|
t_stat
|
||||||
sim_read_card(UNIT * uptr)
|
_sim_parse_card(UNIT *uptr, DEVICE *dptr, struct _card_buffer *buf, uint16 (*image)[80]) {
|
||||||
{
|
int mode;
|
||||||
|
uint16 temp;
|
||||||
int i;
|
int i;
|
||||||
char c;
|
char c;
|
||||||
uint16 temp;
|
|
||||||
int mode;
|
|
||||||
int len;
|
|
||||||
int size;
|
|
||||||
int col;
|
int col;
|
||||||
struct _card_data *data;
|
|
||||||
DEVICE *dptr;
|
|
||||||
t_stat r = SCPE_OK;
|
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_ATT) == 0)
|
|
||||||
return SCPE_UNATT; /* attached? */
|
|
||||||
|
|
||||||
dptr = find_dev_from_unit( uptr);
|
|
||||||
data = (struct _card_data *)uptr->up7;
|
|
||||||
sim_debug(DEBUG_CARD, dptr, "Read card ");
|
sim_debug(DEBUG_CARD, dptr, "Read card ");
|
||||||
|
|
||||||
/* Move data to start at begining of buffer */
|
|
||||||
if (data->ptr > 0) {
|
|
||||||
int ptr = data->ptr;
|
|
||||||
int start = 0;
|
|
||||||
|
|
||||||
while (ptr < data->len)
|
|
||||||
(data->cbuff)[start++] = (data->cbuff)[ptr++];
|
|
||||||
data->len -= data->ptr;
|
|
||||||
/* On eof, just return */
|
|
||||||
if (!feof(uptr->fileref) && data->len < 512)
|
|
||||||
len = sim_fread(&data->cbuff[start], 1,
|
|
||||||
sizeof(data->cbuff) - start, uptr->fileref);
|
|
||||||
else
|
|
||||||
len = 0;
|
|
||||||
data->len += len;
|
|
||||||
size = data->len;
|
|
||||||
} else {
|
|
||||||
/* Load rest of buffer */
|
|
||||||
if (!feof(uptr->fileref)) {
|
|
||||||
len = sim_fread(&data->cbuff[0], 1, sizeof(data->cbuff), uptr->fileref);
|
|
||||||
size = len;
|
|
||||||
} else
|
|
||||||
len = size = 0;
|
|
||||||
data->len = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((len < 0 || size == 0) && feof(uptr->fileref)) {
|
|
||||||
sim_debug(DEBUG_CARD, dptr, "EOF\n");
|
|
||||||
return SCPE_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ferror(uptr->fileref)) { /* error? */
|
|
||||||
sim_perror("Card reader I/O error");
|
|
||||||
clearerr(uptr->fileref);
|
|
||||||
return SCPE_IOERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear image buffer */
|
|
||||||
for (col = 0; col < 80; data->image[col++] = 0);
|
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_CARD_MODE) == MODE_AUTO) {
|
if ((uptr->flags & UNIT_CARD_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 <buf->len; i+=2)
|
||||||
temp |= data->cbuff[i];
|
temp |= buf->buffer[i];
|
||||||
/* Check if every other char < 16 & full buffer */
|
/* Check if every other char < 16 & full buffer */
|
||||||
if (size == 160 && (temp & 0x0f) == 0)
|
if ((temp & 0x0f) == 0 && i == 160)
|
||||||
mode = MODE_BIN; /* Probably binary */
|
mode = MODE_BIN; /* Probably binary */
|
||||||
/* Check if maybe BCD or CBN */
|
/* Check if maybe BCD or CBN */
|
||||||
if (data->cbuff[0] & 0x80) {
|
if (buf->buffer[0] & 0x80) {
|
||||||
int odd = 0;
|
int odd = 0;
|
||||||
int even = 0;
|
int even = 0;
|
||||||
|
|
||||||
/* Clear record mark */
|
/* Clear record mark */
|
||||||
data->cbuff[0] &= 0x7f;
|
buf->buffer[0] &= 0x7f;
|
||||||
/* Check all chars for correct parity */
|
/* Check all chars for correct parity */
|
||||||
for(i = 0, temp = 0; i < size; i++) {
|
for(i = 0, temp = 0; i < buf->len; i++) {
|
||||||
uint8 ch = data->cbuff[i];
|
uint8 ch = buf->buffer[i];
|
||||||
/* Stop at EOR */
|
/* Stop at EOR */
|
||||||
if (ch & 0x80)
|
if (ch & 0x80)
|
||||||
break;
|
break;
|
||||||
|
@ -564,7 +653,7 @@ sim_read_card(UNIT * uptr)
|
||||||
odd++;
|
odd++;
|
||||||
}
|
}
|
||||||
/* Restore it */
|
/* Restore it */
|
||||||
data->cbuff[0] |= 0x80;
|
buf->buffer[0] |= 0x80;
|
||||||
if (i == 160 && odd == i)
|
if (i == 160 && odd == i)
|
||||||
mode = MODE_CBN;
|
mode = MODE_CBN;
|
||||||
else if (i < 80 && even == i)
|
else if (i < 80 && even == i)
|
||||||
|
@ -574,8 +663,9 @@ sim_read_card(UNIT * uptr)
|
||||||
/* Check if modes match */
|
/* Check if modes match */
|
||||||
if ((uptr->flags & UNIT_CARD_MODE) != MODE_AUTO &&
|
if ((uptr->flags & UNIT_CARD_MODE) != MODE_AUTO &&
|
||||||
(uptr->flags & UNIT_CARD_MODE) != mode) {
|
(uptr->flags & UNIT_CARD_MODE) != mode) {
|
||||||
|
(*image)[0] = CARD_ERR;
|
||||||
sim_debug(DEBUG_CARD, dptr, "invalid mode\n");
|
sim_debug(DEBUG_CARD, dptr, "invalid mode\n");
|
||||||
return SCPE_IOERR;
|
return SCPE_OPENERR;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
mode = uptr->flags & UNIT_CARD_MODE;
|
mode = uptr->flags & UNIT_CARD_MODE;
|
||||||
|
@ -585,10 +675,10 @@ sim_read_card(UNIT * uptr)
|
||||||
case MODE_TEXT:
|
case MODE_TEXT:
|
||||||
sim_debug(DEBUG_CARD, dptr, "text: [");
|
sim_debug(DEBUG_CARD, dptr, "text: [");
|
||||||
/* Check for special codes */
|
/* Check for special codes */
|
||||||
if (data->cbuff[0] == '~') {
|
if (buf->buffer[0] == '~') {
|
||||||
int f = 1;
|
int f = 1;
|
||||||
for(col = i = 1; col < 80 && f; i++) {
|
for(col = i = 1; col < 80 && f && i < buf->len; i++) {
|
||||||
c = data->cbuff[i];
|
c = buf->buffer[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\0':
|
case '\0':
|
||||||
|
@ -605,23 +695,21 @@ sim_read_card(UNIT * uptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (f) {
|
if (f) {
|
||||||
r = SCPE_EOF;
|
(*image)[0] |= CARD_EOF;
|
||||||
goto end_card;
|
goto end_card;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cmpcard(&data->cbuff[0], "raw")) {
|
if (_cmpcard(&buf->buffer[0], "raw")) {
|
||||||
int j = 0;
|
int j = 0;
|
||||||
sim_debug(DEBUG_CARD, dptr, "-octal-");
|
sim_debug(DEBUG_CARD, dptr, "-octal-");
|
||||||
for(col = 0, i = 4; col < 80; i++) {
|
for(col = 0, i = 4; col < 80 && i < buf->len; i++) {
|
||||||
if (data->cbuff[i] >= '0' && data->cbuff[i] <= '7') {
|
if (buf->buffer[i] >= '0' && buf->buffer[i] <= '7') {
|
||||||
data->image[col] = (data->image[col] << 3) |
|
(*image)[col] = ((*image)[col] << 3) | (buf->buffer[i] - '0');
|
||||||
(data->cbuff[i] - '0');
|
|
||||||
j++;
|
j++;
|
||||||
} else if (data->cbuff[i] == '\n' ||
|
} else if (buf->buffer[i] == '\n' || buf->buffer[i] == '\r') {
|
||||||
data->cbuff[i] == '\r') {
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
r = SCPE_IOERR;
|
(*image)[0] = CARD_ERR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j == 4) {
|
if (j == 4) {
|
||||||
|
@ -629,22 +717,22 @@ sim_read_card(UNIT * uptr)
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (cmpcard(&data->cbuff[0], "eor")) {
|
} else if (_cmpcard(&buf->buffer[0], "eor")) {
|
||||||
sim_debug(DEBUG_CARD, dptr, "-eor-");
|
sim_debug(DEBUG_CARD, dptr, "-eor-");
|
||||||
data->image[0] = 07; /* 7/8/9 punch */
|
(*image)[0] = 07; /* 7/8/9 punch */
|
||||||
i = 4;
|
i = 4;
|
||||||
} else if (cmpcard(&data->cbuff[0], "eof")) {
|
} else if (_cmpcard(&buf->buffer[0], "eof")) {
|
||||||
sim_debug(DEBUG_CARD, dptr, "-eof-");
|
sim_debug(DEBUG_CARD, dptr, "-eof-");
|
||||||
data->image[0] = 015; /* 6/7/9 punch */
|
(*image)[0] = 015; /* 6/7/9 punch */
|
||||||
i = 4;
|
i = 4;
|
||||||
} else if (cmpcard(&data->cbuff[0], "eoi")) {
|
} else if (_cmpcard(&buf->buffer[0], "eoi")) {
|
||||||
sim_debug(DEBUG_CARD, dptr, "-eoi-");
|
sim_debug(DEBUG_CARD, dptr, "-eoi-");
|
||||||
data->image[0] = 017; /* 6/7/8/9 punch */
|
(*image)[0] = 017; /* 6/7/8/9 punch */
|
||||||
i = 4;
|
i = 4;
|
||||||
} else {
|
} else {
|
||||||
/* Convert text line into card image */
|
/* Convert text line into card image */
|
||||||
for (col = 0, i = 0; col < 80 && i < size; i++) {
|
for (col = 0, i = 0; col < 80 && i < buf->len; i++) {
|
||||||
c = data->cbuff[i];
|
c = buf->buffer[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\0':
|
case '\0':
|
||||||
case '\r':
|
case '\r':
|
||||||
|
@ -673,8 +761,8 @@ sim_read_card(UNIT * uptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (temp & 0xf000)
|
if (temp & 0xf000)
|
||||||
r = SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
data->image[col++] = temp & 0xfff;
|
(*image)[col++] = temp & 0xfff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,12 +770,12 @@ sim_read_card(UNIT * uptr)
|
||||||
sim_debug(DEBUG_CARD, dptr, "-%d-", i);
|
sim_debug(DEBUG_CARD, dptr, "-%d-", i);
|
||||||
|
|
||||||
/* Scan to end of line, ignore anything after last column */
|
/* Scan to end of line, ignore anything after last column */
|
||||||
while (data->cbuff[i] != '\n' && data->cbuff[i] != '\r' && i < data->len) {
|
while (buf->buffer[i] != '\n' && buf->buffer[i] != '\r' && i < buf->len) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (data->cbuff[i] == '\r')
|
if (buf->buffer[i] == '\r')
|
||||||
i++;
|
i++;
|
||||||
if (data->cbuff[i] == '\n')
|
if (buf->buffer[i] == '\n')
|
||||||
i++;
|
i++;
|
||||||
sim_debug(DEBUG_CARD, dptr, "]\n");
|
sim_debug(DEBUG_CARD, dptr, "]\n");
|
||||||
break;
|
break;
|
||||||
|
@ -695,57 +783,59 @@ sim_read_card(UNIT * uptr)
|
||||||
case MODE_BIN:
|
case MODE_BIN:
|
||||||
temp = 0;
|
temp = 0;
|
||||||
sim_debug(DEBUG_CARD, dptr, "bin\n");
|
sim_debug(DEBUG_CARD, dptr, "bin\n");
|
||||||
if (size < 160)
|
if (buf->len < 160) {
|
||||||
return SCPE_IOERR;
|
(*image)[0] = CARD_ERR;
|
||||||
|
return SCPE_OPENERR;
|
||||||
|
}
|
||||||
/* Move data to buffer */
|
/* Move data to buffer */
|
||||||
for (col = i = 0; i < 160;) {
|
for (col = i = 0; i < 160;) {
|
||||||
temp |= data->cbuff[i];
|
temp |= buf->buffer[i];
|
||||||
data->image[col] = (data->cbuff[i++] >> 4) & 0xF;
|
(*image)[col] = (buf->buffer[i++] >> 4) & 0xF;
|
||||||
data->image[col++] |= ((uint16)data->cbuff[i++]) << 4;
|
(*image)[col++] |= ((uint16)buf->buffer[i++]) << 4;
|
||||||
}
|
}
|
||||||
/* Check if format error */
|
/* Check if format error */
|
||||||
if (temp & 0xF)
|
if (temp & 0xF)
|
||||||
r = SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MODE_CBN:
|
case MODE_CBN:
|
||||||
sim_debug(DEBUG_CARD, dptr, "cbn\n");
|
sim_debug(DEBUG_CARD, dptr, "cbn\n");
|
||||||
/* Check if first character is a tape mark */
|
/* Check if first character is a tape mark */
|
||||||
if (((uint8)data->cbuff[0]) == 0217 &&
|
if (((uint8)buf->buffer[0]) == 0217 &&
|
||||||
(size == 1 || (((uint8)data->cbuff[1]) & 0200) != 0)) {
|
(buf->len == 1 || (((uint8)buf->buffer[1]) & 0200) != 0)) {
|
||||||
i = 1;
|
i = 1;
|
||||||
r = SCPE_EOF;
|
(*image)[0] |= CARD_EOF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear record mark */
|
/* Clear record mark */
|
||||||
data->cbuff[0] &= 0x7f;
|
buf->buffer[0] &= 0x7f;
|
||||||
|
|
||||||
/* Convert card and check for errors */
|
/* Convert card and check for errors */
|
||||||
for (col = i = 0; i < data->len && col < 80;) {
|
for (col = i = 0; i < buf->len && col < 80;) {
|
||||||
uint8 c;
|
uint8 c;
|
||||||
|
|
||||||
if (data->cbuff[i] & 0x80)
|
if (buf->buffer[i] & 0x80)
|
||||||
break;
|
break;
|
||||||
c = data->cbuff[i] & 077;
|
c = buf->buffer[i] & 077;
|
||||||
if (sim_parity_table[(int)c] == (data->cbuff[i++] & 0100))
|
if (sim_parity_table[(int)c] == (buf->buffer[i++] & 0100))
|
||||||
r = SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
data->image[col] = ((uint16)c) << 6;
|
(*image)[col] = ((uint16)c) << 6;
|
||||||
if (data->cbuff[i] & 0x80)
|
if (buf->buffer[i] & 0x80)
|
||||||
break;
|
break;
|
||||||
c = data->cbuff[i] & 077;
|
c = buf->buffer[i] & 077;
|
||||||
if (sim_parity_table[(int)c] == (data->cbuff[i++] & 0100))
|
if (sim_parity_table[(int)c] == (buf->buffer[i++] & 0100))
|
||||||
r = SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
data->image[col++] |= c;
|
(*image)[col++] |= c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < data->len && col >= 80 && (data->cbuff[i] & 0x80) == 0) {
|
if (i < buf->len && col >= 80 && (buf->buffer[i] & 0x80) == 0) {
|
||||||
r = SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
}
|
}
|
||||||
/* Record over length of card, skip until next */
|
/* Record over length of card, skip until next */
|
||||||
while ((data->cbuff[i] & 0x80) == 0) {
|
while ((buf->buffer[i] & 0x80) == 0) {
|
||||||
if (i > data->len)
|
if (i > buf->len)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -754,35 +844,34 @@ sim_read_card(UNIT * uptr)
|
||||||
case MODE_BCD:
|
case MODE_BCD:
|
||||||
sim_debug(DEBUG_CARD, dptr, "bcd [");
|
sim_debug(DEBUG_CARD, dptr, "bcd [");
|
||||||
/* Check if first character is a tape mark */
|
/* Check if first character is a tape mark */
|
||||||
if (((uint8)data->cbuff[0]) == 0217 &&
|
if (((uint8)buf->buffer[0]) == 0217 && (((uint8)buf->buffer[1]) & 0200) != 0) {
|
||||||
(size == 1 || (((uint8)data->cbuff[1]) & 0200) != 0)) {
|
|
||||||
i = 1;
|
i = 1;
|
||||||
r = SCPE_EOF;
|
(*image)[0] |= CARD_EOF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear record mark */
|
/* Clear record mark */
|
||||||
data->cbuff[0] &= 0x7f;
|
buf->buffer[0] &= 0x7f;
|
||||||
|
|
||||||
/* Convert text line into card image */
|
/* Convert text line into card image */
|
||||||
for (col = 0, i = 0; col < 80 && i < data->len; i++) {
|
for (col = 0, i = 0; col < 80 && i < buf->len; i++) {
|
||||||
if (data->cbuff[i] & 0x80)
|
if (buf->buffer[i] & 0x80)
|
||||||
break;
|
break;
|
||||||
c = data->cbuff[i] & 077;
|
c = buf->buffer[i] & 077;
|
||||||
if (sim_parity_table[(int)c] != (data->cbuff[i] & 0100))
|
if (sim_parity_table[(int)c] != (buf->buffer[i] & 0100))
|
||||||
r = SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
sim_debug(DEBUG_CARD, dptr, "%c", sim_six_to_ascii[(int)c]);
|
sim_debug(DEBUG_CARD, dptr, "%c", sim_six_to_ascii[(int)c]);
|
||||||
/* Convert to top column */
|
/* Convert to top column */
|
||||||
data->image[col++] = sim_bcd_to_hol(c);
|
(*image)[col++] = sim_bcd_to_hol(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < data->len && col >= 80 && (data->cbuff[i] & 0x80) == 0) {
|
if (i < buf->len && col >= 80 && (buf->buffer[i] & 0x80) == 0) {
|
||||||
r = SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record over length of card, skip until next */
|
/* Record over length of card, skip until next */
|
||||||
while ((data->cbuff[i] & 0x80) == 0) {
|
while ((buf->buffer[i] & 0x80) == 0) {
|
||||||
if (i > data->len)
|
if (i > buf->len)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -792,44 +881,98 @@ sim_read_card(UNIT * uptr)
|
||||||
|
|
||||||
case MODE_EBCDIC:
|
case MODE_EBCDIC:
|
||||||
sim_debug(DEBUG_CARD, dptr, "ebcdic\n");
|
sim_debug(DEBUG_CARD, dptr, "ebcdic\n");
|
||||||
if (size < 80)
|
if (buf->len < 80)
|
||||||
return SCPE_IOERR;
|
(*image)[0] |= CARD_ERR;
|
||||||
/* Move data to buffer */
|
/* Move data to buffer */
|
||||||
for (i = 0; i < 80; i++) {
|
for (i = 0; i < 80 && i < buf->len; i++) {
|
||||||
temp = data->cbuff[i];
|
temp = buf->buffer[i] & 0xFF;
|
||||||
data->image[i] = ebcdic_to_hol[temp];
|
(*image)[i] = ebcdic_to_hol[temp];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (i < size)
|
buf->size = i;
|
||||||
data->ptr = i;
|
return SCPE_OK;
|
||||||
else
|
|
||||||
data->ptr = 0;
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if reader is at last card.
|
t_stat
|
||||||
*
|
_sim_read_deck(UNIT * uptr, int eof)
|
||||||
*/
|
|
||||||
int
|
|
||||||
sim_card_eof(UNIT *uptr)
|
|
||||||
{
|
{
|
||||||
struct _card_data *data;
|
struct _card_buffer buf;
|
||||||
|
struct card_context *data;
|
||||||
|
DEVICE *dptr;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int l;
|
||||||
|
int cards = 0;
|
||||||
|
t_stat r = SCPE_OK;
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_ATT) == 0)
|
if ((uptr->flags & UNIT_ATT) == 0)
|
||||||
return 1; /* attached? */
|
return SCPE_UNATT; /* attached? */
|
||||||
|
|
||||||
data = (struct _card_data *)uptr->up7;
|
dptr = find_dev_from_unit( uptr);
|
||||||
|
data = (struct card_context *)uptr->card_ctx;
|
||||||
|
|
||||||
if (data->ptr > 0) {
|
buf.len = 0;
|
||||||
if ((data->ptr - data->len) == 0 && feof(uptr->fileref))
|
buf.size = 0;
|
||||||
return 1;
|
buf.buffer[0] = 0; /* Initialize bufer to empty */
|
||||||
} else {
|
|
||||||
if (feof(uptr->fileref))
|
/* Slurp up current file */
|
||||||
return 1;
|
do {
|
||||||
|
if (buf.len < 500 && !feof(uptr->fileref)) {
|
||||||
|
l = sim_fread(&buf.buffer[buf.len], 1, 8192, uptr->fileref);
|
||||||
|
if (l < 0)
|
||||||
|
r = SCPE_OPENERR;
|
||||||
|
else
|
||||||
|
buf.len += l;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
/* Allocate space for some more cards if needed */
|
||||||
|
if (data->hopper_cards >= data->hopper_size) {
|
||||||
|
data->hopper_size += DECK_SIZE;
|
||||||
|
data->images = (uint16 (*)[1][80])realloc(data->images,
|
||||||
|
data->hopper_size * sizeof(*(data->images)));
|
||||||
|
memset(&data->images[data->hopper_cards], 0,
|
||||||
|
(data->hopper_size - data->hopper_cards) *
|
||||||
|
sizeof(*(data->images)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process one card */
|
||||||
|
cards++;
|
||||||
|
if (_sim_parse_card(uptr, dptr, &buf, &(*data->images)[data->hopper_cards])
|
||||||
|
!= SCPE_OK) {
|
||||||
|
r = sim_messagef(SCPE_OPENERR, "%s: %s Error (%s) in card %d\n",
|
||||||
|
sim_uname(uptr), uptr->filename, sim_error_text(r), cards);
|
||||||
|
}
|
||||||
|
data->hopper_cards++;
|
||||||
|
/* Move data to start at begining of buffer */
|
||||||
|
/* Data is moved down to simplify the decoding of one card */
|
||||||
|
l = buf.len - buf.size;
|
||||||
|
j = buf.size;
|
||||||
|
for(i = 0; i < l; i++, j++)
|
||||||
|
buf.buffer[i] = buf.buffer[j];
|
||||||
|
buf.len -= buf.size;
|
||||||
|
} while (buf.len > 0 && r == SCPE_OK);
|
||||||
|
|
||||||
|
/* If there is an error, free just read deck */
|
||||||
|
if (r == SCPE_OK) {
|
||||||
|
if (eof) {
|
||||||
|
/* Allocate space for some more cards if needed */
|
||||||
|
if (data->hopper_cards >= data->hopper_size) {
|
||||||
|
data->hopper_size += DECK_SIZE;
|
||||||
|
data->images = (uint16 (*)[1][80])realloc(data->images,
|
||||||
|
data->hopper_size * sizeof(*(data->images)));
|
||||||
|
memset(&data->images[data->hopper_cards], 0,
|
||||||
|
(data->hopper_size - data->hopper_cards) *
|
||||||
|
sizeof(*(data->images)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create empty card */
|
||||||
|
(*data->images)[data->hopper_cards][0] = CARD_EOF;
|
||||||
|
data->hopper_cards++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -839,8 +982,9 @@ sim_card_eof(UNIT *uptr)
|
||||||
C modifier is recognized (column binary is implemented)
|
C modifier is recognized (column binary is implemented)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
t_stat
|
t_stat
|
||||||
sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
sim_punch_card(UNIT * uptr, uint16 image[80])
|
||||||
{
|
{
|
||||||
/* Convert word record into column image */
|
/* Convert word record into column image */
|
||||||
/* Check output type, if auto or text, try and convert record to bcd first */
|
/* Check output type, if auto or text, try and convert record to bcd first */
|
||||||
|
@ -850,31 +994,23 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
/* Try to convert to text */
|
/* Try to convert to text */
|
||||||
uint8 out[512];
|
uint8 out[512];
|
||||||
int i;
|
int i;
|
||||||
int outp;
|
int outp = 0;
|
||||||
FILE *fo = uptr->fileref;
|
|
||||||
int mode = uptr->flags & UNIT_CARD_MODE;
|
int mode = uptr->flags & UNIT_CARD_MODE;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
struct _card_data *data;
|
struct card_context *data;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
|
||||||
if (stkuptr != NULL && stkuptr->flags & UNIT_ATT) {
|
|
||||||
fo = stkuptr->fileref;
|
|
||||||
if ((stkuptr->flags & UNIT_CARD_MODE) != MODE_AUTO)
|
|
||||||
mode = stkuptr->flags & UNIT_CARD_MODE;
|
|
||||||
} else
|
|
||||||
return SCPE_UNATT; /* attached? */
|
|
||||||
}
|
|
||||||
|
|
||||||
data = (struct _card_data *)uptr->up7;
|
|
||||||
dptr = find_dev_from_unit(uptr);
|
dptr = find_dev_from_unit(uptr);
|
||||||
outp = 0;
|
data = (struct card_context *)uptr->card_ctx;
|
||||||
|
|
||||||
|
if (data == NULL || (uptr->flags & UNIT_ATT) == 0)
|
||||||
|
return CDSE_EMPTY; /* attached? */
|
||||||
|
|
||||||
/* Fix mode if in auto mode */
|
/* Fix mode if in auto mode */
|
||||||
if (mode == MODE_AUTO) {
|
if (mode == MODE_AUTO) {
|
||||||
/* Try to convert each column to ascii */
|
/* Try to convert each column to ascii */
|
||||||
for (i = 0; i < 80; i++) {
|
for (i = 0; i < 80; i++) {
|
||||||
out[i] = data->hol_to_ascii[data->image[i]];
|
out[i] = data->hol_to_ascii[image[i]];
|
||||||
if (out[i] == 0xff) {
|
if (out[i] == 0xff) {
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
|
@ -888,7 +1024,7 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
/* Scan each column */
|
/* Scan each column */
|
||||||
sim_debug(DEBUG_CARD, dptr, "text: [");
|
sim_debug(DEBUG_CARD, dptr, "text: [");
|
||||||
for (i = 0; i < 80; i++, outp++) {
|
for (i = 0; i < 80; i++, outp++) {
|
||||||
out[outp] = data->hol_to_ascii[data->image[i]];
|
out[outp] = data->hol_to_ascii[image[i]];
|
||||||
if (out[outp] == 0xff) {
|
if (out[outp] == 0xff) {
|
||||||
out[outp] = '?';
|
out[outp] = '?';
|
||||||
}
|
}
|
||||||
|
@ -905,26 +1041,26 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
sim_debug(DEBUG_CARD, dptr, "octal: [");
|
sim_debug(DEBUG_CARD, dptr, "octal: [");
|
||||||
out[outp++] = '~';
|
out[outp++] = '~';
|
||||||
for (i = 79; i >= 0; i--) {
|
for (i = 79; i >= 0; i--) {
|
||||||
if (data->image[i] != 0)
|
if (image[i] != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Check if special card */
|
/* Check if special card */
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
out[outp++] = 'e';
|
out[outp++] = 'e';
|
||||||
out[outp++] = 'o';
|
out[outp++] = 'o';
|
||||||
if (data->image[0] == 07) {
|
if (image[0] == 07) {
|
||||||
out[outp++] = 'r';
|
out[outp++] = 'r';
|
||||||
out[outp++] = '\n';
|
out[outp++] = '\n';
|
||||||
sim_debug(DEBUG_CARD, dptr, "eor\n");
|
sim_debug(DEBUG_CARD, dptr, "eor\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (data->image[0] == 015) {
|
if (image[0] == 015) {
|
||||||
out[outp++] = 'f';
|
out[outp++] = 'f';
|
||||||
out[outp++] = '\n';
|
out[outp++] = '\n';
|
||||||
sim_debug(DEBUG_CARD, dptr, "eof\n");
|
sim_debug(DEBUG_CARD, dptr, "eof\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (data->image[0] == 017) {
|
if (image[0] == 017) {
|
||||||
out[outp++] = 'f';
|
out[outp++] = 'f';
|
||||||
out[outp++] = '\n';
|
out[outp++] = '\n';
|
||||||
sim_debug(DEBUG_CARD, dptr, "eoi\n");
|
sim_debug(DEBUG_CARD, dptr, "eoi\n");
|
||||||
|
@ -935,7 +1071,7 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
out[outp++] = 'a';
|
out[outp++] = 'a';
|
||||||
out[outp++] = 'w';
|
out[outp++] = 'w';
|
||||||
for (i = 0; i < 80; i++) {
|
for (i = 0; i < 80; i++) {
|
||||||
uint16 col = data->image[i];
|
uint16 col = image[i];
|
||||||
out[outp++] = ((col >> 9) & 07) + '0';
|
out[outp++] = ((col >> 9) & 07) + '0';
|
||||||
out[outp++] = ((col >> 6) & 07) + '0';
|
out[outp++] = ((col >> 6) & 07) + '0';
|
||||||
out[outp++] = ((col >> 3) & 07) + '0';
|
out[outp++] = ((col >> 3) & 07) + '0';
|
||||||
|
@ -949,7 +1085,7 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
case MODE_BIN:
|
case MODE_BIN:
|
||||||
sim_debug(DEBUG_CARD, dptr, "bin\n");
|
sim_debug(DEBUG_CARD, dptr, "bin\n");
|
||||||
for (i = 0; i < 80; i++) {
|
for (i = 0; i < 80; i++) {
|
||||||
uint16 col = data->image[i];
|
uint16 col = image[i];
|
||||||
out[outp++] = (col & 0x00f) << 4;
|
out[outp++] = (col & 0x00f) << 4;
|
||||||
out[outp++] = (col & 0xff0) >> 4;
|
out[outp++] = (col & 0xff0) >> 4;
|
||||||
}
|
}
|
||||||
|
@ -959,7 +1095,7 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
sim_debug(DEBUG_CARD, dptr, "cbn\n");
|
sim_debug(DEBUG_CARD, dptr, "cbn\n");
|
||||||
/* Fill buffer */
|
/* Fill buffer */
|
||||||
for (i = 0; i < 80; i++) {
|
for (i = 0; i < 80; i++) {
|
||||||
uint16 col = data->image[i];
|
uint16 col = image[i];
|
||||||
out[outp++] = (col >> 6) & 077;
|
out[outp++] = (col >> 6) & 077;
|
||||||
out[outp++] = col & 077;
|
out[outp++] = col & 077;
|
||||||
}
|
}
|
||||||
|
@ -972,7 +1108,7 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
case MODE_BCD:
|
case MODE_BCD:
|
||||||
sim_debug(DEBUG_CARD, dptr, "bcd [");
|
sim_debug(DEBUG_CARD, dptr, "bcd [");
|
||||||
for (i = 0; i < 80; i++, outp++) {
|
for (i = 0; i < 80; i++, outp++) {
|
||||||
out[outp] = sim_hol_to_bcd(data->image[i]);
|
out[outp] = sim_hol_to_bcd(image[i]);
|
||||||
if (out[outp] != 0x7f)
|
if (out[outp] != 0x7f)
|
||||||
out[outp] |= sim_parity_table[(int)out[outp]];
|
out[outp] |= sim_parity_table[(int)out[outp]];
|
||||||
else
|
else
|
||||||
|
@ -990,14 +1126,17 @@ sim_punch_card(UNIT * uptr, UNIT *stkuptr)
|
||||||
sim_debug(DEBUG_CARD, dptr, "ebcdic\n");
|
sim_debug(DEBUG_CARD, dptr, "ebcdic\n");
|
||||||
/* Fill buffer */
|
/* Fill buffer */
|
||||||
for (i = 0; i < 80; i++, outp++) {
|
for (i = 0; i < 80; i++, outp++) {
|
||||||
uint16 col = data->image[i];
|
uint16 col = image[i];
|
||||||
out[outp] = 0xff & hol_to_ebcdic[col];
|
out[outp] = 0xff & hol_to_ebcdic[col];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sim_fwrite(out, 1, outp, fo);
|
data->punch_count++;
|
||||||
memset(&data->image[0], 0, sizeof(data->image));
|
sim_fwrite(out, 1, outp, uptr->fileref);
|
||||||
return SCPE_OK;
|
uptr->pos = ftell (uptr->fileref);
|
||||||
|
/* Clear image buffer */
|
||||||
|
for (i = 0; i < 80; image[i++] = 0);
|
||||||
|
return CDSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set card format */
|
/* Set card format */
|
||||||
|
@ -1036,11 +1175,40 @@ t_stat sim_card_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||||
t_stat
|
t_stat
|
||||||
sim_card_attach(UNIT * uptr, CONST char *cptr)
|
sim_card_attach(UNIT * uptr, CONST char *cptr)
|
||||||
{
|
{
|
||||||
t_stat r;
|
t_stat r = SCPE_OK;
|
||||||
struct _card_data *data;
|
int eof = 0;
|
||||||
|
struct card_context *data;
|
||||||
char gbuf[30];
|
char gbuf[30];
|
||||||
int i;
|
int i;
|
||||||
|
char *saved_filename;
|
||||||
|
t_bool was_attached = (uptr->flags & UNIT_ATT);
|
||||||
|
t_addr saved_pos;
|
||||||
|
static int ebcdic_init = 0;
|
||||||
|
|
||||||
|
if ((uptr->flags & UNIT_RO) && /* Attaching a Reader */
|
||||||
|
strchr (cptr, ',')) { /* Restoring Attach list of files? */
|
||||||
|
char tbuf[10*CBUFSIZE];
|
||||||
|
char *tptr = tbuf;
|
||||||
|
int32 saved_switches = sim_switches;
|
||||||
|
|
||||||
|
strlcpy (tbuf, cptr, sizeof(tbuf));
|
||||||
|
tptr = strtok (tptr, ",");
|
||||||
|
while (tptr) {
|
||||||
|
cptr = tptr;
|
||||||
|
while (isspace(*cptr))
|
||||||
|
++cptr;
|
||||||
|
r = sim_card_attach (uptr, cptr);
|
||||||
|
if (r != SCPE_OK)
|
||||||
|
return r;
|
||||||
|
tptr = strtok (NULL, ",");
|
||||||
|
sim_switches = saved_switches & ~SWMASK('F');
|
||||||
|
sim_switches |= SWMASK('S');
|
||||||
|
}
|
||||||
|
sim_switches = saved_switches;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
cptr = get_sim_sw (cptr); /* Pickup optional format specifier during RESTORE */
|
||||||
if (sim_switches & SWMASK ('F')) { /* format spec? */
|
if (sim_switches & SWMASK ('F')) { /* format spec? */
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get spec */
|
cptr = get_glyph (cptr, gbuf, 0); /* get spec */
|
||||||
if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
||||||
|
@ -1048,20 +1216,31 @@ sim_card_attach(UNIT * uptr, CONST char *cptr)
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = attach_unit(uptr, cptr)) != SCPE_OK)
|
if (sim_switches & SWMASK ('E'))
|
||||||
|
eof = 1;
|
||||||
|
|
||||||
|
saved_filename = uptr->filename;
|
||||||
|
uptr->filename = NULL;
|
||||||
|
saved_pos = uptr->pos;
|
||||||
|
if ((r = attach_unit(uptr, cptr)) != SCPE_OK) {
|
||||||
|
uptr->filename = saved_filename;
|
||||||
|
uptr->pos = saved_pos;
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initialize reverse mapping if not initialized */
|
/* Initialize reverse mapping if not initialized */
|
||||||
/* Set all to invalid */
|
/* Set all to invalid */
|
||||||
/* Allocate a buffer if one does not exist */
|
/* Allocate a buffer if one does not exist */
|
||||||
if (uptr->up7 == 0) {
|
if (uptr->card_ctx == 0) {
|
||||||
uptr->up7 = malloc(sizeof(struct _card_data));
|
uptr->card_ctx = malloc(sizeof(struct card_context));
|
||||||
data = (struct _card_data *)uptr->up7;
|
data = (struct card_context *)uptr->card_ctx;
|
||||||
|
memset(data, 0, sizeof(struct card_context));
|
||||||
} else {
|
} else {
|
||||||
data = (struct _card_data *)uptr->up7;
|
data = (struct card_context *)uptr->card_ctx;
|
||||||
}
|
}
|
||||||
memset(data, 0, sizeof(struct _card_data));
|
|
||||||
|
|
||||||
|
if (!ebcdic_init) {
|
||||||
for (i = 0; i < 4096; i++)
|
for (i = 0; i < 4096; i++)
|
||||||
hol_to_ebcdic[i] = 0x100;
|
hol_to_ebcdic[i] = 0x100;
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
|
@ -1073,6 +1252,8 @@ sim_card_attach(UNIT * uptr, CONST char *cptr)
|
||||||
hol_to_ebcdic[temp] = i;
|
hol_to_ebcdic[temp] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ebcdic_init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
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++) {
|
||||||
|
@ -1092,25 +1273,87 @@ sim_card_attach(UNIT * uptr, CONST char *cptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data->ptr = 0; /* Set for initial read */
|
if (uptr->flags & UNIT_RO) { /* Card Reader? */
|
||||||
data->len = 0;
|
t_addr previous_cards = data->hopper_cards;
|
||||||
return SCPE_OK;
|
|
||||||
|
/* Check if we should append to end of existing */
|
||||||
|
if ((sim_switches & SWMASK ('S')) == 0) {
|
||||||
|
previous_cards = 0;
|
||||||
|
data->hopper_cards = 0;
|
||||||
|
data->hopper_size = 0;
|
||||||
|
data->punch_count = 0;
|
||||||
|
free(data->images);
|
||||||
|
data->images = NULL;
|
||||||
|
free(saved_filename);
|
||||||
|
saved_filename = NULL;
|
||||||
|
saved_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go read the deck */
|
||||||
|
r = _sim_read_deck(uptr, eof);
|
||||||
|
uptr->pos = saved_pos;
|
||||||
|
detach_unit(uptr);
|
||||||
|
if (was_attached) {
|
||||||
|
uptr->flags |= UNIT_ATT;
|
||||||
|
uptr->filename = saved_filename;
|
||||||
|
}
|
||||||
|
if (r == SCPE_OK) {
|
||||||
|
const char *fmt = "AUTO";
|
||||||
|
int mode = uptr->flags & UNIT_CARD_MODE;
|
||||||
|
for (i = 0; fmts[i].name != 0; i++) {
|
||||||
|
if (fmts[i].mode == mode) {
|
||||||
|
fmt = fmts[i].name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uptr->flags |= UNIT_ATT;
|
||||||
|
uptr->dynflags |= UNIT_ATTMULT;
|
||||||
|
if (saved_filename) {
|
||||||
|
uptr->filename = (char *)malloc (32 + strlen (cptr) + strlen (saved_filename));
|
||||||
|
sprintf (uptr->filename, "%s, %s-F %s %s", saved_filename,
|
||||||
|
(eof)? "-E ": "", fmt, cptr);
|
||||||
|
free(saved_filename);
|
||||||
|
} else {
|
||||||
|
uptr->filename = (char *)malloc (32 + strlen (cptr));
|
||||||
|
sprintf (uptr->filename, "%s-F %s %s", (eof)?"-E ": "", fmt, cptr);
|
||||||
|
}
|
||||||
|
r = sim_messagef(SCPE_OK, "%s: %d card Deck Loaded from %s\n",
|
||||||
|
sim_uname(uptr), data->hopper_cards - previous_cards, cptr);
|
||||||
|
} else {
|
||||||
|
if (uptr->dynflags & UNIT_ATTMULT)
|
||||||
|
uptr->flags |= UNIT_ATT;
|
||||||
|
detach_unit(uptr);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat
|
t_stat
|
||||||
sim_card_detach(UNIT * uptr)
|
sim_card_detach(UNIT * uptr)
|
||||||
{
|
{
|
||||||
/* Free buffer if one allocated */
|
/* Free buffer if one allocated */
|
||||||
if (uptr->up7 != 0) {
|
if (uptr->card_ctx != 0) {
|
||||||
free((void *)uptr->up7);
|
struct card_context * data = (struct card_context *)uptr->card_ctx;
|
||||||
uptr->up7 = 0;
|
/* No clear any existing decks on stack */
|
||||||
|
free(data->images);
|
||||||
|
free(uptr->card_ctx);
|
||||||
|
uptr->card_ctx = 0;
|
||||||
|
}
|
||||||
|
if (uptr->flags & UNIT_RO) { /* Card Reader? */
|
||||||
|
free(uptr->filename);
|
||||||
|
uptr->filename = NULL;
|
||||||
|
uptr->flags &= ~UNIT_ATT;
|
||||||
|
uptr->dynflags &= ~UNIT_ATTMULT;
|
||||||
|
return SCPE_OK; /* Already detached */
|
||||||
}
|
}
|
||||||
return detach_unit(uptr);
|
return detach_unit(uptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat sim_card_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
t_stat sim_card_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||||
{
|
{
|
||||||
fprintf (st, "%s Card Attach Help\n\n", dptr->name);
|
fprintf (st, "%s Card %sAttach Help\n\n", dptr->name, (uptr->flags & UNIT_RO) ? "Reader " : "Punch ");
|
||||||
if (0 == (uptr-dptr->units)) {
|
if (0 == (uptr-dptr->units)) {
|
||||||
if (dptr->numunits > 1) {
|
if (dptr->numunits > 1) {
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
@ -1130,8 +1373,18 @@ t_stat sim_card_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, cons
|
||||||
if ((uptr->flags & UNIT_RO) == 0) {
|
if ((uptr->flags & UNIT_RO) == 0) {
|
||||||
fprintf (st, " -N Create a new punch output file (default is to append to\n");
|
fprintf (st, " -N Create a new punch output file (default is to append to\n");
|
||||||
fprintf (st, " an existing file if it exists)\n");
|
fprintf (st, " an existing file if it exists)\n");
|
||||||
|
} else {
|
||||||
|
fprintf (st, " -E Return EOF after deck read\n");
|
||||||
|
fprintf (st, " -S Append deck to cards currently waiting to be read\n");
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
t_stat sim_card_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||||
|
{
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* USE_SIM_CARD */
|
#endif /* USE_SIM_CARD */
|
||||||
|
|
39
sim_card.h
39
sim_card.h
|
@ -66,6 +66,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SIM_CARD_API 2 /* API Version */
|
||||||
|
|
||||||
#define DEBUG_CARD 0x0000010 /* Show details */
|
#define DEBUG_CARD 0x0000010 /* Show details */
|
||||||
|
|
||||||
/* Flags for punch and reader. */
|
/* Flags for punch and reader. */
|
||||||
|
@ -82,22 +84,31 @@ extern "C" {
|
||||||
#define MODE_LOWER (8 << UNIT_V_CARD_MODE)
|
#define MODE_LOWER (8 << UNIT_V_CARD_MODE)
|
||||||
#define MODE_026 (0x10 << UNIT_V_CARD_MODE)
|
#define MODE_026 (0x10 << UNIT_V_CARD_MODE)
|
||||||
#define MODE_029 (0x20 << UNIT_V_CARD_MODE)
|
#define MODE_029 (0x20 << UNIT_V_CARD_MODE)
|
||||||
#define MODE_CHAR (0x30 << UNIT_V_CARD_MODE)
|
#define MODE_CHAR (0x70 << UNIT_V_CARD_MODE)
|
||||||
|
|
||||||
|
|
||||||
struct _card_data
|
/* Card Reader Return Status code */
|
||||||
{
|
typedef int t_cdstat;
|
||||||
int ptr; /* Pointer in buffer */
|
#define CDSE_OK 0 /* Good */
|
||||||
int len; /* Length of buffer */
|
#define CDSE_EOF 1 /* End of File */
|
||||||
char cbuff[1024]; /* Read in buffer for cards */
|
#define CDSE_EMPTY 2 /* Input Hopper Empty */
|
||||||
uint16 image[80]; /* Image */
|
#define CDSE_ERROR 3 /* Error Card Read */
|
||||||
uint8 hol_to_ascii[4096]; /* Back conversion table */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Generic routines. */
|
/* Generic routines. */
|
||||||
t_stat sim_read_card(UNIT * uptr);
|
|
||||||
|
/* Read next card into image row 12,11,10,1-9 */
|
||||||
|
/* Return SCPE_EOF if end file detected. */
|
||||||
|
t_cdstat sim_read_card(UNIT * uptr, uint16 image[80]);
|
||||||
|
/* Punch card from image row 12,11,10,1-9 */
|
||||||
|
t_cdstat sim_punch_card(UNIT * uptr, uint16 image[80]);
|
||||||
|
/* Check if next card to be read is EOF */
|
||||||
int sim_card_eof(UNIT * uptr);
|
int sim_card_eof(UNIT * uptr);
|
||||||
t_stat sim_punch_card(UNIT * uptr, UNIT *stkptr);
|
/* Return number of cards yet to read */
|
||||||
|
t_addr sim_hopper_size(UNIT * uptr);
|
||||||
|
/* Return number of cards punched */
|
||||||
|
t_addr sim_punch_count(UNIT * uptr);
|
||||||
|
t_addr sim_card_input_hopper_count(UNIT *uptr);
|
||||||
|
t_addr sim_card_output_hopper_count(UNIT *uptr);
|
||||||
t_stat sim_card_attach(UNIT * uptr, CONST char *file);
|
t_stat sim_card_attach(UNIT * uptr, CONST char *file);
|
||||||
t_stat sim_card_detach(UNIT *uptr);
|
t_stat sim_card_detach(UNIT *uptr);
|
||||||
|
|
||||||
|
@ -115,9 +126,9 @@ t_stat sim_card_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||||
t_stat sim_card_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
t_stat sim_card_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||||
|
|
||||||
/* Translation tables */
|
/* Translation tables */
|
||||||
extern const char sim_six_to_ascii[64];
|
extern CONST char sim_six_to_ascii[64]; /* Map BCD to ASCII */
|
||||||
extern const char sim_ascii_to_six[128];
|
extern CONST char sim_ascii_to_six[128]; /* Map 7 bit ASCII to BCD */
|
||||||
extern const uint8 sim_parity_table[64];
|
extern CONST uint8 sim_parity_table[64]; /* 64 entry odd parity table */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue