1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-27 00:59:57 +00:00

ICL1900: Fixed Divide, added LP and MT device drivers.

This commit is contained in:
Richard Cornwell
2018-09-05 23:32:28 -04:00
parent e97284d814
commit 57b0fa50ff
11 changed files with 2009 additions and 1058 deletions

View File

@@ -34,14 +34,11 @@
#include "sim_timer.h"
#define UNIT_V_MSIZE (UNIT_V_UF + 0)
#define UNIT_MSIZE (7 << UNIT_V_MSIZE)
#define UNIT_MSIZE (0x1ff << UNIT_V_MSIZE)
#define MEMAMOUNT(x) (x << UNIT_V_MSIZE)
#define UNIT_V_MODEL (UNIT_V_MSIZE + 4)
#define UNIT_V_MODEL (UNIT_V_MSIZE + 9)
#define UNIT_MODEL (0x3f << UNIT_V_MODEL)
#define MODEL(x) (UNIT_MODEL & (x << UNIT_V_MODEL))
#define UNIT_FLOAT (0x40 << UNIT_V_MODEL)
#define UNIT_MULT (0x100 << UNIT_V_MODEL)
#define OPTION_MASK (0x140 << UNIT_V_MODEL)
#define TMR_RTC 1
@@ -72,28 +69,28 @@
#define MOD4 12 /* A2 OPT */
#define MOD4A 13 /* C2 OPT */
#define MOD4E 14 /* C2 OPT */
#define MOD4F 12+32
#define MOD4S 15 /* Ax OPT */
#define MOD5 16 /* A2 FP */
#define MOD5A 17 /* Ax FP */
#define MOD5E 18 /* C2 FP */
#define MOD5F 16+32
#define MOD5S 19 /* Ax FP */
#define MOD6 20 /* C2 OPT */
#define MOD6A 21 /* Ax OPT 076 131 */
#define MOD6E 22 /* Ax OPT 076 */
#define MOD6F 20+32
#define MOD6S 23 /* Ax OPT */
#define MOD7 24 /* C2 FP */
#define MOD7A 25 /* Ax FP */
#define MOD7E 26 /* Ax FP */
#define MOD7F 24+32
#define MOD7S 27 /* Ax FP */
#define MOD8 28 /* Ax FP */
#define MOD8A 29 /* Ax FP */
#define MOD8S 30 /* Ax FP */
#define MOD9 31 /* A2 FP */
#define MODXF 32 /* C2 FP */
#define MOD4F 15
#define MOD4S 16 /* Ax OPT */
#define MOD5 17 /* A2 FP */
#define MOD5A 18 /* Ax FP */
#define MOD5E 19 /* C2 FP */
#define MOD5F 20
#define MOD5S 21 /* Ax FP */
#define MOD6 22 /* C2 OPT */
#define MOD6A 23 /* Ax OPT 076 131 */
#define MOD6E 24 /* Ax OPT 076 */
#define MOD6F 25
#define MOD6S 26 /* Ax OPT */
#define MOD7 27 /* C2 FP */
#define MOD7A 28 /* Ax FP */
#define MOD7E 29 /* Ax FP */
#define MOD7F 30
#define MOD7S 31 /* Ax FP */
#define MOD8 32 /* Ax FP */
#define MOD8A 33 /* Ax FP */
#define MOD8S 34 /* Ax FP */
#define MOD9 35 /* A2 FP */
#define MODXF 36 /* C2 FP */
@@ -172,8 +169,12 @@ t_stat cpu_set_model(UNIT * uptr, int32 val, CONST char *cptr,
void *desc);
t_stat cpu_set_float(UNIT * uptr, int32 val, CONST char *cptr,
void *desc);
t_stat cpu_show_float(FILE * st, UNIT * uptr, int32 val,
CONST void *desc);
t_stat cpu_set_mult(UNIT * uptr, int32 val, CONST char *cptr,
void *desc);
t_stat cpu_show_mult(FILE * st, UNIT * uptr, int32 val,
CONST void *desc);
t_stat cpu_show_hist(FILE * st, UNIT * uptr, int32 val,
CONST void *desc);
t_stat cpu_set_hist(UNIT * uptr, int32 val, CONST char *cptr,
@@ -239,7 +240,7 @@ uint8 io_flags = EXT_IO;
*/
UNIT cpu_unit[] =
{{ UDATA(rtc_srv, MODEL(MOD4A)|UNIT_MULT|MEMAMOUNT(7)|UNIT_IDLE, MAXMEMSIZE ), 16667 }};
{{ UDATA(rtc_srv, MODEL(MOD4A)|MEMAMOUNT(7)|UNIT_IDLE, MAXMEMSIZE ), 16667 }};
REG cpu_reg[] = {
{ORDATAD(C, RC, 22, "Instruction code"), REG_FIT},
@@ -253,17 +254,6 @@ REG cpu_reg[] = {
};
MTAB cpu_mod[] = {
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(0), NULL, "4K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(1), NULL, "8K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(3), NULL, "16K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(7), NULL, "32K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(11), NULL, "48K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(15), NULL, "64K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(23), NULL, "96K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(31), NULL, "128K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(63), NULL, "256K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(127), NULL, "512K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(254), NULL, "1024K", &cpu_set_size},
/* Stevenage */
{UNIT_MODEL, MODEL(MOD1), "1901", "1901", &cpu_set_model, NULL, NULL},
{UNIT_MODEL, MODEL(MOD1A), "1901A", "1901A", &cpu_set_model, NULL, NULL},
@@ -296,10 +286,21 @@ MTAB cpu_mod[] = {
{UNIT_MODEL, MODEL(MOD7F), "1907F", "1907F", &cpu_set_model, NULL, NULL},
{UNIT_MODEL, MODEL(MOD8A), "1908A", "1908A", &cpu_set_model, NULL, NULL},
{UNIT_MODEL, MODEL(MOD9), "1909", "1909", &cpu_set_model, NULL, NULL},
{UNIT_FLOAT, 0, "NOFLOAT", "NOFLOAT", &cpu_set_float, NULL, NULL},
{UNIT_FLOAT, UNIT_FLOAT, "FLOAT", "FLOAT", &cpu_set_float, NULL, NULL},
{UNIT_MULT, 0, "NOMULT", "NOMULT", &cpu_set_mult, NULL, NULL},
{UNIT_MULT, UNIT_MULT, "MULT", "MULT", &cpu_set_mult, NULL, NULL},
{MTAB_XTD|MTAB_VDV, 0, NULL, "NOFLOAT", &cpu_set_float, NULL, NULL, "Disable floating point"},
{MTAB_XTD|MTAB_VDV, 1, "FLOAT", "FLOAT", &cpu_set_float, &cpu_show_float, NULL, "Enable floating point"},
{MTAB_XTD|MTAB_VDV, 0, NULL, "NOMULT", &cpu_set_mult, NULL, NULL, "Disable hardware multiply"},
{MTAB_XTD|MTAB_VDV, 1, "MULT", "MULT", &cpu_set_mult, &cpu_show_mult, NULL, "Enable hardware multiply"},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(0), NULL, "4K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(1), NULL, "8K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(3), NULL, "16K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(7), NULL, "32K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(11), NULL, "48K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(15), NULL, "64K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(23), NULL, "96K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(31), NULL, "128K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(63), NULL, "256K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(127), NULL, "512K", &cpu_set_size},
{UNIT_MSIZE|MTAB_VDV, MEMAMOUNT(254), NULL, "1024K", &cpu_set_size},
{MTAB_VDV, 0, "MEMORY", NULL, NULL, &cpu_show_size},
{MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle },
{MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
@@ -324,10 +325,10 @@ uint8 Mem_test(uint32 addr) {
addr &= M22;
if (!exe_mode) {
if (addr < 8)
if (addr < 8)
return 0;
addr = addr + RD;
} else if (addr < 8)
} else if (addr < 8)
return 0;
if (!exe_mode && RL && (addr < RD || addr >= RL)) {
@@ -441,13 +442,15 @@ sim_instr(void)
intr:
if (!exe_mode && (SR64 | SR65) != 0) {
if (CPU_TYPE < TYPE_C1 && !exe_mode)
if (CPU_TYPE < TYPE_C1 && !exe_mode)
RC += RD;
exe_mode = 1;
loading = 0;
/* Store registers */
Mem_write(RD+13, &facch, 0); /* Save F.P.U. */
Mem_write(RD+12, &faccl, 0);
if (cpu_flags & FLOAT) {
Mem_write(RD+13, &facch, 0); /* Save F.P.U. */
Mem_write(RD+12, &faccl, 0);
}
RA = 0; /* Build ZSTAT */
if (cpu_flags & SV) {
Mem_read(RD+9, &RA, 0);
@@ -458,12 +461,14 @@ intr:
if (BCarry)
RA |= B1;
} else {
if (Zero)
RA |= B3;
if (OPIP | PIP)
RA |= B2;
if (CPU_TYPE >= TYPE_C1) {
if (Zero)
RA |= B3;
if (OPIP | PIP)
RA |= B2;
Mem_write(RD+9, &RA, 0);
}
}
Mem_write(RD+9, &RA, 0);
RA = RC & adrmask;
if (BV)
RA |= B0;
@@ -885,10 +890,7 @@ obey:
RP = XR[(RX+1) & 7]; /* VR */
RA = RB; /* Divisor to RA */
RB = XR[RX]; /* Dividend to RB/RP */
f =0;
//fprintf(stderr, "DVD: %08o %08o %08o - %3o C=%08o\n\r", RA, RP, RB, RF, RC);
if (RA == FMASK && RP == 1 && RB == 0) /* Flag special case */
f=1;
//fprintf(stderr, "DVD0: %08o %08o %08o - %3o C=%08o\n\r", RA, RB, RP, RF, RC);
if (RA == 0) { /* Exit on zero divisor */ /* VI */
BV = 1;
@@ -897,21 +899,41 @@ obey:
BCarry = 0;
break;
}
BCarry = (RP & B0) != 0;
n = (RP | RB) == 0; /* Save zero dividend */
/* Setup for specific divide order code */ /* V11 */
if (RF & 2) { /* DVS */
if (BCarry) {
if (RP & B0) { /* RC22 */ /* Sign extend RB */
RB = FMASK;
} else {
RB = 0;
}
}
// {
// long int divsor;
// long int dividend;
// int sign;
//
// dividend = (((long int)(RB)) << 23) | (long int)(RP);
// if (RB & B0) {
// dividend |= 0xffff800000000000;
// }
// sign = 1;
// divsor = (long int)(RA);
// if (RA & B0) {
// divsor |= 0xffffffffff000000;
// sign = -1;
// }
//fprintf(stderr, "DVD1: %08o %08o %08o %ld (%lo) / %ld (%lo) = %ld (%lo) m %ld (%lo) %o\n\r", RA, RB, RP,
// dividend, dividend, divsor, divsor, dividend/divsor, dividend/divsor,
// sign* (dividend%divsor), sign *(dividend % divsor), BV);
//}
BCarry = 0;
if ((RB | RP) == 0)
goto dvd_zero;
RP <<= 1;
RP &= FMASK;
BCarry = 0;
//fprintf(stderr, "DVD1: %08o %08o %08o \n\r", RA, RP, RB);
/* First partial remainder */ /* V12 */
if (((RB ^ RA) & B0) == 0) {
@@ -921,12 +943,14 @@ obey:
RS = RB + RA;
RK=0;
}
/* Check if potiential overflow */
if (((RS ^ RA) & B0) != 0)
BCarry = 1;
BCarry = RK != BCarry;
/* Shift left quotent and remainder */
RP <<= 1;
if (((RS ^ RA) & B0) == 0) {
RP |= 1;
RP |= 1; /* First quotient digit */
}
RB = RS << 1;
if (RP & BM1)
@@ -951,7 +975,7 @@ obey:
RB |= 1;
RB &= FMASK;
RP &= FMASK;
//fprintf(stderr, "DVD3: %08o %08o %08o \n\r", RA, RP, RB);
//fprintf(stderr, "DVD3: %08o %08o %08o %08o \n\r", RA, RP, RB, RS);
}
/* Final product */
@@ -965,61 +989,58 @@ obey:
RP |= 1;
}
RP &= FMASK;
//fprintf(stderr, "DVD4: %08o %08o %08o \n\r", RA, RP, RB);
/* Final Remainder */
if (RP & 1) {
RB = (RB + (RA ^ FMASK) + 1) & FMASK;
} else {
RB = (RB + RA) & FMASK;
}
RB = RS & FMASK;
//fprintf(stderr, "DVD4: %08o %08o %08o %08o \n\r", RA, RP, RB, RS);
/* End correction */
if ((RP & 1) == 0) {
RB = (RB + RA) & FMASK;
}
//fprintf(stderr, "DVD5: %08o %08o %08o \n\r", RA, RP, RB);
/* Form final partial product */
if (RA & B0) {
RS = (RB + (RA ^ FMASK) + 1) & FMASK;
//fprintf(stderr, "DVD5: %08o %08o %08o %08o\n\r", RA, RP, RB, RT);
if (RS == 0) {
RB = 0;
goto dvd1;
}
}
if ((RF & 1) == 0) /* DVR */
goto dvd2;
if (RB == 0)
goto dvd2;
RT = RB + (RA ^ FMASK) + 1;
//fprintf(stderr, "DVDA: %08o %08o %08o %08o \n\r", RA, RP, RB, RT);
RA = RB;
if ((((RT + RA) ^ RA) & B0) != 0)
goto dvd2;
RB = RT & FMASK;
dvd1:
//fprintf(stderr, "DVD6: %08o %08o %08o \n\r", RA, RP, RB);
RT = RP;
RP++;
if ((RT ^ RP) & B0)
BCarry = !BCarry;
if (RP & BM1)
BCarry = 1;
dvd2:
if ((RF & 1) == 0 || RB == 0) {
//fprintf(stderr, "DVD7: %08o %08o %08o \n\r", RA, RP, RB);
if (n)
BCarry = 0;
/* If remainder same as divisor, bump quotent zero remainder */
if (RB == RA) {
RT = RP;
RP++;
if ((RT & B0) != (RP & B0))
BCarry = !BCarry;
RB = 0;
}
} else { /* DVR */
RT = RB + (RA ^ FMASK) + 1;
//fprintf(stderr, "DVDA: %08o %08o %08o %08o \n\r", RA, RP, RB, RT);
RA = RB;
if ((((RT + RA) ^ RA) & B0) == 0) {
RB = RT & FMASK;
//fprintf(stderr, "DVD6: %08o %08o %08o \n\r", RA, RP, RB);
RT = RP;
RP++;
if ((RT ^ RP) & B0)
BCarry = !BCarry;
if (RP & BM1)
BCarry = 1;
}
}
dvd_zero:
/* Set overflow if BCarry still set */
if (BCarry) {
BV = 1;
if (!exe_mode && (Mode & 7) == 4)
SR64 |= B2;
}
BCarry = 0;
if (f) {
RB = 0;
RP = FMASK;
//fprintf(stderr, "DVD8: %08o %08o %08o \n\r", RA, RP, RB);
}
// {
// int32 a;
// int32 b;
//
// a = RB;
// if (RB & B0)
// a |= 0xff000000;
// b = RP;
// if (RP & B0)
// b |= 0xff000000;
//fprintf(stderr, "DVD8: q=%08o(%d) r=%08o(%d) %d %d %d\n\r", RP, b, RB, a, BV);
//}
XR[RX] = RB & FMASK;
XR[(RX+1) & 7] = RP & FMASK;
break;
@@ -1518,7 +1539,7 @@ norm1:
/* Not on A*/
case OP_SMO: /* Supplementary Modifier - BC */
if (CPU_TYPE < TYPE_B1)
if (CPU_TYPE < TYPE_C1)
goto voluntary;
if (OPIP) { /* Error */
SR64 |= B1;
@@ -1528,7 +1549,7 @@ norm1:
goto intr;
}
PIP = 1;
break;
goto fetch;
case OP_NULL: /* No Operation */
if (!exe_mode && RX == 7 && (Mode & 7) > 0 && (Mode & 7) < 5)
@@ -2128,7 +2149,7 @@ fexp:
case 0151:
case 0160: /* Stevenage machines */ /* Load accumulators */
case 0161: /* Stevenage machines */ /* Store accumulators */
case 0162: /* Stevenage machines */
case 0162: /* Stevenage machines */
case 0163: /* Stevenage machines */ /* Stope and Display */
case 0164: /* Stevenage machines */ /* Search List N for Word X */
case 0165: /* Stevenage machines */ /* Parity Search */
@@ -2143,7 +2164,7 @@ fexp:
case 1: RA = SR1; break;
case 64: RA = SR64; SR64 &= 003777777; break;
case 65: RA = SR65; break;
default: if (RB < 64)
default: if (RB < 64)
chan_nsi_status(RB, &RA);
break;
}
@@ -2154,7 +2175,7 @@ fexp:
case 0171: /* Write special register */
if (exe_mode) {
//fprintf(stderr, "WR SR %o %08o\n\r", RB, RA);
if (RB < 64)
if (RB < 64)
chan_nsi_cmd(RB, RA);
break;
}
@@ -2240,25 +2261,27 @@ voluntary:
reason = SCPE_STOP;
break;
}
if (CPU_TYPE < TYPE_C1 && !exe_mode)
if (CPU_TYPE < TYPE_C1 && !exe_mode)
RC += RD;
exe_mode = 1;
/* Store registers */
Mem_write(RD+13, &facch, 0); /* Save F.P.U. */
Mem_write(RD+12, &faccl, 0);
RA = 0; /* Build ZSTAT */
if (Zero)
RA |= B3;
if (OPIP)
RA |= B2;
Mem_write(RD+9, &RA, 0);
if (CPU_TYPE >= TYPE_C1) {
RA = 0; /* Build ZSTAT */
if (Zero)
RA |= B3;
if (OPIP)
RA |= B2;
Mem_write(RD+9, &RA, 0);
}
RA = RC;
if (BV)
RA |= B0;
if (BCarry)
RA |= B1;
/* Type A & B */
if (CPU_TYPE < TYPE_C1 && Zero)
if (CPU_TYPE < TYPE_C1 && Zero)
RA |= B8;
Mem_write(RD+8, &RA, 0);
for (n = 0; n < 8; n++)
@@ -2382,12 +2405,8 @@ cpu_set_model(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
cpu_flags = ptr->cpu_flags;
io_flags = ptr->io_flags;
rtc_tps = ptr->ticker;
cpu_unit[0].flags &= ~(UNIT_MODEL|UNIT_FLOAT|UNIT_MULT);
cpu_unit[0].flags &= ~(UNIT_MODEL);
cpu_unit[0].flags |= MODEL(val);
if (cpu_flags & FLOAT)
cpu_unit[0].flags |= UNIT_FLOAT;
if (cpu_flags & MULT)
cpu_unit[0].flags |= UNIT_MULT;
return SCPE_OK;
}
}
@@ -2398,10 +2417,6 @@ t_stat
cpu_set_float(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
{
int32 oval = val;
if (val == 0 && (cpu_flags & (FLOAT_OPT|FLOAT)) == FLOAT)
val = UNIT_FLOAT;
cpu_unit[0].flags &= ~UNIT_FLOAT;
cpu_unit[0].flags |= val;
cpu_flags &= ~FLOAT;
if (val)
cpu_flags |= FLOAT;
@@ -2410,14 +2425,17 @@ cpu_set_float(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_OK;
}
t_stat
cpu_show_float(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "%s", (cpu_flags & FLOAT) ? "FLOAT":"NOFLOAT");
return SCPE_OK;
}
t_stat
cpu_set_mult(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
{
int32 oval = val;
if (val == 0 && (cpu_flags & (MULT_OPT|MULT)) == MULT)
val = UNIT_MULT;
cpu_unit[0].flags &= ~UNIT_MULT;
cpu_unit[0].flags |= val;
cpu_flags &= ~MULT;
if (val)
cpu_flags |= MULT;
@@ -2425,6 +2443,13 @@ cpu_set_mult(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_ARG;
return SCPE_OK;
}
t_stat
cpu_show_mult(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "%s", (cpu_flags & MULT) ? "MULT":"NOMULT");
return SCPE_OK;
}
/* Handle execute history */

View File

@@ -42,7 +42,7 @@ DIB cty_dib = { CHAR_DEV, NULL, cty_cmd, cty_status};
#define CMD u3
#define STATUS u4
#define HOLD u5
#define START 01
#define STOP 02
#define END 000001
@@ -104,7 +104,7 @@ DEVICE cty_dev = {
void cty_cmd(int dev, uint32 cmd) {
int u = 0;
if (dev > 3)
if (dev > 3)
return;
if (dev == 2)
u++;
@@ -113,8 +113,8 @@ void cty_cmd(int dev, uint32 cmd) {
cty_unit[u].STATUS |= BUSY;
if (!u)
sim_activate(&cty_unit[u], cty_unit[u].wait);
}
else if (cmd & STOP) {
}
else if (cmd & STOP) {
cty_unit[u].STATUS &= ~BUSY;
}
cty_unit[u].STATUS &= BUSY;
@@ -124,7 +124,7 @@ void cty_cmd(int dev, uint32 cmd) {
void cty_status(int dev, uint32 *resp) {
int u = 0;
if (dev > 3)
if (dev > 3)
return;
if (dev == 2)
u++;
@@ -142,7 +142,7 @@ t_stat ctyo_svc (UNIT *uptr)
/* Check if we had a held characteter */
if (uptr->HOLD != 0) {
if ((r = sim_putchar_s (uptr->HOLD)) == SCPE_STALL) {
r = SCPE_OK;
r = SCPE_OK;
} else {
if (uptr->HOLD == '\r')
uptr->HOLD = '\n';
@@ -153,7 +153,7 @@ t_stat ctyo_svc (UNIT *uptr)
return r;
}
if (uptr->STATUS & BUSY) {
if (uptr->STATUS & BUSY) {
eor = chan_output_char(GET_UADDR(uptr->flags), &ch, 0);
switch (ch & 060) {
case 000: ch = 0060 | (ch & 017); break;
@@ -238,7 +238,7 @@ t_stat ctyi_svc (UNIT *uptr)
default:
sim_debug(DEBUG_DATA, &cty_dev, ": key '%c'\n", ch);
if (ch >= 0140)
if (ch >= 0140)
ch -= 040;
if (ch >= 0100)
ch -= 040;
@@ -286,7 +286,7 @@ t_stat ctyi_svc (UNIT *uptr)
uptr->HOLD = 0;
chan_set_done(GET_UADDR(uptr->flags));
break;
default:
sim_debug(DEBUG_DATA, &cty_dev, ": key '%c'\n", ch);
sim_putchar('\007');

View File

@@ -32,9 +32,9 @@
#define NUM_DEVS_PTP 2
#define NUM_DEVS_CDR 0
#define NUM_DEVS_CDP 0
#define NUM_DEVS_LPR 0
#define NUM_DEVS_LPR 1
#define NUM_DEVS_CON 0
#define NUM_DEVS_MT 0 /* 1971 SI tape drives */
#define NUM_DEVS_MT 4 /* 1971 SI tape drives */
#define NUM_DEVS_MTA 8 /* 1974 NSI tape drives */
#define NUM_DEVS_DSK 0
#define NUM_DEVS_DTC 0

352
ICL1900/icl1900_lp.c Normal file
View File

@@ -0,0 +1,352 @@
/* icl1900_lp.c: ICL1900 Line Printer simulator
Copyright (c) 2018, Richard Cornwell
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
RICHARD CORNWELL 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 Richard Cornwell shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Richard Cornwell
*/
#include "icl1900_defs.h"
#ifndef NUM_DEVS_LPR
#define NUM_DEVS_LPR 0
#endif
#define UNIT_V_TYPE (UNIT_V_UF + 1)
#define UNIT_TYPE (0x1f << UNIT_V_TYPE)
#define GET_TYPE(x) ((UNIT_TYPE & (x)) >> UNIT_V_TYPE)
#define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE))
#define NSI_TYPE(x) ((GET_TYPE(x) & 1) == 0)
#define SI_TYPE(x) ((GET_TYPE(x) & 1) != 0)
#define LW_96(x) ((GET_TYPE(x) & 06) == 0)
#define LW_120(x) ((GET_TYPE(x) & 06) == 2)
#define LW_160(x) ((GET_TYPE(x) & 06) == 4)
#define CMD u3
#define STATUS u4
#define MOTION u5
#define AUTO 00100
#define PRINT 00040
#define SPACE 00010
#define TERMINATE 0001
#define OPAT 0002
#define ERROR 0004
#define BUSY 0040
#define DISC 0100
#if (NUM_DEVS_LPR > 0)
#define T1930_1 0
#define T1930_2 2
#define T1931_1 1
#define T1931_2 3
#define T1932_1 1+8
#define T1932_2 3+8
#define T1933_1 1+12
#define T1933_2 3+12
#define T1933_3 5+12
#define UNIT_LPR(x) UNIT_ADDR(x)|SET_TYPE(T1931_2)|UNIT_ATTABLE|\
UNIT_DISABLE|UNIT_TEXT
void lpr_cmd (int dev, uint32 cmd, uint32 *resp);
void lpr_nsi_cmd (int dev, uint32 cmd);
void lpr_nsi_status (int dev, uint32 *resp);
t_stat lpr_svc (UNIT *uptr);
t_stat lpr_reset (DEVICE *dptr);
t_stat lpr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
CONST char *lpr_description (DEVICE *dptr);
DIB lpr_dib = { CHAR_DEV, &lpr_cmd, &lpr_nsi_cmd, &lpr_nsi_status };
UNIT lpr_unit[] = {
{ UDATA (&lpr_svc, UNIT_LPR(11), 0), 10000 },
{ UDATA (&lpr_svc, UNIT_LPR(13), 0), 10000 },
};
MTAB lpr_mod[] = {
{ UNIT_TYPE, SET_TYPE(T1930_1), "1930/1", "1930/1", NULL, NULL, "ICL 1930/1 NSI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1930_2), "1930/2", "1930/2", NULL, NULL, "ICL 1930/2 NSI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1931_1), "1931/1", "1931/1", NULL, NULL, "ICL 1931/1 SI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1931_2), "1931/2", "1931/2", NULL, NULL, "ICL 1931/2 SI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1932_1), "1932/1", "1932/1", NULL, NULL, "ICL 1932/1 SI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1932_2), "1932/2", "1932/2", NULL, NULL, "ICL 1932/2 SI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1933_1), "1933/1", "1933/1", NULL, NULL, "ICL 1933/1 SI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1933_2), "1933/2", "1933/2", NULL, NULL, "ICL 1933/2 SI 1000LPM printer."},
{ UNIT_TYPE, SET_TYPE(T1933_3), "1933/3", "1933/3", NULL, NULL, "ICL 1933/3 SI 1000LPM printer."},
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_chan, &get_chan, NULL, "Device Number"},
{ 0 }
};
DEVICE lpr_dev = {
"LP", lpr_unit, NULL, lpr_mod,
NUM_DEVS_PTP, 8, 22, 1, 8, 22,
NULL, NULL, &lpr_reset, NULL, &attach_unit, &detach_unit,
&lpr_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
NULL, NULL, &lpr_help, NULL, NULL, &lpr_description
};
/*
* Command codes
*
* 011010 Write
* 000010 AutoWrite
* 010000 Send Q.
* 010100 Send P.
* 011110 Disconnect.
*/
void lpr_cmd(int dev, uint32 cmd, uint32 *resp) {
int i;
UNIT *uptr = NULL;
*resp = 0;
/* Find the unit from dev */
for (i = 0; i < lpr_dev.numunits; i++) {
if (GET_UADDR(lpr_unit[i].flags) == dev) {
uptr = &lpr_unit[i];
break;
}
}
/* Should not happen, but just in case */
if (uptr == NULL)
return;
/* Ignore this command if not a SI device */
if (NSI_TYPE(uptr->flags))
return;
if ((uptr->flags & UNIT_ATT) == 0)
return;
if (cmd == 032 || cmd == 02) { /* Command */
if (uptr->STATUS & BUSY) {
*resp = 3;
return;
}
uptr->CMD = (cmd == 02) ? AUTO: 0;
uptr->STATUS = BUSY;
sim_activate(uptr, uptr->wait);
chan_clr_done(GET_UADDR(uptr->flags));
*resp = 5;
} else if (cmd == SEND_Q) {
if ((uptr->flags & UNIT_ATT) == 0)
*resp = 040;
if (uptr->STATUS & 06)
*resp = 040;
*resp |= uptr->STATUS & TERMINATE;
} else if (cmd == SEND_P) { /* Send P */
if ((uptr->flags & UNIT_ATT) != 0)
*resp = (uptr->STATUS & ERROR) | 1;
uptr->STATUS = 0;
chan_clr_done(GET_UADDR(uptr->flags));
} else if (cmd == DISCO) { /* Disconnect */
uptr->STATUS |= DISC;
*resp = 5;
}
sim_debug(DEBUG_CMD, &lpr_dev, "CMD: %03o %03o %03o\n", cmd, uptr->CMD, uptr->STATUS);
}
/*
* Command codes
*
* xxxx01 Start print.
* xxxx10 Stop print.
*/
void lpr_nsi_cmd(int dev, uint32 cmd) {
int i;
UNIT *uptr = NULL;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTP; i++) {
if (GET_UADDR(lpr_unit[i].flags) == dev) {
uptr = &lpr_unit[i];
break;
}
}
/* Should not happen, but just in case */
if (uptr == NULL)
return;
/* Ignore this command if not a SI device */
if (SI_TYPE(uptr->flags))
return;
if (cmd & 02) {
if (uptr->STATUS & BUSY)
uptr->STATUS |= DISC;
return;
}
if (cmd & 01) {
if (uptr->CMD & BUSY || (uptr->flags & UNIT_ATT) == 0) {
uptr->STATUS |= OPAT;
chan_set_done(GET_UADDR(uptr->flags));
return;
}
uptr->CMD |= 0;
uptr->STATUS = BUSY;
sim_activate(uptr, uptr->wait);
chan_clr_done(GET_UADDR(uptr->flags));
sim_debug(DEBUG_CMD, &lpr_dev, "CMD: %03o %03o %03o\n", cmd, uptr->CMD, uptr->STATUS);
}
}
/*
* NSI Status bits.
*
* 001 End.
* 002 Opat.
* 004 ERROR
* 020 ACCEPT
* 040 BUSY
*/
void lpr_nsi_status(int dev, uint32 *resp) {
int i;
UNIT *uptr = NULL;
*resp = 0;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTP; i++) {
if (GET_UADDR(lpr_unit[i].flags) == dev) {
uptr = &lpr_unit[i];
break;
}
}
/* Should not happen, but just in case */
if (uptr == NULL)
return;
/* Ignore this command if not a SI device */
if (SI_TYPE(uptr->flags))
return;
*resp = uptr->STATUS & 077;
uptr->STATUS &= BUSY|DISCO ;
chan_clr_done(GET_UADDR(uptr->flags));
sim_debug(DEBUG_CMD, &lpr_dev, "ST: %08o %03o %03o\n", *resp, uptr->CMD, uptr->STATUS);
}
t_stat lpr_svc (UNIT *uptr)
{
t_stat r;
uint8 ch;
int data;
char buffer[200];
int i;
int len;
int eor;
/* Handle a disconnect request */
if (uptr->STATUS & DISC) {
uptr->STATUS &= ~(BUSY|DISC);
uptr->STATUS |= TERMINATE;
chan_set_done(GET_UADDR(uptr->flags));
return SCPE_OK;
}
/* If not busy, false schedule, just exit */
if ((uptr->STATUS & BUSY) == 0)
return SCPE_OK;
/* Check if attached */
if ((uptr->flags & UNIT_ATT) == 0) {
uptr->STATUS = ERROR|TERMINATE;
chan_set_done(GET_UADDR(uptr->flags));
return SCPE_OK;
}
len = 96;
if (LW_120(uptr->flags))
len = 120;
else if (LW_160(uptr->flags))
len = 160;
for (i = 0; i < len && eor == 0; i++) {
eor = chan_output_char(GET_UADDR(uptr->flags), &ch, 0);
sim_debug(DEBUG_DATA, &lpr_dev, "DATA: %03o\n", ch);
switch (ch & 060) {
case 000: ch = 0060 | (ch & 017); break;
case 020: ch = 0040 | (ch & 017); break;
case 040: ch = 0100 | (ch & 017); break;
case 060: ch = 0120 | (ch & 017); break;
}
buffer[i] = ch;
}
buffer[i++] = '\r';
buffer[i++] = '\n';
buffer[i++] = '\0';
sim_fwrite(&buffer, 1, i, uptr->fileref);
/* Check if Done */
if (eor) {
uptr->STATUS |= TERMINATE;
uptr->STATUS &= ~(BUSY|DISC);
chan_set_done(GET_UADDR(uptr->flags));
return SCPE_OK;
}
return SCPE_OK;
}
/* Reset */
t_stat lpr_reset (DEVICE *dptr)
{
UNIT *uptr = dptr->units;
int unit;
for (unit = 0; unit < NUM_DEVS_PTP; unit++, uptr++) {
uptr->STATUS = 0;
chan_clr_done(GET_UADDR(uptr->flags));
}
return SCPE_OK;
}
t_stat lpr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "The Paper Tape Punch can be set to one of two modes: 7P, or 7B.\n\n");
fprintf (st, " mode \n");
fprintf (st, " 7P Process even parity input tapes. \n");
fprintf (st, " 7B Ignore parity of input data.\n");
fprintf (st, "The default mode is 7B.\n");
return SCPE_OK;
}
CONST char *lpr_description (DEVICE *dptr)
{
return "PTP";
}
#endif

584
ICL1900/icl1900_mt.c Normal file
View File

@@ -0,0 +1,584 @@
/* icl1900_mt.c: ICL1900 2504 mag tape drive simulator.
Copyright (c) 2018, Richard Cornwell
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
RICHARD CORNWELL 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 Richard Cornwell shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Richard Cornwell
Magnetic tapes are represented as a series of variable records
of the form:
32b byte count
byte 0
byte 1
:
byte n-2
byte n-1
32b byte count
If the byte count is odd, the record is padded with an extra byte
of junk. File marks are represented by a byte count of 0.
*/
#include "icl1900_defs.h"
#include "sim_tape.h"
#if (NUM_DEVS_MT > 0)
#define BUFFSIZE (64 * 1024)
#define UNIT_MT UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE
#define CMD u3 /* Command */
#define STATUS u4
#define POS u6 /* Position within buffer */
/* Command is packed follows:
*
* Lower 3 bits is command.
* Next bit is binary/BCD.
* Next bit is disconnect flag.
* Top 16 bits are count.
*/
#define MT_CMD 077
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
#define MT_NOP 000
#define MT_FSF 001 /* No Qualifier */
#define MT_BSR 002 /* Qualifier */
#define MT_BSF 003 /* Qualifier */
#define MT_REV_READ 011 /* Qualifier */
#define MT_WRITEERG 012 /* Qualifier */
#define MT_WTM 013 /* Qualifier */
#define MT_TEST 014 /* Qualifier */
#define MT_REW 016 /* No Qualifier */
#define MT_READ 031 /* Qualifier */
#define MT_WRITE 032 /* Qualifier */
#define MT_RUN 036 /* No Qualifier */
#define MT_BOOT 037 /* No Qualifier */
#define MT_QUAL 0100 /* Qualifier expected */
#define MT_BUSY 0200 /* Device running command */
#define ST1_OK 00100 /* Unit OK */
#define ST1_WARN 00200 /* Warning, EOT, BOT, TM */
#define ST1_ERR 00400 /* Parity error, blank, no unit */
#define ST1_CORERR 01000 /* Corrected error */
#define ST1_LONG 02000 /* Long Block */
#define ST1_P2 040 /* P2 Status */
#define ST2_ROWS 0030000 /* Number of rows read */
#define ST2_BLNK 0040000 /* Blank Tape */
#define STQ_TERM 001 /* Operation terminated */
#define STQ_WRP 002 /* Write ring present */
#define STQ_ACCP 004 /* Handler accepted order */
#define STQ_S1 010 /* Controller ready to accept */
#define STQ_S2 020 /* Controller ready to accept */
#define STQ_P1 040 /* P1 Status on */
int mt_busy; /* Indicates that controller is talking to a drive */
int mt_drive; /* Indicates last selected drive */
uint8 mt_buffer[BUFFSIZE];
void mt_cmd (int dev, uint32 cmd, uint32 *resp);
t_stat mt_svc (UNIT *uptr);
t_stat mt_reset (DEVICE *dptr);
t_stat mt_boot (int32 unit_num, DEVICE * dptr);
t_stat mt_attach(UNIT *, CONST char *);
t_stat mt_detach(UNIT *);
t_stat mt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
CONST char *mt_description (DEVICE *dptr);
DIB mt_dib = { WORD_DEV|MULT_DEV, &mt_cmd, NULL, NULL };
MTAB mt_mod[] = {
{MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL},
{MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL},
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL},
{MTAB_XTD | MTAB_VDV | MTAB_VALR, 0, "DEV", "DEV",
&set_chan, &get_chan, NULL, "Device Number"},
{0}
};
UNIT mt_unit[] = {
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 0 */
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 1 */
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 2 */
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 3 */
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 4 */
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 5 */
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 6 */
{UDATA(&mt_svc, UNIT_MT, 0) }, /* 7 */
};
DEVICE mt_dev = {
"MT", mt_unit, NULL, mt_mod,
NUM_DEVS_MT, 8, 22, 1, 8, 22,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach,
&mt_dib, DEV_DISABLE | DEV_DEBUG | UNIT_ADDR(20), 0, dev_debug,
NULL, NULL, &mt_help, NULL, NULL, &mt_description
};
void mt_cmd(int dev, uint32 cmd, uint32 *resp) {
UNIT *uptr = &mt_unit[mt_drive];
*resp = 0;
if (dev & 0400) {
mt_drive = cmd & 07;
return;
}
if ((uptr->flags & UNIT_ATT) == 0) {
uptr->CMD = 0;
return;
}
if (uptr->CMD & MT_QUAL) {
*resp = 5;
uptr->CMD &= ~MT_QUAL;
} else {
switch(cmd & 070) {
case 000: if (cmd == 0) {
*resp = 5;
return;
}
uptr->CMD = cmd;
if (cmd != 1)
uptr->CMD |= MT_QUAL;
break;
case 010: uptr->CMD = cmd;
if (cmd < 016)
uptr->CMD |= MT_QUAL;
break;
case 020: if (cmd == SEND_Q) {
if (!sim_tape_wrp(uptr))
uptr->STATUS |= STQ_WRP;
*resp = uptr->STATUS & 037;
if (uptr->STATUS & 0777700)
*resp |= STQ_P1;
} else if (cmd == SEND_P) {
*resp = (uptr->STATUS >> 6) & 037;
if (uptr->STATUS & 0770000)
*resp |= ST1_P2;
} else if (cmd == SEND_P2) {
*resp = (uptr->STATUS >> 12) & 037;
}
return;
case 030: uptr->CMD = cmd;
if (cmd < 036)
uptr->CMD |= MT_QUAL;
break;
default:
return;
}
}
sim_debug(DEBUG_CMD, &mt_dev, "Cmd: unit=%d %02o\n", mt_drive, uptr->CMD);
if (uptr->flags & MT_BUSY) {
*resp = 3;
return;
}
if ((uptr->CMD & MT_QUAL) == 0) {
sim_debug(DEBUG_CMD, &mt_dev, "Cmd: unit=%d start %02o\n", mt_drive, uptr->CMD);
mt_busy = 1;
CLR_BUF(uptr);
uptr->POS = 0;
uptr->CMD |= MT_BUSY;
uptr->STATUS = ST1_OK|STQ_ACCP;
sim_activate(uptr, 100);
}
*resp = 5;
}
t_stat mt_svc (UNIT *uptr)
{
DEVICE *dptr = &mt_dev;
int unit = (uptr - dptr->units);
int dev = GET_UADDR(dptr->flags);
t_mtrlnt reclen;
t_stat r;
uint8 ch;
uint32 word;
int i;
int stop;
int eor;
/* If not busy, false schedule, just exit */
if ((uptr->CMD & MT_BUSY) == 0)
return SCPE_OK;
switch (uptr->CMD & MT_CMD) {
case MT_BOOT:
case MT_READ:
/* If empty buffer, fill */
if (BUF_EMPTY(uptr)) {
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d ", unit);
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[0], &reclen,
BUFFSIZE)) != MTSE_OK) {
sim_debug(DEBUG_DETAIL, dptr, " error %d\n", r);
uptr->STATUS = ST1_OK|STQ_TERM;
if (r == MTSE_TMK)
uptr->STATUS |= ST1_WARN;
else if (r == MTSE_WRP)
uptr->STATUS |= ST1_ERR;
else if (r == MTSE_EOM)
uptr->STATUS |= ST1_WARN;
else
uptr->STATUS |= ST1_ERR;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
uptr->hwmark = reclen;
sim_debug(DEBUG_DETAIL, dptr, "Block %d chars\n", reclen);
}
stop = 0;
/* Grab three chars off buffer */
word = 0;
for(i = 16; i >= 0; i-=8) {
if (uptr->POS >= uptr->hwmark) {
/* Add in fill characters */
if (i == 8) {
stop = 2;
} else if (i == 16) {
stop = 1;
}
break;
}
word |= (uint32)mt_buffer[uptr->POS++] << i;
}
sim_debug(DEBUG_DATA, dptr, "unit=%d read %08o\n", unit, word);
eor = chan_input_word(dev, &word, 0);
if (eor || uptr->POS >= uptr->hwmark) {
uptr->STATUS = (stop << 12) | ST1_OK|STQ_TERM;
if (uptr->POS < uptr->hwmark)
uptr->STATUS |= ST1_LONG;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
sim_activate(uptr, 100);
break;
case MT_WRITEERG: /* Write and Erase */
case MT_WRITE:
/* Check if write protected */
if (sim_tape_wrp(uptr)) {
uptr->STATUS = ST1_OK|STQ_TERM|ST1_ERR;
uptr->CMD &= ~MT_BUSY;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
eor = chan_output_word(dev, &word, 0);
sim_debug(DEBUG_DATA, dptr, "unit=%d write %08o\n", unit, word);
/* Put three chars in buffer */
word = 0;
for(i = 16; i >= 0; i-=8) {
mt_buffer[uptr->POS++] = (uint8)((word >> i) & 0xff);
}
uptr->hwmark = uptr->POS;
if (eor) {
/* Done with transfer */
reclen = uptr->hwmark;
sim_debug(DEBUG_DETAIL, dptr, "Write unit=%d Block %d chars\n",
unit, reclen);
r = sim_tape_wrrecf(uptr, &mt_buffer[0], reclen);
uptr->STATUS = ST1_OK|STQ_TERM;
if (r != MTSE_OK)
uptr->STATUS |= ST1_ERR;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
sim_activate(uptr, 100);
break;
case MT_REV_READ:
/* If empty buffer, fill */
if (BUF_EMPTY(uptr)) {
if (sim_tape_bot(uptr)) {
uptr->STATUS = ST1_OK|ST1_WARN|STQ_TERM;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
sim_debug(DEBUG_DETAIL, dptr, "Read rev unit=%d ", unit);
if ((r = sim_tape_rdrecr(uptr, &mt_buffer[0], &reclen,
BUFFSIZE)) != MTSE_OK) {
sim_debug(DEBUG_DETAIL, dptr, " error %d\n", r);
uptr->STATUS = ST1_OK|STQ_TERM;
if (r == MTSE_TMK)
uptr->STATUS |= ST1_WARN;
else if (r == MTSE_WRP)
uptr->STATUS |= ST1_ERR;
else if (r == MTSE_EOM)
uptr->STATUS |= ST1_WARN;
else
uptr->STATUS |= ST1_ERR;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
uptr->POS = reclen;
uptr->hwmark = reclen;
sim_debug(DEBUG_DETAIL, dptr, "Block %d chars\n", reclen);
}
/* Grab three chars off buffer */
word = 0;
for(i = 0; i <= 16; i+=8) {
word |= (uint32)mt_buffer[--uptr->POS] << i;
if (uptr->POS == 0) {
stop = 1;
break;
}
}
sim_debug(DEBUG_DATA, dptr, "unit=%d read %08o\n", unit, word);
eor = chan_input_word(dev, &word, 0);
if (eor || uptr->POS == 0) {
uptr->STATUS = (stop << 12) | ST1_OK|STQ_TERM;
if (uptr->POS != 0)
uptr->STATUS |= ST1_LONG;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
sim_activate(uptr, 100);
break;
case MT_FSF:
switch(uptr->POS) {
case 0:
uptr->POS ++;
sim_activate(uptr, 500);
break;
case 1:
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
r = sim_tape_sprecf(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS++;
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
sim_activate(uptr, 50);
} else if (r == MTSE_EOM) {
uptr->POS++;
uptr->STATUS = ST1_WARN;
sim_activate(uptr, 50);
} else {
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
sim_activate(uptr, 10 + (10 * reclen));
}
break;
case 2:
uptr->STATUS = ST1_OK|(ST1_WARN & uptr->STATUS) | STQ_TERM;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
}
break;
case MT_WTM:
if (uptr->POS == 0) {
if (sim_tape_wrp(uptr)) {
uptr->STATUS = ST1_OK|ST1_ERR|STQ_TERM;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
return SCPE_OK;
}
uptr->POS ++;
sim_activate(uptr, 500);
} else {
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit);
r = sim_tape_wrtmk(uptr);
uptr->STATUS = ST1_OK|STQ_TERM;
if (r != MTSE_OK)
uptr->STATUS |= ST1_ERR;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
}
break;
case MT_BSR:
switch (uptr->POS ) {
case 0:
if (sim_tape_bot(uptr)) {
uptr->STATUS = ST1_OK|ST1_WARN|STQ_TERM;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
break;
}
uptr->POS ++;
sim_activate(uptr, 500);
break;
case 1:
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
r = sim_tape_sprecr(uptr, &reclen);
/* We don't set EOF on BSR */
uptr->STATUS = ST1_OK|STQ_TERM;
if (r == MTSE_TMK || r == MTSE_BOT) {
uptr->STATUS |= ST1_WARN;
}
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
}
break;
case MT_BSF:
switch (uptr->POS ) {
case 0:
if (sim_tape_bot(uptr)) {
uptr->STATUS = ST1_OK|ST1_WARN|STQ_TERM;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
break;
}
uptr->POS ++;
sim_activate(uptr, 500);
break;
case 1:
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
r = sim_tape_sprecr(uptr, &reclen);
/* We don't set EOF on BSR */
if (r == MTSE_TMK || r == MTSE_BOT) {
uptr->POS++;
sim_activate(uptr, 50);
} else {
sim_debug(DEBUG_DETAIL, dptr, "%d \n", reclen);
sim_activate(uptr, 10 + (10 * reclen));
}
break;
case 2:
uptr->STATUS = ST1_OK|STQ_TERM;
uptr->CMD = 0;
mt_busy = 0;
chan_set_done(dev);
}
break;
case MT_REW:
if (uptr->POS == 0) {
uptr->POS ++;
sim_activate(uptr, 30000);
mt_busy = 0;
} else {
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d\n", unit);
r = sim_tape_rewind(uptr);
uptr->CMD = 0;
uptr->STATUS = ST1_OK|STQ_TERM;
chan_set_done(dev);
}
break;
}
return SCPE_OK;
}
/* Reset */
t_stat mt_reset (DEVICE *dptr)
{
UNIT *uptr = dptr->units;
int unit;
for (unit = 0; unit < dptr->numunits; unit++, uptr++) {
uptr->CMD = 0;
uptr->STATUS = 0;
if ((uptr->flags & UNIT_ATT) != 0)
uptr->STATUS = ST1_OK;
mt_busy = 0;
}
chan_clr_done(GET_UADDR(dptr->flags));
return SCPE_OK;
}
/* Boot from given device */
t_stat
mt_boot(int32 unit_num, DEVICE * dptr)
{
UNIT *uptr = &dptr->units[unit_num];
int chan = GET_UADDR(dptr->flags);
if ((uptr->flags & UNIT_ATT) == 0)
return SCPE_UNATT; /* attached? */
M[64 + chan] = 0;
M[256 + 4 * chan] = B2;
M[257 + 4 * chan] = 020;
loading = 1;
mt_busy = 1;
CLR_BUF(uptr);
uptr->CMD = MT_BUSY|MT_BOOT;
uptr->STATUS = ST1_OK|STQ_ACCP;
sim_activate (uptr, 100);
return SCPE_OK;
}
t_stat
mt_attach(UNIT * uptr, CONST char *file)
{
t_stat r;
DEVICE *dptr = &mt_dev;
int unit = (uptr - dptr->units);
if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK)
return r;
uptr->STATUS = ST1_OK;
return SCPE_OK;
}
t_stat
mt_detach(UNIT * uptr)
{
uptr->STATUS = 0;
return sim_tape_detach(uptr);
}
t_stat mt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cmt)
{
fprintf (st, "The Paper Tape Reader can be set to one of twp modes: 7P, or 7B.\n\n");
fprintf (st, " mode \n");
fprintf (st, " 7P Process even parity input tapes. \n");
fprintf (st, " 7B Ignore parity of input data.\n");
fprintf (st, "The default mode is 7B.\n");
return SCPE_OK;
}
CONST char *mt_description (DEVICE *dptr)
{
return "MT";
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -50,7 +50,7 @@ chan_set_devs()
devs[i] = NULL;
/* Add in hidden channels */
devs[22] = &nul_dib;
devs[22] = &nul_dib;
devs[23] = &nul_dib;
/* Scan all devices and assign to channel */
for(i = 0; sim_devices[i] != NULL; i++) {
@@ -64,7 +64,7 @@ chan_set_devs()
continue;
if (dibp->type & BLK_DEV) {
int f = 1;
chan = GET_UADDR(sim_devices[i]->flags);
/* Make sure it is in range */
if (chan < 2 || (chan + sim_devices[i]->numunits) > 36)
@@ -76,13 +76,13 @@ chan_set_devs()
fprintf(stderr, "Conflict between devices %d %s\n", chan+j, sim_devices[i]->name);
f = 0;
}
}
}
if (f) {
for (j = 0; j < sim_devices[i]->numunits; j++) {
if (sim_devices[i]->units[j].flags & UNIT_DIS)
continue;
devs[chan+j] = dibp;
}
}
}
} else if (dibp->type & MULT_DEV) {
chan = GET_UADDR(sim_devices[i]->flags);
@@ -136,7 +136,7 @@ set_chan(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
if (dptr == NULL)
return SCPE_IERR;
dibp = (DIB *) dptr->ctxt;
if (dibp == NULL)
return SCPE_IERR;
new_chan = get_uint(cptr, 10, 37, &r);
@@ -160,7 +160,7 @@ set_chan(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
for (i = 0; i < dptr->numunits; i++) {
if (dptr->units[i].flags & UNIT_DIS)
continue;
if (devs[cur_chan+i] == dibp)
if (devs[cur_chan+i] == dibp)
devs[cur_chan] = NULL;
}
} else if (dibp->type & MULT_DEV) {
@@ -181,7 +181,7 @@ set_chan(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
}
return SCPE_OK;
}
if (dibp->type & BLK_DEV) {
dptr->flags &= ~UNIT_M_ADDR;
dptr->flags |= UNIT_ADDR(new_chan);
@@ -210,7 +210,7 @@ set_chan(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
/* Print the channel the device is on */
t_stat
get_chan(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
get_chan(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
{
DEVICE *dptr;
DIB *dibp;
@@ -236,7 +236,7 @@ get_chan(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
return SCPE_OK;
}
int
int
get_ccw(int dev, uint32 *addr, uint8 type) {
int cw_addr;
uint32 cw0; /* Holding registers for current control word */
@@ -248,7 +248,7 @@ get_ccw(int dev, uint32 *addr, uint8 type) {
cw1 = M[cw_addr+1];
*addr = cw1;
if (cw0 & WORDCCW) {
if (cw0 & BACKWARD)
if (cw0 & BACKWARD)
cw1 = ((cw1 + M22) & M22) | (cw1 & CMASK);
else
cw1 = ((cw1 + 1) & M22) | (cw1 & CMASK);
@@ -274,7 +274,7 @@ get_ccw(int dev, uint32 *addr, uint8 type) {
cw1 = M[cw_addr+3];
} else if ((cw0 & GATHER) != 0) {
int a;
if ((cw0 & CWRECHARGE) != 0)
if ((cw0 & CWRECHARGE) != 0)
M[cw_addr+3] = M[cw_addr+2];
a = M[cw_addr+3];
cw0 = M[a & M22];
@@ -328,7 +328,7 @@ chan_nsi_cmd(int dev, uint32 cmd) {
if (dibp != NULL && dibp->nsi_cmd != NULL) {
(dibp->nsi_cmd)(dev, cmd);
}
}
}
/* Talk to non-standard interface devices */
@@ -339,7 +339,7 @@ chan_nsi_status(int dev, uint32 *resp) {
*resp = 0;
if (dibp != NULL && dibp->nsi_cmd != NULL) {
(dibp->nsi_status)(dev, resp);
}
}
}
@@ -351,7 +351,7 @@ chan_send_cmd(int dev, uint32 cmd, uint32 *resp) {
*resp = 0;
if (dibp != NULL && dibp->si_cmd != NULL) {
(dibp->si_cmd)(dev, cmd, resp);
}
}
}
/* Transfer date between device and memory */
@@ -384,8 +384,7 @@ chan_input_char(int dev, uint8 *data, int eor) {
mb |= ((uint32)(*data) & 077) << c;
if (addr < 8)
XR[addr] = mb;
else
M[addr] = mb;
M[addr] = mb;
return r;
}
@@ -437,8 +436,7 @@ chan_input_word(int dev, uint32 *data, int eor) {
addr &= M22;
if (addr < 8)
XR[addr] = *data;
else
M[addr] = *data;
M[addr] = *data;
return r;
}
@@ -468,7 +466,7 @@ chan_output_word(int dev, uint32 *data, int eor) {
void
chan_set_done(int dev) {
if (dev < 22)
if (dev < 22)
SR64 |= B2 >> dev;
else
SR65 |= B1 >> (dev - 23);
@@ -476,7 +474,7 @@ chan_set_done(int dev) {
void
chan_clr_done(int dev) {
if (dev < 22)
if (dev < 22)
SR64 &= ~(B2 >> dev);
else
SR65 &= ~(B1 >> (dev - 23));

View File

@@ -92,8 +92,8 @@ DEBTAB dev_debug[] = {
};
uint8 parity_table[64] = {
/* 0 1 2 3 4 5 6 7 */
uint8 parity_table[64] = {
/* 0 1 2 3 4 5 6 7 */
0000, 0100, 0100, 0000, 0100, 0000, 0000, 0100,
0100, 0000, 0000, 0100, 0000, 0100, 0100, 0000,
0100, 0000, 0000, 0100, 0000, 0100, 0100, 0000,
@@ -105,7 +105,7 @@ uint8 parity_table[64] = {
};
uint8 mem_to_ascii[64] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 */
/* x0 x1 x2 x3 x4 x5 x6 x7 */
'0', '1', '2', '3', '4', '5', '6', '7', /* 0x */
'8', '9', ':', ';', '<', '=', '>', '?', /* 1x */
' ', '!', '"', '#', '\\', '%', '&', '\'', /* 2x */
@@ -174,19 +174,17 @@ sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag)
if (buffer[j] == '\n')
break;
image[j] = ascii_to_mem[buffer[j]];
if (image[j] < 0) {
if (image[j] < 0) {
fprintf(stderr, "Char %c: %s", buffer[j], buffer);
return SCPE_FMT;
}
}
for (j = 0; j < 64; ) {
data = 0;
for (k = 0; k < 4; k++)
for (k = 0; k < 4; k++)
data = (data << 6) | image[j++];
fprintf(stderr, "Addr: %06o %08o\n\r", addr, data);
if (addr < 8)
XR[addr++] = data;
else
if (addr < 8)
XR[addr++] = data;
M[addr++] = data;
}
}
@@ -199,7 +197,7 @@ else
if (buffer[j] == '\n')
break;
image[j] = ascii_to_mem[buffer[j]];
if (image[j] < 0) {
if (image[j] < 0) {
fprintf(stderr, "Char %c: %s", buffer[j], buffer);
return SCPE_FMT;
}
@@ -211,24 +209,24 @@ else
switch(image[3]) {
case 0:
checksum = 0;
for (j = 0; j < 4; j++)
for (j = 0; j < 4; j++)
checksum = (checksum << 6) | image[j];
addr = 0;
for (; j < 8; j++)
for (; j < 8; j++)
addr = (addr << 6) | image[j];
checksum += addr;
for (i = 3; i < image[1]; i++) {
data = 0;
for (k = 0; k < 4; k++)
for (k = 0; k < 4; k++)
data = (data << 6) | image[j++];
checksum += data;
M[addr++] = data;
}
data = 0;
for (k = 0; k < 4; k++)
for (k = 0; k < 4; k++)
data = (data << 6) | image[j++];
data = FMASK & (checksum + data);
if (data != 0)
if (data != 0)
fprintf(stderr, "Check %08o %08o: %s", addr, data, buffer);
break;
case 1:
@@ -237,24 +235,24 @@ else
case 2:
case 3:
checksum = 0;
for (j = 0; j < 4; j++)
for (j = 0; j < 4; j++)
checksum = (checksum << 6) | image[j];
addr = 0;
for (; j < 8; j++)
for (; j < 8; j++)
addr = (addr << 6) | image[j];
checksum += addr;
RC = addr;
data = 0;
for (i = 3; i < image[1]; i++) {
data = 0;
for (k = 0; k < 4; k++)
for (k = 0; k < 4; k++)
data = (data << 6) | image[j++];
checksum += data;
}
for (k = 0; k < 4; k++)
for (k = 0; k < 4; k++)
data = (data << 6) | image[j++];
data = FMASK & (checksum + data);
if (data != 0)
if (data != 0)
fprintf(stderr, "Check %08o %08o: %s", addr, data, buffer);
break;
case 4:
@@ -282,134 +280,134 @@ else
/* Opcodes */
t_opcode ops[] = {
"LDX", TYPE_A, /* Load to X */
"ADX", TYPE_A, /* Add to X */
"NGX", TYPE_A, /* Negative to X */
"SBX", TYPE_A, /* Subtract from X */
"LDXC", TYPE_A, /* Load into X with carry */
"ADXC", TYPE_A, /* Add to X with carry */
"NGXC", TYPE_A, /* Negative to X with carry */
"SBXC", TYPE_A, /* Subtract from X with carry */
"STO", TYPE_A, /* Store contents of X */
"ADS", TYPE_A, /* Add X to store */
"NGS", TYPE_A, /* Negative into Store */
"SBS", TYPE_A, /* Subtract from store */
"STOC", TYPE_A, /* Store contents of X with carry */
"ADSC", TYPE_A, /* Add X to store with carry */
"NGSC", TYPE_A, /* Negative into Store with carry */
"SBSC", TYPE_A, /* Subtract from store with carry */
"ANDX", TYPE_A, /* Logical AND into X */
"ORX", TYPE_A, /* Logical OR into X */
"ERX", TYPE_A, /* Logical XOR into X */
"OBEY", TYPE_A, /* Obey instruction at N */
"LDCH", TYPE_A, /* Load Character to X */
"LDEX", TYPE_A, /* Load Exponent */
"TXU", TYPE_A, /* Test X unequal */
"TXL", TYPE_A, /* Test X Less */
"ANDS", TYPE_A, /* Logical AND into store */
"ORS", TYPE_A, /* Logical OR into store */
"ERS", TYPE_A, /* Logical XOR into store */
"STOZ", TYPE_A, /* Store Zero */
"DCH", TYPE_A, /* Deposit Character to X */
"DEX", TYPE_A, /* Deposit Exponent */
"DSA", TYPE_A, /* Deposit Short Address */
"DLA", TYPE_A, /* Deposit Long Address */
"MPY", TYPE_A, /* Multiply */
"MPR", TYPE_A, /* Multiply and Round */
"MPA", TYPE_A, /* Multiply and Accumulate */
"CDB", TYPE_A, /* Convert Decimal to Binary */
"DVD", TYPE_A, /* Unrounded Double Length Divide */
"DVR", TYPE_A, /* Rounded Double Length Divide */
"DVS", TYPE_A, /* Single Length Divide */
"CBD", TYPE_A, /* Convert Binary to Decimal */
"BZE", TYPE_B, /* Branch if X is Zero */
"BZE", TYPE_B,
"BNZ", TYPE_B, /* Branch if X is not Zero */
"BNZ", TYPE_B,
"BPZ", TYPE_B, /* Branch if X is Positive or zero */
"BPZ", TYPE_B,
"BNG", TYPE_B, /* Branch if X is Positive or zero */
"BNG", TYPE_B,
"BUX", TYPE_B, /* Branch on Unit indexing */
"BUX", TYPE_B,
"BDX", TYPE_B, /* Branch on Double Indexing */
"BDX", TYPE_B,
"BCHX", TYPE_B, /* Branch on Character Indexing */
"BCHX", TYPE_B,
"BCT", TYPE_B, /* Branch on Count - BC */
"BCT", TYPE_B,
"CALL", TYPE_B, /* Call Subroutine */
"CALL", TYPE_B,
"EXIT", TYPE_B, /* Exit Subroutine */
"EXIT", TYPE_B,
NULL, TYPE_D, /* Branch unconditional */
NULL, TYPE_D,
"BFP", TYPE_B, /* Branch state of floating point accumulator */
"BFP", TYPE_B,
"LDN", TYPE_A, /* Load direct to X */
"ADN", TYPE_A, /* Add direct to X */
"NGN", TYPE_A, /* Negative direct to X */
"SBN", TYPE_A, /* Subtract direct from X */
"LDNC", TYPE_A, /* Load direct into X with carry */
"ADNC", TYPE_A, /* Add direct to X with carry */
"NGNC", TYPE_A, /* Negative direct to X with carry */
"SBNC", TYPE_A, /* Subtract direct from X with carry */
"SL", TYPE_C, /* Shift Left */
"SLD", TYPE_C, /* Shift Left Double */
"SR", TYPE_C, /* Shift Right */
"SRD", TYPE_C, /* Shift Right Double */
"NORM", TYPE_A, /* Nomarlize Single -2 +FP */
"NORMD", TYPE_A, /* Normalize Double -2 +FP */
"MVCH", TYPE_A, /* Move Characters - BC */
"SMO", TYPE_A, /* Supplementary Modifier - BC */
"ANDN", TYPE_A, /* Logical AND direct into X */
"ORN", TYPE_A, /* Logical OR direct into X */
"ERN", TYPE_A, /* Logical XOR direct into X */
"NULL", TYPE_A, /* No Operation */
"LDCT", TYPE_A, /* Load Count */
"MODE", TYPE_A, /* Set Mode */
"MOVE", TYPE_A, /* Copy N words */
"SUM", TYPE_A, /* Sum N words */
"FLOAT", TYPE_A, /* Convert Fixed to Float +FP */
"FIX", TYPE_A, /* Convert Float to Fixed +FP */
"FAD", TYPE_A, /* Floating Point Add +FP */
"FSB", TYPE_A, /* Floating Point Subtract +FP */
"FMPY", TYPE_A, /* Floating Point Multiply +FP */
"FDVD", TYPE_A, /* Floating Point Divide +FP */
"LFP", TYPE_A, /* Load Floating Point +FP */
"SFP", TYPE_A, /* Store Floating Point +FP */
"140", TYPE_A,
"141", TYPE_A,
"142", TYPE_A,
"143", TYPE_A,
"144", TYPE_A,
"145", TYPE_A,
"146", TYPE_A,
"147", TYPE_A,
"150", TYPE_A,
"151", TYPE_A,
"152", TYPE_A,
"153", TYPE_A,
"154", TYPE_A,
"155", TYPE_A,
"156", TYPE_A,
"157", TYPE_A,
"160", TYPE_A,
"161", TYPE_A,
"162", TYPE_A,
"163", TYPE_A,
"164", TYPE_A,
"165", TYPE_A,
"166", TYPE_A,
"167", TYPE_A,
"170", TYPE_A,
"171", TYPE_A,
"172", TYPE_A,
"173", TYPE_A,
"174", TYPE_A,
"175", TYPE_A,
"176", TYPE_A,
"177", TYPE_A,
"LDX", TYPE_A, /* Load to X */
"ADX", TYPE_A, /* Add to X */
"NGX", TYPE_A, /* Negative to X */
"SBX", TYPE_A, /* Subtract from X */
"LDXC", TYPE_A, /* Load into X with carry */
"ADXC", TYPE_A, /* Add to X with carry */
"NGXC", TYPE_A, /* Negative to X with carry */
"SBXC", TYPE_A, /* Subtract from X with carry */
"STO", TYPE_A, /* Store contents of X */
"ADS", TYPE_A, /* Add X to store */
"NGS", TYPE_A, /* Negative into Store */
"SBS", TYPE_A, /* Subtract from store */
"STOC", TYPE_A, /* Store contents of X with carry */
"ADSC", TYPE_A, /* Add X to store with carry */
"NGSC", TYPE_A, /* Negative into Store with carry */
"SBSC", TYPE_A, /* Subtract from store with carry */
"ANDX", TYPE_A, /* Logical AND into X */
"ORX", TYPE_A, /* Logical OR into X */
"ERX", TYPE_A, /* Logical XOR into X */
"OBEY", TYPE_A, /* Obey instruction at N */
"LDCH", TYPE_A, /* Load Character to X */
"LDEX", TYPE_A, /* Load Exponent */
"TXU", TYPE_A, /* Test X unequal */
"TXL", TYPE_A, /* Test X Less */
"ANDS", TYPE_A, /* Logical AND into store */
"ORS", TYPE_A, /* Logical OR into store */
"ERS", TYPE_A, /* Logical XOR into store */
"STOZ", TYPE_A, /* Store Zero */
"DCH", TYPE_A, /* Deposit Character to X */
"DEX", TYPE_A, /* Deposit Exponent */
"DSA", TYPE_A, /* Deposit Short Address */
"DLA", TYPE_A, /* Deposit Long Address */
"MPY", TYPE_A, /* Multiply */
"MPR", TYPE_A, /* Multiply and Round */
"MPA", TYPE_A, /* Multiply and Accumulate */
"CDB", TYPE_A, /* Convert Decimal to Binary */
"DVD", TYPE_A, /* Unrounded Double Length Divide */
"DVR", TYPE_A, /* Rounded Double Length Divide */
"DVS", TYPE_A, /* Single Length Divide */
"CBD", TYPE_A, /* Convert Binary to Decimal */
"BZE", TYPE_B, /* Branch if X is Zero */
"BZE", TYPE_B,
"BNZ", TYPE_B, /* Branch if X is not Zero */
"BNZ", TYPE_B,
"BPZ", TYPE_B, /* Branch if X is Positive or zero */
"BPZ", TYPE_B,
"BNG", TYPE_B, /* Branch if X is Positive or zero */
"BNG", TYPE_B,
"BUX", TYPE_B, /* Branch on Unit indexing */
"BUX", TYPE_B,
"BDX", TYPE_B, /* Branch on Double Indexing */
"BDX", TYPE_B,
"BCHX", TYPE_B, /* Branch on Character Indexing */
"BCHX", TYPE_B,
"BCT", TYPE_B, /* Branch on Count - BC */
"BCT", TYPE_B,
"CALL", TYPE_B, /* Call Subroutine */
"CALL", TYPE_B,
"EXIT", TYPE_B, /* Exit Subroutine */
"EXIT", TYPE_B,
NULL, TYPE_D, /* Branch unconditional */
NULL, TYPE_D,
"BFP", TYPE_B, /* Branch state of floating point accumulator */
"BFP", TYPE_B,
"LDN", TYPE_A, /* Load direct to X */
"ADN", TYPE_A, /* Add direct to X */
"NGN", TYPE_A, /* Negative direct to X */
"SBN", TYPE_A, /* Subtract direct from X */
"LDNC", TYPE_A, /* Load direct into X with carry */
"ADNC", TYPE_A, /* Add direct to X with carry */
"NGNC", TYPE_A, /* Negative direct to X with carry */
"SBNC", TYPE_A, /* Subtract direct from X with carry */
"SL", TYPE_C, /* Shift Left */
"SLD", TYPE_C, /* Shift Left Double */
"SR", TYPE_C, /* Shift Right */
"SRD", TYPE_C, /* Shift Right Double */
"NORM", TYPE_A, /* Nomarlize Single -2 +FP */
"NORMD", TYPE_A, /* Normalize Double -2 +FP */
"MVCH", TYPE_A, /* Move Characters - BC */
"SMO", TYPE_A, /* Supplementary Modifier - BC */
"ANDN", TYPE_A, /* Logical AND direct into X */
"ORN", TYPE_A, /* Logical OR direct into X */
"ERN", TYPE_A, /* Logical XOR direct into X */
"NULL", TYPE_A, /* No Operation */
"LDCT", TYPE_A, /* Load Count */
"MODE", TYPE_A, /* Set Mode */
"MOVE", TYPE_A, /* Copy N words */
"SUM", TYPE_A, /* Sum N words */
"FLOAT", TYPE_A, /* Convert Fixed to Float +FP */
"FIX", TYPE_A, /* Convert Float to Fixed +FP */
"FAD", TYPE_A, /* Floating Point Add +FP */
"FSB", TYPE_A, /* Floating Point Subtract +FP */
"FMPY", TYPE_A, /* Floating Point Multiply +FP */
"FDVD", TYPE_A, /* Floating Point Divide +FP */
"LFP", TYPE_A, /* Load Floating Point +FP */
"SFP", TYPE_A, /* Store Floating Point +FP */
"140", TYPE_A,
"141", TYPE_A,
"142", TYPE_A,
"143", TYPE_A,
"144", TYPE_A,
"145", TYPE_A,
"146", TYPE_A,
"147", TYPE_A,
"150", TYPE_A,
"151", TYPE_A,
"152", TYPE_A,
"153", TYPE_A,
"154", TYPE_A,
"155", TYPE_A,
"156", TYPE_A,
"157", TYPE_A,
"160", TYPE_A,
"161", TYPE_A,
"162", TYPE_A,
"163", TYPE_A,
"164", TYPE_A,
"165", TYPE_A,
"166", TYPE_A,
"167", TYPE_A,
"170", TYPE_A,
"171", TYPE_A,
"172", TYPE_A,
"173", TYPE_A,
"174", TYPE_A,
"175", TYPE_A,
"176", TYPE_A,
"177", TYPE_A,
};
char *type_d[] = { "BRN", "BVS", "BVSR", "BVC", "BVCR", "BCS", "BCC", "BVCI" };
@@ -426,7 +424,7 @@ print_opcode(FILE * of, t_value val)
int m;
int n;
t_opcode *tab;
op = 0177 & (val >> 14);;
x = 07 & (val >> 21);
m = 03 & (val >> 12);
@@ -496,7 +494,7 @@ fprint_sym(FILE * of, t_addr addr, t_value * val, UNIT * uptr, int32 sw)
return SCPE_OK;
}
int
int
find_opcode(char *op, int *val)
{
int i;
@@ -513,10 +511,10 @@ find_opcode(char *op, int *val)
return -1;
}
}
if (op[i] == 0 && v <= 0177)
if (op[i] == 0 && v <= 0177)
return v;
for(i = 0; i <= 0177; i++) {
if (ops[i].name != '\0' && sim_strcasecmp(op, ops[i].name) == 0)
if (ops[i].name != '\0' && sim_strcasecmp(op, ops[i].name) == 0)
return i;
}
for(i = 0; i < 8; i++) {
@@ -593,12 +591,12 @@ if (sw & SWMASK ('M')) {
*val = (0177 & op) << 14;
if (x >= 0)
*val |= (07 & x) << 21;
switch (ops[op].type) {
case TYPE_A: /* OP x m/n or OP x /n */
if (m > 0)
*val |= (m & 03) << 12;
if (*cptr == '/') {
if (*cptr == '/') {
cptr++;
n = get_uint(cptr, 8, 07777, &r);
if (r != SCPE_OK)
@@ -610,7 +608,7 @@ if (sw & SWMASK ('M')) {
if (m >= 0)
return SCPE_ARG;
*val |= (m & 03) << 12;
if (*cptr == '/') {
if (*cptr == '/') {
cptr++;
n = get_uint(cptr, 8, 077777, &r);
if (r != SCPE_OK)
@@ -621,7 +619,7 @@ if (sw & SWMASK ('M')) {
case TYPE_C: /* OP x m/c+n or OP X /c+n */
if (m > 0)
*val |= (m & 03) << 12;
if (*cptr == '/') {
if (*cptr == '/') {
cptr++;
for (i = 0; i< 4; i++) {
if (type_c[i] == *cptr) {
@@ -629,7 +627,7 @@ if (sw & SWMASK ('M')) {
break;
}
}
if (*cptr != '+')
if (*cptr != '+')
return SCPE_ARG;
cptr++;
n = get_uint(cptr, 8, 01777, &r);
@@ -646,7 +644,7 @@ if (sw & SWMASK ('M')) {
}
if (m >= 0 || x >= 0)
return SCPE_ARG;
if (*cptr == '/') {
if (*cptr == '/') {
cptr++;
n = get_uint(cptr, 8, 077777, &r);
if (r != SCPE_OK)

View File

@@ -91,7 +91,7 @@
* p101xxxx Alpha + 11xxxx xxxx < 4
* p110xxxx Beta + 10xxxx
* p111xxxx Beta + 11xxxx xxxx < 4
*
*
* Two modes Alpha and Beta. Delta is always output.
*
* Graphics mode translation.
@@ -162,7 +162,7 @@ void ptp_cmd(int dev, uint32 cmd, uint32 *resp) {
*resp = 0;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTP; i++) {
for (i = 0; i < ptp_dev.numunits; i++) {
if (GET_UADDR(ptp_unit[i].flags) == dev) {
uptr = &ptp_unit[i];
break;
@@ -183,7 +183,7 @@ void ptp_cmd(int dev, uint32 cmd, uint32 *resp) {
cmd &= 077;
switch(cmd & 070) {
case 010: /* Command */
if ((uptr->flags & UNIT_ATT) == 0)
if ((uptr->flags & UNIT_ATT) == 0)
break;
if (uptr->CMD & BUSY) {
*resp = 3;
@@ -200,13 +200,13 @@ void ptp_cmd(int dev, uint32 cmd, uint32 *resp) {
break;
case 020: if (cmd == 020) { /* Send Q */
if ((uptr->flags & UNIT_ATT) == 0)
if ((uptr->flags & UNIT_ATT) == 0)
*resp = 040;
if (uptr->STATUS & 06)
*resp = 040;
*resp |= uptr->STATUS & TERMINATE;
} else if (cmd == 024) { /* Send P */
if ((uptr->flags & UNIT_ATT) != 0)
if ((uptr->flags & UNIT_ATT) != 0)
*resp = (uptr->STATUS & ERROR) | 1;
uptr->STATUS = 0;
chan_clr_done(GET_UADDR(uptr->flags));
@@ -219,7 +219,7 @@ void ptp_cmd(int dev, uint32 cmd, uint32 *resp) {
}
break;
default:
default:
break;
}
}
@@ -238,7 +238,7 @@ void ptp_nsi_cmd(int dev, uint32 cmd) {
UNIT *uptr = NULL;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTP; i++) {
for (i = 0; i < ptp_dev.numunits; i++) {
if (GET_UADDR(ptp_unit[i].flags) == dev) {
uptr = &ptp_unit[i];
break;
@@ -296,7 +296,7 @@ void ptp_nsi_status(int dev, uint32 *resp) {
*resp = 0;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTP; i++) {
for (i = 0; i < ptp_dev.numunits; i++) {
if (GET_UADDR(ptp_unit[i].flags) == dev) {
uptr = &ptp_unit[i];
break;
@@ -373,7 +373,7 @@ t_stat ptp_svc (UNIT *uptr)
if (uptr->CMD & DELTA_MODE) {
uptr->CMD &= ~DELTA_MODE;
data = ch;
if (ch & 040)
if (ch & 040)
data |= 0174 ^ ((ch & 020) << 1);
} else if (uptr->CMD & ALPHA_MODE) {
data = ch & 017;
@@ -391,7 +391,7 @@ t_stat ptp_svc (UNIT *uptr)
case 0040: data |= 0140; break;
case 0060: data |= 0160; break;
}
}
}
}
}
if (data != 0) {
@@ -402,7 +402,7 @@ t_stat ptp_svc (UNIT *uptr)
ch = ch ^ (ch << 2);
ch = ch ^ (ch << 1);
data |= ch;
}
}
fputc(data, uptr->fileref);
uptr->pos = ftell(uptr->fileref);
if (ferror (uptr->fileref)) {

View File

@@ -93,7 +93,7 @@
* p101xxxx Alpha + 11xxxx xxxx < 4
* p110xxxx Beta + 10xxxx
* p111xxxx Beta + 11xxxx xxxx < 4
*
*
* Two modes Alpha and Beta. Delta is always output.
*
* Graphics mode translation.
@@ -165,7 +165,7 @@ void ptr_cmd(int dev, uint32 cmd, uint32 *resp) {
*resp = 0;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTR; i++) {
for (i = 0; i < ptr_dev.numunits; i++) {
if (GET_UADDR(ptr_unit[i].flags) == dev) {
uptr = &ptr_unit[i];
break;
@@ -180,12 +180,12 @@ void ptr_cmd(int dev, uint32 cmd, uint32 *resp) {
if (NSI_TYPE(uptr->flags))
return;
if ((uptr->flags & UNIT_ATT) == 0)
if ((uptr->flags & UNIT_ATT) == 0)
return;
cmd &= 077;
switch(cmd & 070) {
case 010: /* Command */
if ((uptr->flags & UNIT_ATT) == 0)
if ((uptr->flags & UNIT_ATT) == 0)
break;
if (uptr->CMD & BUSY) {
*resp = 3;
@@ -201,13 +201,13 @@ void ptr_cmd(int dev, uint32 cmd, uint32 *resp) {
break;
case 020: if (cmd == 020) { /* Send Q */
if ((uptr->flags & UNIT_ATT) != 0)
if ((uptr->flags & UNIT_ATT) != 0)
*resp = 040;
if (uptr->STATUS & 06)
*resp = 040;
*resp |= uptr->STATUS & TERMINATE;
} else if (cmd == 024) { /* Send P */
if ((uptr->flags & UNIT_ATT) != 0)
if ((uptr->flags & UNIT_ATT) != 0)
*resp = (uptr->STATUS & ERROR) | 1;
uptr->STATUS = 0;
chan_clr_done(GET_UADDR(uptr->flags));
@@ -220,7 +220,7 @@ void ptr_cmd(int dev, uint32 cmd, uint32 *resp) {
}
break;
default:
default:
break;
}
}
@@ -240,7 +240,7 @@ void ptr_nsi_cmd(int dev, uint32 cmd) {
UNIT *uptr = NULL;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTR; i++) {
for (i = 0; i < ptr_dev.numunits; i++) {
if (GET_UADDR(ptr_unit[i].flags) == dev) {
uptr = &ptr_unit[i];
break;
@@ -276,7 +276,7 @@ void ptr_nsi_cmd(int dev, uint32 cmd) {
uptr->CMD |= STOP_CHAR;
if (cmd & 020)
uptr->CMD |= BIN_MODE;
if ((cmd & 040) == 0)
if ((cmd & 040) == 0)
uptr->CMD |= IGN_BLNK;
uptr->CMD |= BUSY;
uptr->STATUS = 0;
@@ -300,7 +300,7 @@ void ptr_nsi_status(int dev, uint32 *resp) {
*resp = 0;
/* Find the unit from dev */
for (i = 0; i < NUM_DEVS_PTR; i++) {
for (i = 0; i < ptr_dev.numunits; i++) {
if (GET_UADDR(ptr_unit[i].flags) == dev) {
uptr = &ptr_unit[i];
break;
@@ -352,7 +352,7 @@ t_stat ptr_svc (UNIT *uptr)
if ((uptr->CMD & STOP_CHAR) != 0 && uptr->HOLD == 032)
uptr->STATUS |= TERMINATE;
}
/* Read next charater */
if ((uptr->flags & UNIT_ATT) == 0 ||
feof(uptr->fileref) ||
@@ -369,10 +369,10 @@ t_stat ptr_svc (UNIT *uptr)
ch = data ^ (data >> 4);
ch = ch ^ (ch >> 2);
ch = ch ^ (ch >> 1);
if (ch != 0)
if (ch != 0)
uptr->STATUS = TERMINATE | ERROR;
chan_set_done(GET_UADDR(uptr->flags));
}
}
data &= 0177;
if ((data == 0 || data == 0177) && (uptr->CMD & IGN_BLNK) != 0) {
sim_activate (uptr, uptr->wait); /* try again */
@@ -423,7 +423,7 @@ t_stat ptr_svc (UNIT *uptr)
break;
}
case 0100:
if ((uptr->CMD & 1) == BETA_MODE)
if ((uptr->CMD & 1) == BETA_MODE)
shift = ALPHA_SHIFT;
uptr->CMD |= ALPHA_MODE;
ch = 040 | (data & 037);
@@ -435,7 +435,7 @@ t_stat ptr_svc (UNIT *uptr)
break;
}
case 0120:
if ((uptr->CMD & 1) == ALPHA_MODE)
if ((uptr->CMD & 1) == ALPHA_MODE)
shift = BETA_SHIFT;
uptr->CMD &= ~ALPHA_MODE;
ch = 040 | (data & 037);
@@ -498,7 +498,7 @@ ptr_boot(int32 unit_num, DEVICE * dptr)
M[64 + chan] = 0;
M[256 + 4 * chan] = 0;
M[257 + 4 * chan] = 020;
M[257 + 4 * chan] = 0;
loading = 1;
uptr->CMD = BUSY|ALPHA_MODE|BIN_MODE|IGN_BLNK;
sim_activate (uptr, uptr->wait);

View File

@@ -10,7 +10,7 @@
#define TAPE_IRG 0200
#define BCD_TM 017
unsigned char buffer[TAPE_BUFFER_SIZE];
char *xlat; /* Pointer to translate table */
int eor = 0; /* Report eor */
@@ -125,7 +125,7 @@ int read_tape(FILE *f, int *len) {
*len = -1;
return 1;
}
if (lastchar != 0xff)
if (lastchar != 0xff)
buffer[sz++] = lastchar;
lastchar = 0xff;
while(fread(&ch, sizeof(unsigned char), 1, f) == 1) {
@@ -146,7 +146,7 @@ int read_tape(FILE *f, int *len) {
} else {
unsigned char xlen[4];
int i;
if (fread(&xlen, sizeof(unsigned char), 4, f) != 4)
if (fread(&xlen, sizeof(unsigned char), 4, f) != 4)
return 0;
/* Convert to number */
sz = xlen[0];
@@ -269,27 +269,14 @@ int main(int argc, char *argv[]) {
}
/* Process records of the file */
while(read_tape(tape, &sz)) {
if (sz == -2)
if (sz == -2)
break;
if (sz == -1) {
puts("*EOF*");
write_mark(otape);
} else {
// p = buffer;
// col = 0;
// for(i = 0; i < sz; i++) {
// char ch = *p++;
// if (parity_table[ch & 077] == (ch & 0100))
// col ++;
// }
// if (col == sz) {
// p = buffer;
// for(i = 0; i < sz; i++)
// putchar(xlat[*p++ & 077]);
// putchar('\n');
// } else
for (i = 0; i < sz; i+=3)
printf("%08o ", (buffer[i] << 16) | (buffer[i+1] << 8) | buffer[i+2]);
for (i = 0; i < sz; i+=3)
printf("%08o ", (buffer[i] << 16) | (buffer[i+1] << 8) | buffer[i+2]);
printf("\n");
write_block(otape, sz, buffer);
}