mirror of
https://github.com/open-simh/simh.git
synced 2026-04-10 23:01:39 +00:00
Release V3.12-5
This commit is contained in:
Binary file not shown.
@@ -114,20 +114,32 @@
|
||||
108. DP: TIO status routine always returns DVS_AUTO instead of proper status.
|
||||
109. DP: DP_SEEK definition is off by 1.
|
||||
110. DP: reset does not properly initialize controller, seek threads.
|
||||
111. DP: device address must include unit identifier everywhere, for interrupt generation.
|
||||
112. DK: device address must include unit identifier everywhere, for interrupt generation.
|
||||
113. MT: device address must include unit identifier everywhere, for interrupt generation.
|
||||
114: RAD: device address must include unit identifier everywhere, for interrupt generation.
|
||||
115. MT: error handling not consistent.
|
||||
116: IO: dangling else in write direct mode 1 code causes incorrect behavior.
|
||||
117: CPU: sim_interval is decremented before breakpoint test, which is incorrect.
|
||||
118. MT: revised error handling failed to set tape mark status on space file forward/reverse.
|
||||
119. IO: UEND flag in the wrong bit position in status word.
|
||||
120. DP: SEEK(I), RECAL(I) must be coded as fast operations.
|
||||
121. COC: Transmit long space is 0x6, and stop transmit is 0xE.
|
||||
122. COC: Received break generates a data-in channel transaction with a flag bit set
|
||||
111. DP, DK, MT, RAD: device address must include unit identifier everywhere, for interrupt generation.
|
||||
112. MT: error handling not consistent.
|
||||
113: IO: dangling else in write direct mode 1 code causes incorrect behavior.
|
||||
114: CPU: sim_interval is decremented before breakpoint test, which is incorrect.
|
||||
115. MT: revised error handling failed to set tape mark status on space file forward/reverse.
|
||||
116. IO: UEND flag in the wrong bit position in status word.
|
||||
117. DP: SEEK(I), RECAL(I) must be coded as fast operations.
|
||||
118. COC: Transmit long space is 0x6, and stop transmit is 0xE.
|
||||
119. COC: Received break generates a data-in channel transaction with a flag bit set
|
||||
in the line number.
|
||||
123. DP: dp_inv_adr error must set a TDV visible flag (i.e., PGE) before UEND.
|
||||
120. DP: dp_inv_adr error must set a TDV visible flag (i.e., PGE) before UEND.
|
||||
121. IO, all devices: moved SIO reject-on-interrupt test to devices.
|
||||
122. DP: SIO will knock down pending device interrupts and allow operation to proceed.
|
||||
123. MT: AIO must mask unit number before calling TDV status.
|
||||
124. IO: location 20/21 set incorrectly in the even, non-zero register case.
|
||||
125. CPU: WAIT must be implemented for correct operation of CP-V.
|
||||
126. DP: On 10 byte models, SENSE length errors can't happen. On 16 byte models,
|
||||
SENSE length errors only occur if length == 0 || length > 16.
|
||||
127. IO: DVT_NOTDEV macro incorrect.
|
||||
128. DP, DK, MT, RAD: Test for non-existent device returns wrong status.
|
||||
129. DP, DK, MT: TIO status should return non-operational for unattached device.
|
||||
130. IO: Device mapping algorithm creates false dispatch points.
|
||||
131. All devices: dispatch time to INIT state must be 0.
|
||||
132. LPT: device must flag illegal commands in IDLE state.
|
||||
133. COC: must flag 0xFF as illegal command in IDLE state.
|
||||
134. IO: multiplexor channel implements a "chain modifier" capability, needed by punch.
|
||||
|
||||
Diagnostic Notes
|
||||
----------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_coc.c: Sigma character-oriented communications subsystem simulator
|
||||
|
||||
Copyright (c) 2007-2022, Robert M Supnik
|
||||
Copyright (c) 2007-2024, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
coc 7611 communications multiplexor
|
||||
|
||||
17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
Detect and UEN on 0xFF order
|
||||
15-Dec-22 RMS Moved SIO int pending test to devices
|
||||
24-Aug-22 RMS Transmit long space is 0x6, not 0xD (Ken Rector)
|
||||
Added LNORDER modifier
|
||||
*/
|
||||
@@ -277,9 +280,11 @@ switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = mux_tio_status (); /* get status */
|
||||
if ((*dvst & DVS_CST) == 0) { /* ctrl idle? */
|
||||
if (chan_chk_dvi (dva)) /* int pending? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
else if ((*dvst & DVS_CST) == 0) { /* ctrl idle? */
|
||||
muxc_cmd = MUXC_INIT; /* start dev thread */
|
||||
sim_activate (&mux_unit[MUXC], chan_ctl_time);
|
||||
sim_activate (&mux_unit[MUXC], 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -403,7 +408,11 @@ else { /* receive */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unit service - channel overhead */
|
||||
/* Unit service - channel overhead
|
||||
|
||||
The documentation says that the channel command is thrown away,
|
||||
but the system exerciser requires a UEN on command 0xFF.
|
||||
*/
|
||||
|
||||
t_stat muxc_svc (UNIT *uptr)
|
||||
{
|
||||
@@ -415,6 +424,10 @@ if (muxc_cmd == MUXC_INIT) { /* init state? */
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
mux_chan_err (st); /* go idle */
|
||||
else muxc_cmd = MUXC_RCV; /* no, receive */
|
||||
if (cmd == 0xFF) { /* invalid cmd? */
|
||||
chan_uen (mux_dib.dva); /* uend */
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
else if (muxc_cmd == MUXC_END) { /* end state? */
|
||||
st = chan_end (mux_dib.dva); /* set channel end */
|
||||
|
||||
337
sigma/sigma_cp.c
Normal file
337
sigma/sigma_cp.c
Normal file
@@ -0,0 +1,337 @@
|
||||
/* sigma_cp.c Sigma 7160 Card Punch
|
||||
|
||||
Copyright (c) 2024, Ken Rector
|
||||
|
||||
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
|
||||
KEN RECTOR 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 Ken Rector shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Ken Rector.
|
||||
|
||||
cp 7160 300 cpm card punch
|
||||
|
||||
The 7160 card punch is described in the SDS Reference Manual, 900971A.
|
||||
|
||||
The simulator writes 120 byte records to the cp attached output file. There
|
||||
is no control or formatting meta data included in the file.
|
||||
|
||||
Output requests in EBCDIC mode produce hollerith encoded card images.
|
||||
Output in binary mode produces column binary card images.
|
||||
|
||||
Capacity describes the number of punched cards in the outout stacker. This
|
||||
accumulates indefinitely. It is not reset when the output file is detached.
|
||||
|
||||
*/
|
||||
|
||||
#include "sigma_io_defs.h"
|
||||
|
||||
|
||||
/* Local unit Commands */
|
||||
|
||||
#define CPS_INIT 0x101
|
||||
#define CPS_STOP 0x00 /* stop*/
|
||||
#define CPS_PU01 0x01 /* punch binary normal */
|
||||
#define CPS_PU05 0x05 /* punch ebcdic normal */
|
||||
#define CPS_PU09 0x09 /* punch binary, error alternate */
|
||||
#define CPS_PU0D 0x0d /* punch ebcdic, error alternate */
|
||||
#define CPS_PU11 0x11 /* punch binary, alternate */
|
||||
#define CPS_PU15 0x15 /* punch ebcdic, alternate */
|
||||
#define CPS_PU19 0x19 /* punch binary, alternate */
|
||||
#define CPS_PU1D 0x1d /* punch ebcdic, alternate */
|
||||
#define CPS_STOPI 0x80 /* stop and interrupt */
|
||||
|
||||
|
||||
#define UST u3 /* unit status */
|
||||
#define UCMD u4 /* unit command */
|
||||
|
||||
#define LEN 120 /* output length */
|
||||
|
||||
#define DPS_UEN 0x04 /* unusual end occured */
|
||||
|
||||
char cp_buffer[LEN]; /* card output image */
|
||||
int32 cp_bptr = 0; /* buf ptr */
|
||||
int32 cp_row = 0; /* row counter */
|
||||
int32 cp_stacker1;
|
||||
int32 cp_stacker2;
|
||||
|
||||
uint32 cp_disp(uint32 fnc, uint32 inst, uint32 *dat);
|
||||
uint32 cp_tio_status(void);
|
||||
uint32 cp_tdv_status(void);
|
||||
t_stat cp_chan_err (uint32 st);
|
||||
t_stat cp_svc(UNIT *);
|
||||
t_stat cp_reset (DEVICE *dptr);
|
||||
t_stat cp_attach(UNIT * uptr, CONST char *file);
|
||||
t_stat cp_detach(UNIT * uptr);
|
||||
t_stat cp_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
|
||||
uint8 cp_op[] = {
|
||||
1, 1, 0, 0, 0, 1, 0, 0,
|
||||
0, 1, 0, 0, 0, 1, 0, 0,
|
||||
0, 1, 0, 0, 0, 1, 0, 0,
|
||||
0, 1, 0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1
|
||||
};
|
||||
|
||||
|
||||
extern uint32 chan_ctl_time;
|
||||
extern uint16 ebcdic_to_hol[];
|
||||
|
||||
dib_t cp_dib = { DVA_CP, cp_disp, 0, NULL };
|
||||
|
||||
UNIT cp_unit = {UDATA(&cp_svc, UNIT_ATTABLE , 0), 2000 };
|
||||
|
||||
MTAB cp_mod[] = {
|
||||
{MTAB_XTD | MTAB_VDV, 0, "CHANNEL", "CHANNEL",
|
||||
&io_set_dvc,&io_show_dvc,NULL},
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "CAPACITY", NULL,
|
||||
NULL, &cp_show_cap, NULL, "Punch stacker Count" },
|
||||
{0}
|
||||
};
|
||||
|
||||
REG cp_reg[] = {
|
||||
{ BRDATA (BUFF, cp_buffer, 8, 8, sizeof(cp_buffer)/sizeof(*cp_buffer)), REG_HRO},
|
||||
{ DRDATA (BPTR, cp_bptr, 18), PV_LEFT },
|
||||
{ DRDATA (POS, cp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE cp_dev = {
|
||||
"CP", &cp_unit, cp_reg, cp_mod,
|
||||
1, 10, 31, 1, 16, 8,
|
||||
NULL, NULL, &cp_reset, NULL, &cp_attach, &cp_detach,
|
||||
&cp_dib, 0
|
||||
};
|
||||
|
||||
/* Card Punch : IO Dispatch rotine*/
|
||||
|
||||
uint32 cp_disp (uint32 op, uint32 dva, uint32 *dvst) {
|
||||
|
||||
switch (op) {
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = cp_tio_status (); /* get status */
|
||||
/* if automatic mode and ready */
|
||||
if ((*dvst & DVS_AUTO) && !sim_is_active(&cp_unit)) {
|
||||
cp_unit.UCMD = CPS_INIT; /* start dev thread */
|
||||
cp_unit.UST = 0;
|
||||
cp_row = 0;
|
||||
sim_activate (&cp_unit, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_TIO: /* test status */
|
||||
*dvst = cp_tio_status (); /* return status */
|
||||
break;
|
||||
|
||||
case OP_TDV: /* test status */
|
||||
*dvst = cp_tdv_status (); /* return status */
|
||||
break;
|
||||
|
||||
case OP_HIO: /* halt I/O */
|
||||
chan_clr_chi (cp_dib.dva); /* clear int */
|
||||
*dvst = cp_tio_status (); /* get status */
|
||||
if ((*dvst & DVS_DST) != 0) { /* busy? */
|
||||
sim_cancel (&cp_unit); /* stop dev thread */
|
||||
cp_unit.UST = DPS_UEN;
|
||||
chan_uen (cp_dib.dva); /* uend */
|
||||
cp_unit.UCMD = 0; /* ctlr idle */
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_AIO: /* acknowledge int */
|
||||
chan_clr_chi (cp_dib.dva); /* clr int*/
|
||||
*dvst = 0; /* no status */
|
||||
break;
|
||||
|
||||
default:
|
||||
*dvst = 0;
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* punch service */
|
||||
t_stat cp_svc(UNIT *uptr) {
|
||||
uint32 cmd;
|
||||
uint32 dva = cp_dib.dva;
|
||||
uint32 st;
|
||||
uint32 i;
|
||||
uint32 c;
|
||||
|
||||
if (uptr->UCMD == CPS_INIT) { /* init state? */
|
||||
st = chan_get_cmd (cp_dib.dva, &cmd); /* get order */
|
||||
if (CHS_IFERR (st))
|
||||
return cp_chan_err (st);
|
||||
if ((cmd > 0x80) ||
|
||||
(cp_op[cmd] == 0)) { /* invalid order? */
|
||||
uptr->UST = DPS_UEN;
|
||||
chan_uen (cp_dib.dva); /* report uend */
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->UCMD = cmd;
|
||||
sim_activate (uptr, chan_ctl_time);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
switch (uptr->UCMD) {
|
||||
case CPS_PU01:
|
||||
case CPS_PU05:
|
||||
case CPS_PU09:
|
||||
case CPS_PU0D:
|
||||
case CPS_PU11:
|
||||
case CPS_PU15:
|
||||
case CPS_PU19:
|
||||
case CPS_PU1D:
|
||||
if (cp_row++ == 11) { /* last row? */
|
||||
memset(cp_buffer,0,sizeof(cp_buffer));
|
||||
if (uptr->UCMD & 0x4) { /* mode? */
|
||||
i = 0; /* ebcdic */
|
||||
while (i < LEN) {
|
||||
st = chan_RdMemB(dva,&c);
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
return cp_chan_err (st);
|
||||
unsigned short int col = ebcdic_to_hol[c]; /* byte and 1/2 */
|
||||
cp_buffer[i++] = (col >> 4) & 0xff;
|
||||
cp_buffer[i] = (col & 0x0f) << 4;
|
||||
if (st == CHS_ZBC) /* end request size? */
|
||||
break;
|
||||
st = chan_RdMemB(dva,&c);
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
return cp_chan_err (st);
|
||||
col = ebcdic_to_hol[c]; /* 1/2 and byte */
|
||||
cp_buffer[i++] |= (col >> 8) & 0xf;
|
||||
cp_buffer[i++] = (col & 0xff);
|
||||
if (st == CHS_ZBC) /* end request size? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < LEN; i++) { /* Binary */
|
||||
st = chan_RdMemB(dva,&c);
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
return cp_chan_err (st);
|
||||
cp_buffer[i] = c;
|
||||
if (st == CHS_ZBC) /* end request size? */
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
sim_fwrite (cp_buffer, LEN, 1, uptr->fileref);
|
||||
cp_stacker1++;
|
||||
chan_set_cm (dva); /* set Chaining Modifier flag */
|
||||
}
|
||||
st = chan_end (dva);
|
||||
uptr->UCMD = CPS_INIT;
|
||||
break;
|
||||
case CPS_STOPI:
|
||||
chan_set_chi(dva,CHI_END); /* interrupt */
|
||||
case CPS_STOP:
|
||||
st = chan_end (dva); /* set channel end */
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
return cp_chan_err (st);
|
||||
return SCPE_OK; /* done */
|
||||
}
|
||||
sim_activate (uptr, chan_ctl_time);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* CP status routine */
|
||||
|
||||
uint32 cp_tio_status (void)
|
||||
{
|
||||
uint32 st;
|
||||
|
||||
st = cp_unit.flags & UNIT_ATT? DVS_AUTO: 0; /* AUTO : MANUAL */
|
||||
if (sim_is_active (&cp_unit)) /* dev busy? */
|
||||
st |= ( DVS_DBUSY | (CC2 << DVT_V_CC));
|
||||
st |= cp_unit.UST; /* uend? */
|
||||
return st;
|
||||
}
|
||||
|
||||
uint32 cp_tdv_status (void)
|
||||
{
|
||||
|
||||
if (cp_unit.flags & UNIT_ATT) /* rdr att? */
|
||||
return cp_unit.UST; /* uend */
|
||||
return CC2 << DVT_V_CC;
|
||||
}
|
||||
|
||||
/* Channel error */
|
||||
|
||||
t_stat cp_chan_err (uint32 st)
|
||||
{
|
||||
cp_unit.UST = DPS_UEN;
|
||||
chan_uen (cp_dib.dva); /* uend */
|
||||
if (st < CHS_ERR)
|
||||
return st;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat cp_reset (DEVICE *dptr)
|
||||
{
|
||||
|
||||
sim_cancel (&cp_unit); /* stop dev thread */
|
||||
cp_bptr = 0;
|
||||
cp_row = 0;
|
||||
chan_reset_dev (cp_dib.dva); /* clr int, active */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Attach routine */
|
||||
|
||||
t_stat cp_attach(UNIT * uptr, CONST char *cptr) {
|
||||
|
||||
return (attach_unit(uptr, cptr));
|
||||
}
|
||||
|
||||
t_stat cp_detach(UNIT * uptr) {
|
||||
|
||||
return (detach_unit(uptr));
|
||||
}
|
||||
|
||||
|
||||
t_stat cp_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc) {
|
||||
int n;
|
||||
|
||||
if ((n = cp_stacker1) == 0)
|
||||
fprintf(st,"stacker empty");
|
||||
else {
|
||||
if (n == 1)
|
||||
fprintf(st,"1 card");
|
||||
else
|
||||
fprintf(st,"%d cards",n);
|
||||
fprintf(st," in stacker");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_cpu.c: XDS Sigma CPU simulator
|
||||
|
||||
Copyright (c) 2007-2008, Robert M Supnik
|
||||
Copyright (c) 2007-2023, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
cpu central processor
|
||||
|
||||
04-May-23 RMS Implement WAIT
|
||||
12-Jul-22 RMS Fix incorrect decrement on breakpoint (Ken Rector)
|
||||
|
||||
The system state for the Sigma CPU is as follows:
|
||||
@@ -174,6 +175,7 @@ uint32 cpu_pdf = 0; /* proc detected fault *
|
||||
uint32 cons_alarm = 0; /* console alarm */
|
||||
uint32 cons_alarm_enb = 0; /* alarm enable */
|
||||
uint32 cons_pcf = 0;
|
||||
uint32 wait_state = 0; /* wait state */
|
||||
uint32 rf_bmax = 4; /* num reg blocks */
|
||||
uint32 exu_lim = 32; /* nested EXU limit */
|
||||
uint32 stop_op = 0; /* stop on ill op */
|
||||
@@ -446,7 +448,8 @@ while (reason == 0) { /* loop until stop */
|
||||
|
||||
if (int_hireq < NO_INT) { /* interrupt req? */
|
||||
uint32 sav_hi, vec, wd, op;
|
||||
|
||||
|
||||
wait_state = 0; /* exit wait state */
|
||||
sav_hi = int_hireq; /* save level */
|
||||
vec = io_ackn_int (int_hireq); /* get vector */
|
||||
if (vec == 0) { /* illegal vector? */
|
||||
@@ -474,7 +477,7 @@ while (reason == 0) { /* loop until stop */
|
||||
}
|
||||
else reason = tr2; /* normal status code */
|
||||
}
|
||||
else { /* normal instruction */
|
||||
else if (wait_state == 0) { /* wait state? skip fetch */
|
||||
if (sim_brk_summ &&
|
||||
sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */
|
||||
reason = STOP_IBKPT; /* stop simulation */
|
||||
@@ -1501,7 +1504,7 @@ switch (op) {
|
||||
if (!io_poss_int ()) /* intr possible? */
|
||||
return STOP_WAITNOINT; /* machine is hung */
|
||||
// put idle here
|
||||
int_hireq = io_eval_int (); /* re-eval intr */
|
||||
wait_state = 1; /* wait for intr */
|
||||
break;
|
||||
|
||||
case OP_AIO: /* acknowledge int */
|
||||
@@ -1539,7 +1542,7 @@ switch (op) {
|
||||
return TR_PRV;
|
||||
if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */
|
||||
return tr;
|
||||
if ((tr = io_tio (rn, bva)) != 0) /* do AIO */
|
||||
if ((tr = io_tio (rn, bva)) != 0) /* do TIO */
|
||||
return tr;
|
||||
int_hireq = io_eval_int (); /* re-eval intr */
|
||||
break;
|
||||
@@ -2513,6 +2516,7 @@ cpu_new_PSD (1, PSW1_DFLT | (PSW1 & PSW1_PCMASK), PSW2_DFLT);
|
||||
cpu_pdf = 0;
|
||||
cons_alarm = 0;
|
||||
cons_pcf = 0;
|
||||
wait_state = 0;
|
||||
set_rf_display (R);
|
||||
if (M == NULL)
|
||||
M = (uint32 *) calloc (MAXMEMSIZE, sizeof (uint32));
|
||||
|
||||
435
sigma/sigma_cr.c
Normal file
435
sigma/sigma_cr.c
Normal file
@@ -0,0 +1,435 @@
|
||||
/* sigma_cr.c: Sigma 7120/7122/7140 card reader
|
||||
|
||||
Copyright (c) 2024, Ken Rector
|
||||
|
||||
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
|
||||
KEN RECTOR 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 Ken Rector shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Ken Rector.
|
||||
|
||||
cr 7120 card reader
|
||||
|
||||
27-Feb-2024 kenr Initial version
|
||||
|
||||
The 7120, 7122 and 7140 card readers are described in the SDS
|
||||
reference manual, 900970C.
|
||||
|
||||
The simulator expects input data to be a file of 120 byte records with no control
|
||||
or other extraneous data, to simulate a punched card deck. Each 120 byte record
|
||||
is translated to 80 16 bit columns with data in the loworder 12 bits. In
|
||||
automatic mode each column (1-1/2 bytes) is translated from a hollerith code
|
||||
to an ebcdic character (1 byte). In binary mode each pair of columns is
|
||||
translated to 3 data bytes.
|
||||
|
||||
A length error in the input data will not be detected until the end of file
|
||||
and results in an Invalid Length and Unusual End status. CPV sets the ignore
|
||||
incorrect length flag so this can cause trouble in the symbiont input process.
|
||||
|
||||
Card reader speed for the 7120, 7122 and 7140 machines was 400, 400 and 1500
|
||||
cards per minute respectively, or 150, 150 and 40 msec per card. The simulator
|
||||
runs much faster than this, transmitting 80 columns in ~400 instruction cycles,
|
||||
or 5 cycles per column.
|
||||
|
||||
The cr device capacity indicates the number of cards in the hopper and stacker.
|
||||
There is no limit on the number of records in the hopper or stacker. The
|
||||
stacker is never emptied and the count can overflow. The hopper counter is
|
||||
set when a file is attached and reduced as each card is read.
|
||||
|
||||
The cardreader is detached from the input file when the hopper count
|
||||
reaches zero.
|
||||
|
||||
The card reader reports a Data Transmission Error if an incorrect EBCDIC character
|
||||
is detected, (more than 1 punch in rows 1-7).
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "sigma_io_defs.h"
|
||||
|
||||
|
||||
/* Unit status */
|
||||
|
||||
#define CDR_DTE 0x08 /* data error */
|
||||
|
||||
/* Device States */
|
||||
|
||||
#define CRS_INIT 0x101 /* feed card */
|
||||
#define CRS_END 0x102 /* end card */
|
||||
|
||||
#define UST u3 /* unit status */
|
||||
#define UCMD u4 /* unit command */
|
||||
|
||||
uint32 cr_bptr; /* buffer index */
|
||||
uint32 cr_blnt; /* buffer length */
|
||||
uint32 cr_col; /* current column */
|
||||
uint32 cr_hopper; /* hopper count */
|
||||
uint32 *cr_stkptr; /* selected stacker */
|
||||
uint32 cr_stacker = 0; /* stacker count */
|
||||
uint32 cr_stacker1 = 0; /* stacker 1 count */
|
||||
uint32 cr_stacker2 = 0; /* stacker 2 count */
|
||||
uint16 cr_buffer[80]; /* 80 column data */
|
||||
uint32 cr_ebcdic_init = 0; /* translate initial flag */
|
||||
uint16 hol_to_ebcdic[4096]; /* translation table */
|
||||
|
||||
uint8 cr_ord[] = { /* valid order codes*/
|
||||
0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0, 0, 1, 0
|
||||
};
|
||||
|
||||
extern uint32 chan_ctl_time;
|
||||
extern uint16 ebcdic_to_hol[];
|
||||
|
||||
|
||||
uint32 cr_disp (uint32 op, uint32 dva, uint32 *dvst);
|
||||
t_stat cr_readrec (UNIT *uptr);
|
||||
uint32 cr_tio_status (void);
|
||||
uint32 cr_tdv_status (void);
|
||||
t_stat cr_chan_err (uint32 st);
|
||||
t_stat cr_svc (UNIT *uptr);
|
||||
t_stat cr_reset (DEVICE *dptr);
|
||||
t_stat cr_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat cr_detach (UNIT *uptr);
|
||||
t_stat cr_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
|
||||
|
||||
dib_t cr_dib = { DVA_CR, cr_disp, 0, NULL };
|
||||
|
||||
UNIT cr_unit = {
|
||||
UDATA(&cr_svc, UNIT_ATTABLE | UNIT_RO , 0),
|
||||
60
|
||||
};
|
||||
|
||||
REG cr_reg[] = {
|
||||
{ DRDATA (BPTR, cr_bptr, 17), PV_LEFT },
|
||||
{ DRDATA (BLNT, cr_blnt, 17), PV_LEFT },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB cr_mod[] = {
|
||||
{MTAB_XTD | MTAB_VDV, 0, "CHANNEL", "CHANNEL",
|
||||
&io_set_dvc,&io_show_dvc,NULL},
|
||||
{MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA",
|
||||
&io_set_dva, &io_show_dva, NULL },
|
||||
{MTAB_XTD|MTAB_VDV, 0, "CAPACITY", NULL,
|
||||
NULL, &cr_show_cap, NULL, "Card hopper size" },
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE cr_dev = {
|
||||
"CR", &cr_unit, cr_reg, cr_mod,
|
||||
1, 10, 31, 1, 16, 8,
|
||||
NULL, NULL, &cr_reset, &io_boot,&cr_attach,&cr_detach,
|
||||
&cr_dib, 0
|
||||
};
|
||||
|
||||
|
||||
/* Card Reader : IO dispatch routine */
|
||||
|
||||
uint32 cr_disp (uint32 op, uint32 dva, uint32 *dvst)
|
||||
{
|
||||
switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = cr_tio_status (); /* get status */
|
||||
if ((*dvst & DVS_AUTO) && !sim_is_active(&cr_unit)) {
|
||||
cr_unit.UCMD = CRS_INIT; /* start dev thread */
|
||||
cr_stkptr = &cr_stacker;
|
||||
sim_activate (&cr_unit, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_TIO: /* test status */
|
||||
*dvst = cr_tio_status (); /* return status */
|
||||
break;
|
||||
|
||||
case OP_TDV: /* test status */
|
||||
*dvst = cr_tdv_status (); /* return status */
|
||||
break;
|
||||
|
||||
case OP_HIO: /* halt I/O */
|
||||
chan_clr_chi (cr_dib.dva); /* clear int */
|
||||
*dvst = cr_tio_status ();
|
||||
if ((*dvst & DVS_DST) != 0) { /* busy? */
|
||||
sim_cancel (&cr_unit); /* stop dev thread */
|
||||
chan_uen (cr_dib.dva); /* uend */
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_AIO: /* acknowledge int */
|
||||
chan_clr_chi (cr_dib.dva); /* clr int*/
|
||||
*dvst = 0; /* no status */
|
||||
break;
|
||||
|
||||
default:
|
||||
*dvst = 0;
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Service routine */
|
||||
|
||||
t_stat cr_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 cmd = uptr->UCMD;
|
||||
t_stat st;
|
||||
char c;
|
||||
|
||||
if (cmd == CRS_INIT) { /* init state */
|
||||
st = chan_get_cmd (cr_dib.dva, &cmd); /* get order */
|
||||
if (CHS_IFERR (st)) /* bad device id, inactive state */
|
||||
return cr_chan_err (st);
|
||||
if ((cmd > 0x3e) || /* invalid order? */
|
||||
(cr_ord[cmd] == 0)) {
|
||||
chan_uen (cr_dib.dva);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->UCMD = cmd; /* save order */
|
||||
cr_blnt = 0; /* empty buffer */
|
||||
cr_col = 0; /* initial column */
|
||||
switch (cmd & 0x30) { /* note stacker */
|
||||
case 0x10:
|
||||
cr_stkptr = &cr_stacker1;
|
||||
break;
|
||||
case 0x30:
|
||||
cr_stkptr = &cr_stacker2;
|
||||
break;
|
||||
default:
|
||||
cr_stkptr = &cr_stacker;
|
||||
break;
|
||||
}
|
||||
sim_activate (uptr, chan_ctl_time);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (cmd == CRS_END) { /* end of card */
|
||||
st = chan_end (cr_dib.dva); /* set channel end, inactive */
|
||||
if (CHS_IFERR (st)) /* bad dev/inactive? */
|
||||
return cr_chan_err (st);
|
||||
++*cr_stkptr; /* add to stacker */
|
||||
if (--cr_hopper == 0) /* remove from hopper */
|
||||
cr_detach(uptr); /* end input deck */
|
||||
if (st == CHS_CCH) { /* command chain? */
|
||||
uptr->UCMD = CRS_INIT; /* restart thread */
|
||||
sim_activate (uptr, chan_ctl_time);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (cr_blnt == 0) { /* card arriving? */
|
||||
if (cr_readrec (uptr) == 0) { /* unexpected EOF, inv reclnt? */
|
||||
uptr->UCMD = CRS_END; /* end state */
|
||||
sim_activate (uptr, chan_ctl_time); /* sched ctlr */
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((cmd & 0x04) && /* mode change? */
|
||||
((cr_buffer[0] & 0x180) == 0x180)) {
|
||||
cmd &= ~0x04; /* automatic(EBCDIC) and row 1 2 */
|
||||
uptr->UCMD = cmd; /* switch to binary mode */
|
||||
}
|
||||
}
|
||||
if (cmd & 0x04) { /* mode? */
|
||||
c = (char) hol_to_ebcdic[cr_buffer[cr_bptr]]; /* automatic */
|
||||
int i = 0; /* invalid punches? */
|
||||
int n = cr_buffer[cr_bptr++] & 0x1fc;
|
||||
while (n) { /* Kerninghams bit count alg */
|
||||
n &= (n-1); /* count bits in row 1-7 */
|
||||
i++;
|
||||
}
|
||||
if (i > 1) { /* >2 punches? */
|
||||
c = 0x00; /* return 0x00 */
|
||||
uptr->UST |= CDR_DTE; /* Transmission Data Error*/
|
||||
chan_set_chf (cr_dib.dva, CHF_XMDE); /* operational status byte */
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (cr_col % 3) { /* binary */
|
||||
case 0:
|
||||
c = ((cr_buffer[cr_bptr] >> 4) & 0xff);
|
||||
break;
|
||||
case 1:
|
||||
c = ((cr_buffer[cr_bptr] & 0x0f) << 4);
|
||||
cr_bptr++;
|
||||
c |= ((cr_buffer[cr_bptr] & 0xf00) >> 8);
|
||||
break;
|
||||
case 2:
|
||||
c = (cr_buffer[cr_bptr++] & 0xff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cr_col++;
|
||||
st = chan_WrMemB (cr_dib.dva, c); /* write to memory */
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
return cr_chan_err (st);
|
||||
if ((st != CHS_ZBC) && (cr_bptr != cr_blnt)) { /* not done? */
|
||||
sim_activate (uptr, chan_ctl_time); /* continue */
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (((st == CHS_ZBC) ^ (cr_bptr == cr_blnt)) && /* length err? */
|
||||
chan_set_chf (cr_dib.dva, CHF_LNTE)) /* Incorrect Length */
|
||||
return SCPE_OK; /* to operational status byte */
|
||||
|
||||
uptr->UCMD = CRS_END; /* end state */
|
||||
sim_activate (uptr, chan_ctl_time); /* sched ctlr */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* get next record */
|
||||
|
||||
t_stat cr_readrec (UNIT *uptr) {
|
||||
|
||||
int col;
|
||||
FILE *fp = uptr->fileref;
|
||||
|
||||
for (col = 0; col < 80; ) {
|
||||
int16 i;
|
||||
int c1, c2, c3;
|
||||
|
||||
c1 = fgetc (fp); /* read 3 bytes */
|
||||
c2 = fgetc (fp);
|
||||
c3 = fgetc (fp);
|
||||
if (feof(fp) || (c1 == EOF) || (c2 == EOF) || (c3 == EOF)) {
|
||||
cr_blnt = cr_bptr = 0;
|
||||
chan_set_chf (cr_dib.dva, CHF_LNTE);
|
||||
return 0;
|
||||
}
|
||||
i = ((c1 << 4) | ( c2 >> 4)) & 0xFFF; /* pack 1-1/2 bytes per column */
|
||||
cr_buffer[col] = i;
|
||||
col++;
|
||||
i = (((c2 & 017) << 8) | c3) & 0xFFF;
|
||||
cr_buffer[col] = i;
|
||||
col++;
|
||||
}
|
||||
cr_bptr = 0;
|
||||
cr_blnt = 80;
|
||||
return 80;
|
||||
}
|
||||
|
||||
|
||||
/* CR status routine */
|
||||
|
||||
uint32 cr_tio_status (void)
|
||||
{
|
||||
uint32 st;
|
||||
|
||||
st = (cr_unit.flags & UNIT_ATT) ? DVS_AUTO: 0; /* AUTO : MANUAL */
|
||||
if (sim_is_active (&cr_unit)) /* dev busy? */
|
||||
st |= ( DVS_CBUSY | DVS_DBUSY | (CC2 << DVT_V_CC));
|
||||
return st;
|
||||
}
|
||||
|
||||
uint32 cr_tdv_status (void)
|
||||
{
|
||||
uint32 st;
|
||||
|
||||
if (cr_unit.flags & UNIT_ATT &&
|
||||
(cr_hopper > 0)) /* rdr att? */
|
||||
st = cr_unit.UST;
|
||||
else
|
||||
st = (CC2 << DVT_V_CC);
|
||||
return st;
|
||||
}
|
||||
|
||||
/* Channel error */
|
||||
|
||||
t_stat cr_chan_err (uint32 st)
|
||||
{
|
||||
chan_uen (cr_dib.dva);
|
||||
if (st < CHS_ERR)
|
||||
return st;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat cr_reset (DEVICE *dptr)
|
||||
{
|
||||
if (!cr_ebcdic_init) { /* initialize translate table */
|
||||
for (int i = 0; i < 4096; i++)
|
||||
hol_to_ebcdic[i] = 0x100; /* a la sim_card */
|
||||
for (int i = 0; i < 256; i++) {
|
||||
uint16 temp = ebcdic_to_hol[i];
|
||||
if (hol_to_ebcdic[temp] != 0x100) {
|
||||
fprintf(stderr, "Translation error %02x is %03x and %03x\n",
|
||||
i, temp, hol_to_ebcdic[temp]);
|
||||
} else {
|
||||
hol_to_ebcdic[temp] = i;
|
||||
}
|
||||
}
|
||||
cr_ebcdic_init = 1;
|
||||
}
|
||||
sim_cancel (&cr_unit); /* stop dev thread */
|
||||
chan_reset_dev (cr_dib.dva); /* clr int, active */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Attach routine */
|
||||
|
||||
t_stat cr_attach (UNIT *uptr, CONST char *cptr)
|
||||
{
|
||||
char *saved_filename;
|
||||
int r;
|
||||
|
||||
saved_filename = uptr->filename;
|
||||
uptr->filename = NULL;
|
||||
if ((r = attach_unit(uptr, cptr)) != SCPE_OK) {
|
||||
uptr->filename = saved_filename;
|
||||
return r;
|
||||
}
|
||||
r = sim_fsize(uptr->fileref);
|
||||
if ((r % 120) != 0) { /* multiple of 120 byte cards? */
|
||||
detach_unit(uptr);
|
||||
fprintf(stderr,"CR file size error\n");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
cr_hopper = r / 120;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Detach routine */
|
||||
|
||||
t_stat cr_detach (UNIT *uptr)
|
||||
{
|
||||
cr_hopper = 0;
|
||||
return detach_unit(uptr);
|
||||
}
|
||||
|
||||
t_stat cr_show_cap (FILE *st, UNIT *uptr, int32 val, CONST void *desc) {
|
||||
|
||||
if (cr_hopper == 0)
|
||||
fprintf(st,"hopper empty");
|
||||
else {
|
||||
if (cr_hopper == 1)
|
||||
fprintf(st,"1 card");
|
||||
else
|
||||
fprintf(st,"%d cards",cr_hopper);
|
||||
fprintf(st," in hopper");
|
||||
}
|
||||
fprintf(st,"\nNormal Stacker %d\n",cr_stacker);
|
||||
fprintf(st,"Alt Stacker 1 %d\n",cr_stacker1);
|
||||
fprintf(st,"Alt Stacker 2 %d",cr_stacker2);
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_dk.c: 7250/7251-7252 cartridge disk simulator
|
||||
|
||||
Copyright (c) 2007-2022, Robert M Supnik
|
||||
Copyright (c) 2007-2024, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,10 @@
|
||||
|
||||
dk 7250/7251-7252 cartridge disk
|
||||
|
||||
17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
11-Feb-24 RMS Report non-operational if not attached (Ken Rector)
|
||||
01-Feb-24 RMS Fixed nx unit test (Ken Rector)
|
||||
15-Dec-22 RMS Moved SIO interrupt test to devices
|
||||
02-Jul-22 RMS Fixed bugs in multi-unit operation
|
||||
|
||||
Transfers are always done a sector at a time.
|
||||
@@ -165,15 +169,19 @@ int32 iu;
|
||||
UNIT *uptr;
|
||||
|
||||
if ((un >= DK_NUMDR) || /* inv unit num? */
|
||||
(dk_unit[un].flags & UNIT_DIS)) /* disabled unit? */
|
||||
return DVT_NODEV;
|
||||
(dk_unit[un].flags & UNIT_DIS)) { /* disabled unit? */
|
||||
*dvst = DVT_NODEV;
|
||||
return 0;
|
||||
}
|
||||
switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = dk_tio_status (un); /* get status */
|
||||
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||
if (chan_chk_dvi (dva)) /* int pending? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||
dk_cmd = DKS_INIT; /* start dev thread */
|
||||
sim_activate (&dk_unit[un], chan_ctl_time);
|
||||
sim_activate (&dk_unit[un], 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -411,12 +419,17 @@ return FALSE; /* cmd done */
|
||||
|
||||
uint32 dk_tio_status (uint32 un)
|
||||
{
|
||||
uint32 i;
|
||||
uint32 i, st;
|
||||
|
||||
st = DVS_AUTO; /* flags */
|
||||
if (sim_is_active (&dk_unit[un])) /* active => busy */
|
||||
st |= DVS_DBUSY;
|
||||
else if ((dk_unit[un].flags & UNIT_ATT) == 0) /* not att => offl */
|
||||
st |= DVS_DOFFL;
|
||||
for (i = 0; i < DK_NUMDR; i++) { /* loop thru units */
|
||||
if (sim_is_active (&dk_unit[i])) /* active? */
|
||||
return (DVS_AUTO | DVS_CBUSY | (CC2 << DVT_V_CC) |
|
||||
((i == un)? DVS_DBUSY: 0));
|
||||
st |= (DVS_CBUSY | (CC2 << DVT_V_CC)); /* ctrl is busy */
|
||||
return st;
|
||||
}
|
||||
return DVS_AUTO;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_dp.c: moving head disk pack controller
|
||||
|
||||
Copyright (c) 2008-2022, Robert M Supnik
|
||||
Copyright (c) 2008-2024, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,13 @@
|
||||
|
||||
dp moving head disk pack controller
|
||||
|
||||
05-Apr-24 RMS Added case points for RDEES, CRIOF (Ken Rector)
|
||||
17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
11-Feb-24 RMS Report non-operational if not attached (Ken Rector)
|
||||
01-Feb-24 RMS Fixed nx unit test (Ken Rector)
|
||||
03-Jun-23 RMS Fixed SENSE length error detection (Ken Rector)
|
||||
06-Mar-23 RMS SIO can start despite outstanding seek interrupt (Ken Rector)
|
||||
15-Dec-22 RMS Moved SIO interrupt test to devices
|
||||
09-Dec-22 RMS Invalid address must set a TDV-visible error flag (Ken Rector)
|
||||
23-Jul-22 RMS SEEK(I), RECAL(I) should be fast operations (Ken Rector)
|
||||
02-Jul-22 RMS Fixed bugs in multi-unit operation
|
||||
@@ -47,6 +54,16 @@
|
||||
one for timing asynchronous seek completions. The controller will not
|
||||
start a new operation is it is busy (any of the main units active) or if
|
||||
the target device is busy (its seek unit is active).
|
||||
|
||||
The DP's seek interrupt has a unique feature: it comes and goes, lasting only
|
||||
a sector's time; and it gets "knocked down" by any SIO to a different unit.
|
||||
Therefore, the SIO interrupt check is complicated.
|
||||
|
||||
1. If there's a controller interrupt, the SIO fails.
|
||||
2. If there's a seek interrupt on the selected unit, the SIO fails.
|
||||
3. All other seek interrupts are "knocked down" and rescheduled for
|
||||
some time "in the future."
|
||||
4. The SIO completes normally.
|
||||
*/
|
||||
|
||||
#include "sigma_io_defs.h"
|
||||
@@ -577,22 +594,39 @@ int32 iu;
|
||||
uint32 i;
|
||||
DP_CTX *ctx;
|
||||
|
||||
if (cidx >= DP_NUMCTL) /* inv ctrl num? */
|
||||
return DVT_NODEV;
|
||||
if (cidx >= DP_NUMCTL) { /* inv ctrl num? */
|
||||
*dvst = DVT_NODEV;
|
||||
return 0;
|
||||
}
|
||||
ctx = &dp_ctx[cidx];
|
||||
if (((un < DP_NUMDR) && /* un valid and */
|
||||
((dp_unit[un].flags & UNIT_DIS) == 0)) || /* not disabled OR */
|
||||
((un == 0xF) && (ctx->dp_ctype == DP_C3281))) /* 3281 unit F? */
|
||||
uptr = dp_unit + un; /* un exists */
|
||||
else return DVT_NODEV;
|
||||
else {
|
||||
*dvst = DVT_NODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = dp_tio_status (cidx, un); /* get status */
|
||||
if ((chan_chk_chi (dva) >= 0) || /* channel int pending? */
|
||||
(dp_ctx[cidx].dp_ski & (1u << un))) { /* seek int on sel unit? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < DP_NUMDR; i++) { /* knock down other seek ints */
|
||||
if (dp_ctx[cidx].dp_ski & (1u << i)) { /* seek int on unit? */
|
||||
dp_clr_ski (cidx, i); /* knock it down */
|
||||
sim_activate (&dp_unit[i + DP_SEEK], chan_ctl_time * 10);
|
||||
dp_unit[i + DP_SEEK].UCMD = DSC_SEEKW; /* resched interrupt */
|
||||
}
|
||||
}
|
||||
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||
uptr->UCMD = DPS_INIT; /* start dev thread */
|
||||
sim_activate (uptr, chan_ctl_time);
|
||||
sim_activate (uptr, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -759,7 +793,7 @@ switch (uptr->UCMD) {
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
return dp_chan_err (dva, st);
|
||||
}
|
||||
if ((i != DPS_NBY) || (st != CHS_ZBC)) { /* length error? */
|
||||
if (!DP_Q10B (ctx->dp_ctype) && (st != CHS_ZBC)) { /* 16B only: length error? */
|
||||
ctx->dp_flags |= DPF_PGE; /* set prog err */
|
||||
if (chan_set_chf (dva, CHF_LNTE)) /* do we care? */
|
||||
return SCPE_OK;
|
||||
@@ -852,6 +886,7 @@ switch (uptr->UCMD) {
|
||||
return SCPE_OK; /* err or cont */
|
||||
break;
|
||||
|
||||
case DPS_RDEES: /* read */
|
||||
case DPS_READ: /* read */
|
||||
if (dp_inv_ad (uptr, &da)) { /* invalid addr? */
|
||||
ctx->dp_flags |= DPF_PGE;
|
||||
@@ -903,6 +938,7 @@ switch (uptr->UCMD) {
|
||||
return SCPE_OK;
|
||||
break;
|
||||
|
||||
case DPS_CRIOF: /* cond rls intr */
|
||||
case DPS_RSRV: /* reserve */
|
||||
case DPS_RLS: /* release */
|
||||
case DPS_RLSA: /* release */
|
||||
@@ -974,21 +1010,23 @@ return FALSE; /* cmd done */
|
||||
|
||||
uint32 dp_tio_status (uint32 cidx, uint32 un)
|
||||
{
|
||||
uint32 i;
|
||||
uint32 i, st;
|
||||
DP_CTX *ctx = &dp_ctx[cidx];
|
||||
UNIT *dp_unit = dp_dev[cidx].units;
|
||||
uint32 stat = DVS_AUTO;
|
||||
|
||||
st = DVS_AUTO;
|
||||
if (sim_is_active (&dp_unit[un]) ||
|
||||
sim_is_active (&dp_unit[un + DP_SEEK]))
|
||||
st |= (DVS_DBUSY | (CC2 << DVT_V_CC));
|
||||
else if ((un != 0xF) && ((dp_unit[un].flags & UNIT_ATT) == 0))
|
||||
st |= DVS_DOFFL;
|
||||
for (i = 0; i < DP_NUMDR; i++) {
|
||||
if (sim_is_active (&dp_unit[i])) {
|
||||
stat |= (DVS_CBUSY | (CC2 << DVT_V_CC));
|
||||
st |= (DVS_CBUSY | (CC2 << DVT_V_CC));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sim_is_active (&dp_unit[un]) ||
|
||||
sim_is_active (&dp_unit[un + DP_SEEK]))
|
||||
stat |= (DVS_DBUSY | (CC2 << DVT_V_CC));
|
||||
return stat;
|
||||
return st;
|
||||
}
|
||||
|
||||
uint32 dp_tdv_status (uint32 cidx, uint32 un)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_io.c: XDS Sigma IO simulator
|
||||
|
||||
Copyright (c) 2007-2022, Robert M Supnik
|
||||
Copyright (c) 2007-2024, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -23,6 +23,10 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
19-Mar-2024 RMS Added chaining modifier flag (Ken Rector)
|
||||
11-Feb-2024 RMS Fixed false dispatch bug (Ken Rector)
|
||||
04-May-2023 RMS Fixed location 21 usage in even register case (Ken Rector)
|
||||
15-Dec-2022 RMS Moved SIO interrupt test to devices
|
||||
23-Jul-2022 RMS Made chan_ctl_time accessible as a register
|
||||
21-Jul-2022 RMS Added numeric channel numbers to SET/SHOW
|
||||
07-Jul-2022 RMS Fixed dangling else in read/write direct (Ken Rector)
|
||||
@@ -353,11 +357,6 @@ if (!io_init_inst (rn, ad, ch, dev, R[0])) { /* valid inst? */
|
||||
CC |= CC1|CC2;
|
||||
return 0;
|
||||
}
|
||||
if (chan[ch].chf[dev] & CHF_INP) { /* int pending? */
|
||||
chan[ch].disp[dev] (OP_TIO, ad, &dvst); /* get status */
|
||||
CC |= (CC2 | io_set_status (rn, ch, dev, dvst, 0)); /* set status */
|
||||
return 0;
|
||||
}
|
||||
st = chan[ch].disp[dev] (OP_SIO, ad, &dvst); /* start I/O */
|
||||
CC |= io_set_status (rn, ch, dev, dvst, 0); /* set status */
|
||||
if (CC & cpu_tab[cpu_model].iocc) /* error? */
|
||||
@@ -365,6 +364,7 @@ if (CC & cpu_tab[cpu_model].iocc) /* error? */
|
||||
chan[ch].chf[dev] = 0; /* clear flags */
|
||||
chan[ch].chi[dev] = 0; /* clear intrs */
|
||||
chan[ch].chsf[dev] |= CHSF_ACT; /* set chan active */
|
||||
chan[ch].chsf[dev] &= ~CHSF_CM; /* clear chain mod */
|
||||
chan_new_cmd (ch, dev, R[0]); /* new command */
|
||||
return st;
|
||||
}
|
||||
@@ -478,14 +478,27 @@ CC |= CC1|CC2; /* no recognition */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initiate I/O instruction */
|
||||
/* Initiate I/O instruction
|
||||
|
||||
False dispatch problem. Although device numbers are not permitted to overlap,
|
||||
there is nothing to stop programs from issuing IO instructions to a multi-
|
||||
unit device address using its single-unit counterpart, or vice-versa.
|
||||
For example, an IO address of 0x00 will map to the dispatch used for
|
||||
0x80, and vice versa. This routine must detect that the device
|
||||
address actually agrees with the type of device in that dispatch slot.
|
||||
*/
|
||||
|
||||
t_bool io_init_inst (uint32 rn, uint32 ad, uint32 ch, uint32 dev, uint32 r0)
|
||||
{
|
||||
uint32 loc20;
|
||||
t_bool ch_mu, dva_mu;
|
||||
|
||||
if (ch >= chan_num) /* bad chan? */
|
||||
if ((dev >= CHAN_N_DEV) || (ch >= chan_num)) /* bad dev or chan? */
|
||||
return FALSE;
|
||||
ch_mu = (chan[ch].chsf[dev] & CHSF_MU) != 0; /* does chan think MU? */
|
||||
dva_mu = (ad & DVA_MU) != 0; /* is dva MU? */
|
||||
if (ch_mu != dva_mu) /* not the same? */
|
||||
return FALSE; /* dev not there */
|
||||
loc20 = ((ad & 0xFF) << 24) | /* <0:7> = dev ad */
|
||||
((rn & 1) | (rn? 3: 0) << 22) | /* <8:9> = reg ind */
|
||||
(r0 & (cpu_tab[cpu_model].pamask >> 1)); /* <14/16:31> = r0 */
|
||||
@@ -498,17 +511,17 @@ return (chan[ch].disp[dev] != NULL)? TRUE: FALSE;
|
||||
uint32 io_set_status (uint32 rn, uint32 ch, uint32 dev, uint32 dvst, t_bool tdv)
|
||||
{
|
||||
uint32 mrgst;
|
||||
uint32 odd = rn & 1;
|
||||
|
||||
if ((rn != 0) && !(dvst & DVT_NOST)) { /* return status? */
|
||||
if (tdv)
|
||||
mrgst = (DVT_GETDVS (dvst) << 8) | (chan[ch].chf[dev] & 0xFF);
|
||||
else mrgst = ((DVT_GETDVS(dvst) << 8) & ~CHF_ALL) | (chan[ch].chf[dev] & CHF_ALL);
|
||||
R[rn] = chan[ch].clc[dev]; /* even reg */
|
||||
if (!odd) /* even pair? */
|
||||
WritePW (0x20, R[rn]); /* write to 20 */
|
||||
if ((rn & 1) == 0) { /* even reg? */
|
||||
R[rn] = chan[ch].clc[dev]; /* current addr to R */
|
||||
WritePW (0x20, R[rn]); /* and loc 20 */
|
||||
}
|
||||
R[rn|1] = (mrgst << 16) | chan[ch].bc[dev]; /* odd reg */
|
||||
WritePW (0x20 + odd, R[rn|1]); /* write to 20/21 */
|
||||
WritePW (0x21, R[rn|1]); /* write loc 21 */
|
||||
}
|
||||
return DVT_GETCC (dvst);
|
||||
}
|
||||
@@ -533,16 +546,18 @@ return 0;
|
||||
uint32 chan_end (uint32 dva)
|
||||
{
|
||||
uint32 ch, dev;
|
||||
uint32 st;
|
||||
uint32 st, cm;
|
||||
|
||||
if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */
|
||||
return st;
|
||||
if (chan[ch].cmf[dev] & CMF_ICE) /* int on chan end? */
|
||||
chan_set_chi (dva, CHI_END);
|
||||
cm = chan[ch].chsf[dev] & CHSF_CM ? 1 : 0; /* get modifier flag, */
|
||||
chan[ch].chsf[dev] &= ~CHSF_CM; /* then clear it */
|
||||
if ((chan[ch].cmf[dev] & CMF_CCH) && /* command chain? */
|
||||
!chan_new_cmd (ch, dev, chan[ch].clc[dev] + 1)) /* next command? */
|
||||
!chan_new_cmd (ch, dev, chan[ch].clc[dev] + 1 + cm)) /* next command? */
|
||||
return CHS_CCH;
|
||||
else chan[ch].chsf[dev] &= ~CHSF_ACT; /* channel inactive */
|
||||
else chan[ch].chsf[dev] &= ~(CHSF_ACT|CHSF_CM); /* channel inactive */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -600,7 +615,7 @@ if (!VALID_DVA (ch, dev)) /* valid? */
|
||||
if (chan[ch].cmf[dev] & CMF_IUE) /* int on uend? */
|
||||
chan_set_chi (dva, CHI_UEN);
|
||||
chan[ch].chf[dev] |= CHF_UEN; /* flag uend */
|
||||
chan[ch].chsf[dev] &= ~CHSF_ACT;
|
||||
chan[ch].chsf[dev] &= ~(CHSF_ACT|CHSF_CM);
|
||||
return CHS_INACTV; /* done */
|
||||
}
|
||||
|
||||
@@ -749,7 +764,7 @@ for (i = 0; i < 2; i++) { /* max twice */
|
||||
chan[ch].clc[dev] = clc; /* and save */
|
||||
if (ReadPW (clc << 1, &ccw1)) { /* get ccw1, nxm? */
|
||||
chan[ch].chf[dev] |= CHF_IOME; /* memory error */
|
||||
chan[ch].chsf[dev] &= ~CHSF_ACT; /* stop channel */
|
||||
chan[ch].chsf[dev] &= ~(CHSF_ACT|CHSF_CM); /* stop channel */
|
||||
return CHS_INACTV;
|
||||
}
|
||||
ReadPW ((clc << 1) + 1, &ccw2); /* get ccw2 */
|
||||
@@ -765,7 +780,7 @@ for (i = 0; i < 2; i++) { /* max twice */
|
||||
}
|
||||
}
|
||||
chan[ch].chf[dev] |= CHF_IOCE; /* control error */
|
||||
chan[ch].chsf[dev] &= ~CHSF_ACT; /* stop channel */
|
||||
chan[ch].chsf[dev] &= ~(CHSF_ACT|CHSF_CM); /* stop channel */
|
||||
return CHS_INACTV;
|
||||
}
|
||||
|
||||
@@ -806,7 +821,7 @@ if (chan[ch].chi[dev] & CHI_CTL) /* ctl int pending? */
|
||||
else return -1;
|
||||
}
|
||||
|
||||
/* Set device interrupt */
|
||||
/* Set, check device interrupt */
|
||||
|
||||
void chan_set_dvi (uint32 dva)
|
||||
{
|
||||
@@ -817,6 +832,30 @@ chan[ch].chf[dev] |= CHF_INP; /* int pending */
|
||||
return;
|
||||
}
|
||||
|
||||
t_bool chan_chk_dvi (uint32 dva)
|
||||
{
|
||||
uint32 ch = DVA_GETCHAN (dva); /* get ch, dev */
|
||||
uint32 dev = DVA_GETDEV (dva);
|
||||
|
||||
if ((chan[ch].chf[dev] & CHF_INP) != 0)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Channel set Chaining Modifier flag */
|
||||
|
||||
uint32 chan_set_cm (uint32 dva)
|
||||
{
|
||||
uint32 ch, dev;
|
||||
|
||||
ch = DVA_GETCHAN (dva); /* get chan, dev */
|
||||
dev = DVA_GETDEV (dva);
|
||||
if (!VALID_DVA (ch, dev)) /* valid? */
|
||||
return SCPE_IERR;
|
||||
chan[ch].chsf[dev] |= CHSF_CM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called by device reset to reset channel registers */
|
||||
|
||||
t_stat chan_reset_dev (uint32 dva)
|
||||
@@ -828,7 +867,7 @@ dev = DVA_GETDEV (dva);
|
||||
if (!VALID_DVA (ch, dev)) /* valid? */
|
||||
return SCPE_IERR;
|
||||
chan[ch].chf[dev] &= ~CHF_INP; /* clear intr */
|
||||
chan[ch].chsf[dev] &= ~CHSF_ACT; /* clear active */
|
||||
chan[ch].chsf[dev] &= ~(CHSF_ACT|CHSF_CM); /* clear active */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1224,7 +1263,7 @@ for (i = 0; i < CHAN_N_DEV; i++) {
|
||||
chan[ch].bc[i] = 0;
|
||||
chan[ch].chf[i] = 0;
|
||||
chan[ch].chi[i] = 0;
|
||||
chan[ch].chsf[i] &= ~CHSF_ACT;
|
||||
chan[ch].chsf[i] &= ~(CHSF_ACT|CHSF_CM);
|
||||
for (j = 0; (devp = sim_devices[j]) != NULL; j++) { /* loop thru dev */
|
||||
if (devp->ctxt != NULL) {
|
||||
dib_t *dibp = (dib_t *) devp->ctxt;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_io_defs.h: XDS Sigma I/O device simulator definitions
|
||||
|
||||
Copyright (c) 2007-2008, Robert M Supnik
|
||||
Copyright (c) 2007-2024, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -23,6 +23,9 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
19-Mar-24 RMS Added chaining modifier flag (Ken Rector)
|
||||
01-Feb-24 RMS Fixed DVT_NODEV definition (Ken Rector)
|
||||
15-Dec-22 RMS Added chan_chk_dvi definition
|
||||
21-Jul-22 RMS Channel UEND flag in wrong bit position (Ken Rector)
|
||||
*/
|
||||
|
||||
@@ -126,6 +129,7 @@ typedef struct {
|
||||
|
||||
#define CHSF_ACT 0x0001 /* channel active */
|
||||
#define CHSF_MU 0x0002 /* multi-unit dev */
|
||||
#define CHSF_CM 0x0004 /* chaining modifier */
|
||||
|
||||
/* Dispatch routine status return value */
|
||||
|
||||
@@ -149,7 +153,7 @@ typedef struct {
|
||||
#define DVT_GETCC(x) (((x) >> DVT_V_CC) & DVT_M_CC)
|
||||
#define DVT_GETDVS(x) (((x) >> DVT_V_DVS) & DVT_M_DVS)
|
||||
#define DVT_NOST (CC1 << DVT_V_CC) /* no status */
|
||||
#define DVT_NODEV ((CC1|CC2) < DVT_V_CC) /* no device */
|
||||
#define DVT_NODEV ((CC1|CC2) << DVT_V_CC) /* no device */
|
||||
|
||||
/* Read and write direct address format */
|
||||
|
||||
@@ -252,6 +256,8 @@ void chan_set_chi (uint32 dva, uint32 fl);
|
||||
void chan_set_dvi (uint32 dva);
|
||||
int32 chan_clr_chi (uint32 dva);
|
||||
int32 chan_chk_chi (uint32 dva);
|
||||
t_bool chan_chk_dvi (uint32 dva);
|
||||
uint32 chan_set_cm (uint32 dva);
|
||||
uint32 chan_end (uint32 dva);
|
||||
uint32 chan_uen (uint32 dva);
|
||||
uint32 chan_RdMemB (uint32 dva, uint32 *dat);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_lp.c: Sigma 7440/7450 line printer
|
||||
|
||||
Copyright (c) 2007-2021, Robert M. Supnik
|
||||
Copyright (c) 2007-2024, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
lp 7440/7445 or 7450 line printer
|
||||
|
||||
18-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
Added INIT test for illegal command (Ken Rector)
|
||||
15-Dec-2022 RMS Moved SIO interrupt test to devices
|
||||
10-Jun-2021 RMS Removed use of ftell for pipe compatibility
|
||||
09-Mar-2017 RMS Fixed unclosed file returns in CCT load (COVERITY)
|
||||
*/
|
||||
@@ -97,6 +100,24 @@ uint8 lp_to_ascii[64] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', '#', '@', '\'', '=', '"'
|
||||
};
|
||||
static uint8 lp_valid_cmd[256] = {
|
||||
0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0n */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4n */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
extern uint32 chan_ctl_time;
|
||||
|
||||
@@ -180,9 +201,11 @@ switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = lp_tio_status (); /* get status */
|
||||
if ((*dvst & DVS_DST) == 0) { /* idle? */
|
||||
if (chan_chk_dvi (dva)) /* int pending? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
else if ((*dvst & DVS_DST) == 0) { /* idle? */
|
||||
lp_cmd = LPS_INIT; /* start dev thread */
|
||||
sim_activate (&lp_unit, chan_ctl_time);
|
||||
sim_activate (&lp_unit, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -230,6 +253,10 @@ switch (lp_cmd) { /* case on state */
|
||||
st = chan_get_cmd (lp_dib.dva, &cmd); /* get command */
|
||||
if (CHS_IFERR (st)) /* channel error? */
|
||||
return lp_chan_err (st);
|
||||
if (lp_valid_cmd[cmd] == 0) { /* bad command? */
|
||||
chan_uen (lp_dib.dva); /* uend */
|
||||
return SCPE_OK;
|
||||
}
|
||||
lp_inh = 0; /* clear inhibit, */
|
||||
lp_run = 0; /* runaway */
|
||||
lp_cmd = lp_lastcmd = cmd; /* save command */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_mt.c: Sigma 732X 9-track magnetic tape
|
||||
|
||||
Copyright (c) 2007-2022, Robert M. Supnik
|
||||
Copyright (c) 2007-2024, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,13 @@
|
||||
|
||||
mt 7320 and 7322/7323 magnetic tape
|
||||
|
||||
17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
11-Feb-24 RMS Report non-operational if not attached (Ken Rector)
|
||||
01-Feb-24 RMS Fixed nx unit test (Ken Rector)
|
||||
01-Nov-23 RMS Fixed reset not to clear BOT
|
||||
31-Mar-23 RMS Mask unit flag before calling status in AIO (Ken Rector)
|
||||
07-Feb-23 RMS Silenced Mac compiler warnings (Ken Rector)
|
||||
15-Dec-22 RMS Moved SIO interrupt test to devices
|
||||
20-Jul-22 RMS Space record must set EOF flag on tape mark (Ken Rector)
|
||||
03-Jul-22 RMS Fixed error in handling of channel errors (Ken Rector)
|
||||
02-Jul-22 RMS Fixed bugs in multi-unit operation
|
||||
@@ -230,15 +237,19 @@ uint32 un = DVA_GETUNIT (dva);
|
||||
UNIT *uptr = &mt_unit[un];
|
||||
|
||||
if ((un >= MT_NUMDR) || /* inv unit num? */
|
||||
(uptr-> flags & UNIT_DIS)) /* disabled unit? */
|
||||
return DVT_NODEV;
|
||||
(uptr-> flags & UNIT_DIS)) { /* disabled unit? */
|
||||
*dvst = DVT_NODEV;
|
||||
return 0;
|
||||
}
|
||||
switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = mt_tio_status (un); /* get status */
|
||||
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||
if (chan_chk_dvi (dva)) /* int pending? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||
uptr->UCMD = MCM_INIT; /* start dev thread */
|
||||
sim_activate (uptr, chan_ctl_time);
|
||||
sim_activate (uptr, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -264,7 +275,8 @@ switch (op) { /* case on op */
|
||||
|
||||
case OP_AIO: /* acknowledge int */
|
||||
un = mt_clr_int (mt_dib.dva); /* clr int, get unit and flag */
|
||||
*dvst = (mt_tdv_status (un) & MTAI_MASK) | /* device status */
|
||||
*dvst =
|
||||
(mt_tdv_status (un & DVA_M_DEVMU) & MTAI_MASK) | /* device status */
|
||||
(un & MTAI_INT) | /* device int flag */
|
||||
((un & DVA_M_UNIT) << DVT_V_UN); /* unit number */
|
||||
break;
|
||||
@@ -476,7 +488,7 @@ switch (cmd) { /* case on command */
|
||||
sim_activate (uptr, mt_time); /* continue thread */
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (r = mt_flush_buf (uptr)) { /* flush buffer */
|
||||
if ((r = mt_flush_buf (uptr)) != 0) { /* flush buffer */
|
||||
st = mt_map_err (uptr, r); /* map error */
|
||||
if (CHS_IFERR (st)) /* chan or SCP err? */
|
||||
return mt_chan_err (dva, st); /* uend and stop */
|
||||
@@ -560,10 +572,12 @@ uint32 mt_tio_status (uint32 un)
|
||||
uint32 i, st;
|
||||
UNIT *uptr = &mt_unit[un];
|
||||
|
||||
st = (uptr->flags & UNIT_ATT)? DVS_AUTO: 0; /* AUTO */
|
||||
st = DVS_AUTO; /* flags */
|
||||
if (sim_is_active (uptr) || /* unit busy */
|
||||
sim_is_active (uptr + MT_REW)) /* or rewinding? */
|
||||
st |= DVS_DBUSY;
|
||||
else if ((uptr -> flags & UNIT_ATT) == 0) /* not att => offl */
|
||||
st |= DVS_DOFFL;
|
||||
for (i = 0; i < MT_NUMDR; i++) { /* loop thru units */
|
||||
if (sim_is_active (&mt_unit[i])) { /* active? */
|
||||
st |= (DVS_CBUSY | (CC2 << DVT_V_CC)); /* ctrl is busy */
|
||||
@@ -651,7 +665,9 @@ uint32 i;
|
||||
for (i = 0; i < MT_NUMDR; i++) {
|
||||
sim_cancel (&mt_unit[i]); /* stop unit */
|
||||
sim_cancel (&mt_unit[i + MT_REW]); /* stop rewind */
|
||||
mt_unit[i].UST = 0;
|
||||
if (mt_unit[i].flags & UNIT_ATT) /* attached? */
|
||||
mt_unit[i].UST &= MTDV_BOT; /* clr sta exc BOT */
|
||||
else mt_unit[i].UST = 0;
|
||||
mt_unit[i].UCMD = 0;
|
||||
}
|
||||
mt_rwi = 0;
|
||||
@@ -670,7 +686,8 @@ t_stat mt_attach (UNIT *uptr, CONST char *cptr)
|
||||
t_stat r;
|
||||
|
||||
r = sim_tape_attach (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
uptr->UST = MTDV_BOT;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_pt.c: Sigma 7060 paper tape reader/punch
|
||||
|
||||
Copyright (c) 2007-2018, Robert M. Supnik
|
||||
Copyright (c) 2007-2024, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
pt 7060 paper-tape reader/punch
|
||||
|
||||
17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
15-Dec-2022 RMS Moved SIO interrupt test to devices
|
||||
02-Jun-2018 RMS Defanged clang signed/unsigned whining (Mark Pizzolato)
|
||||
*/
|
||||
|
||||
@@ -119,9 +121,11 @@ switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = pt_tio_status (); /* get status */
|
||||
if ((*dvst & DVS_DST) == 0) { /* idle? */
|
||||
if (chan_chk_dvi (dva)) /* int pending? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
else if ((*dvst & DVS_DST) == 0) { /* idle? */
|
||||
pt_cmd = PTS_INIT; /* start dev thread */
|
||||
sim_activate (&pt_unit[PTR], chan_ctl_time);
|
||||
sim_activate (&pt_unit[PTR], 0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_rad.c: Sigma 7211/7212 or 7231/7232 fixed head disk simulator
|
||||
|
||||
Copyright (c) 2007-2022, Robert M Supnik
|
||||
Copyright (c) 2007-2024, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,10 @@
|
||||
|
||||
rad 7211/7212 or 7231/7232 fixed head disk
|
||||
|
||||
17-Feb-24 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
01-Feb-24 RMS Fixed nx unit test (Ken Rector)
|
||||
22-Apr-23 RMS Fixed write protect test (Ken Rector)
|
||||
15-Dec-22 RMS Moved SIO interrupt test to devices
|
||||
02-Jul-22 RMS Fixed bugs in multi-unit operation
|
||||
|
||||
The RAD is a head-per-track disk. To minimize overhead, the entire RAD
|
||||
@@ -64,9 +68,9 @@
|
||||
#define RADA_GETTK(x) (((x) >> rad_tab[rad_model].tk_v) & rad_tab[rad_model].tk_m)
|
||||
#define RADA_GETSC(x) (((x) >> rad_tab[rad_model].sc_v) & rad_tab[rad_model].sc_m)
|
||||
|
||||
/* Address bad flag */
|
||||
/* Write protect flag */
|
||||
|
||||
#define RADA_INV 0x80
|
||||
#define RADA_WP 0x80
|
||||
|
||||
/* Status byte 3 is current sector */
|
||||
/* Status byte 4 (7212 only) is failing sector */
|
||||
@@ -131,6 +135,7 @@ t_stat rad_showtype (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_bool rad_inv_ad (uint32 *da);
|
||||
t_bool rad_inc_ad (void);
|
||||
t_bool rad_end_sec (UNIT *uptr, uint32 lnt, uint32 exp, uint32 st);
|
||||
t_bool rad_wp_trk (uint32 adr);
|
||||
|
||||
/* RAD data structures
|
||||
|
||||
@@ -205,15 +210,19 @@ int32 iu;
|
||||
UNIT *uptr;
|
||||
|
||||
if ((un >= RAD_NUMDR) || /* inv unit num? */
|
||||
(rad_unit[un].flags & UNIT_DIS)) /* disabled unit? */
|
||||
return DVT_NODEV;
|
||||
(rad_unit[un].flags & UNIT_DIS)) { /* disabled unit? */
|
||||
*dvst = DVT_NODEV;
|
||||
return 0;
|
||||
}
|
||||
switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = rad_tio_status (un); /* get status */
|
||||
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||
if (chan_chk_dvi (dva)) /* int pending? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||
rad_cmd = RADS_INIT; /* start dev thread */
|
||||
sim_activate (&rad_unit[un], chan_ctl_time);
|
||||
sim_activate (&rad_unit[un], 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -261,7 +270,7 @@ return 0;
|
||||
|
||||
t_stat rad_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 i, sc, da, cmd, wd, wd1, c[4], gp;
|
||||
uint32 i, sc, da, cmd, wd, wd1, c[4];
|
||||
uint32 *fbuf = (uint32 *) uptr->filebuf;
|
||||
uint32 un = uptr - rad_unit;
|
||||
uint32 dva = rad_dib.dva | un;
|
||||
@@ -316,8 +325,10 @@ switch (rad_cmd) {
|
||||
break;
|
||||
|
||||
case RADS_SENSE: /* sense */
|
||||
c[0] = ((rad_ad >> 8) & 0x7F) | (rad_inv_ad (NULL)? RADA_INV: 0);
|
||||
c[1] = rad_ad & 0xFF; /* address */
|
||||
c[0] = (rad_ad >> 8) & 0x7F; /* addr hi */
|
||||
if (rad_wp_trk (rad_ad)) /* addr wr prot? */
|
||||
c[0] |= RADA_WP; /* set flag */
|
||||
c[1] = rad_ad & 0xFF; /* addr lo */
|
||||
c[2] = GET_PSC (rad_time); /* curr sector */
|
||||
c[3] = 0;
|
||||
for (i = 0, st = 0; (i < rad_tab[rad_model].nbys) && (st != CHS_ZBC); i++) {
|
||||
@@ -331,9 +342,7 @@ switch (rad_cmd) {
|
||||
break;
|
||||
|
||||
case RADS_WRITE: /* write */
|
||||
gp = (RADA_GETSC (rad_ad) * RAD_N_WLK) / /* write lock group */
|
||||
rad_tab[rad_model].tkun;
|
||||
if ((rad_wlk >> gp) & 1) { /* write lock set? */
|
||||
if (rad_wp_trk (rad_ad)) { /* write protected? */
|
||||
rad_flags |= RADV_WPE; /* set status */
|
||||
chan_uen (dva); /* uend */
|
||||
return SCPE_OK;
|
||||
@@ -498,6 +507,17 @@ if (tk >= rad_tab[rad_model].tkun) /* overflow? */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Test disk addr for protected tracks */
|
||||
|
||||
t_bool rad_wp_trk (uint32 adr)
|
||||
{
|
||||
uint32 trk = RADA_GETTK (adr); /* track */
|
||||
uint32 sw = (trk * RAD_N_WLK) / rad_tab[rad_model].tkun; /* switch num */
|
||||
|
||||
if ((rad_wlk >> sw) & 1) /* switch set? */
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
/* Channel error */
|
||||
|
||||
t_stat rad_chan_err (uint32 dva, uint32 st)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_sys.c: Sigma system interface
|
||||
|
||||
Copyright (c) 2007-2017, Robert M Supnik
|
||||
Copyright (c) 2007-2024, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -23,6 +23,7 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
03-Apr-2024 RMS Added CR, CP support (Ken Rector)
|
||||
09-Mar-2017 RMS Added LOAD processor for CCT
|
||||
*/
|
||||
|
||||
@@ -43,6 +44,8 @@ extern DEVICE rad_dev;
|
||||
extern DEVICE dk_dev;
|
||||
extern DEVICE dp_dev[];
|
||||
extern DEVICE mt_dev;
|
||||
extern DEVICE cr_dev;
|
||||
extern DEVICE cp_dev;
|
||||
extern DEVICE mux_dev, muxl_dev;
|
||||
extern REG cpu_reg[];
|
||||
extern uint32 *M;
|
||||
@@ -93,6 +96,8 @@ DEVICE *sim_devices[] = {
|
||||
&dp_dev[1],
|
||||
&mux_dev,
|
||||
&muxl_dev,
|
||||
&cr_dev,
|
||||
&cp_dev,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -166,6 +171,73 @@ uint8 ebcdic_to_ascii[256] = {
|
||||
'8', '9', 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
|
||||
};
|
||||
|
||||
uint16 ebcdic_to_hol[256] = {
|
||||
/* T918 T91 T92 T93 T94 T95 T96 T97 0x0x */
|
||||
0xB03, 0x901, 0x881, 0x841, 0x821, 0x811, 0x809, 0x805,
|
||||
/* T98, T189 , T289, T389, T489, T589, T689, T789 */
|
||||
0x803, 0x903, 0x883, 0x843, 0x823, 0x813, 0x80B, 0x807,
|
||||
/* TE189 E91 E92 E93 E94 E95 E96 E97 0x1x */
|
||||
0xD03, 0x501, 0x481, 0x441, 0x421, 0x411, 0x409, 0x405,
|
||||
/* E98 E918 E928 E938 E948 E958 E968 E978 */
|
||||
0x403, 0x503, 0x483, 0x443, 0x423, 0x413, 0x40B, 0x407,
|
||||
/* E0918 091 092 093 094 095 096 097 0x2x */
|
||||
0x703, 0x301, 0x281, 0x241, 0x221, 0x211, 0x209, 0x205,
|
||||
/* 098 0918 0928 0938 0948 0958 0968 0978 */
|
||||
0x203, 0x303, 0x283, 0x243, 0x223, 0x213, 0x20B, 0x207,
|
||||
/* TE0918 91 92 93 94 95 96 97 0x3x */
|
||||
0xF03, 0x101, 0x081, 0x041, 0x021, 0x011, 0x009, 0x005,
|
||||
/* 98 189 289 389 489 589 689 789 */
|
||||
0x003, 0x103, 0x083, 0x043, 0x023, 0x013, 0x00B, 0x007,
|
||||
/* T091 T092 T093 T094 T095 T096 T097 0x4x */
|
||||
0x000, 0xB01, 0xA81, 0xA41, 0xA21, 0xA11, 0xA09, 0xA05,
|
||||
/* T098 T18 T28 T38 T48 T58 T68 T78 */
|
||||
0xA03, 0x902, 0x882, 0x842, 0x822, 0x812, 0x80A, 0x806,
|
||||
/* T TE91 TE92 TE93 TE94 TE95 TE96 TE97 0x5x */
|
||||
0x800, 0xD01, 0xC81, 0xC41, 0xC21, 0xC11, 0xC09, 0xC05,
|
||||
/* TE98 E18 E28 E38 E48 E58 E68 E78 */
|
||||
0xC03, 0x502, 0x482, 0x442, 0x422, 0x412, 0x40A, 0x406,
|
||||
/* E 01 E092 E093 E094 E095 E096 E097 0x6x */
|
||||
0x400, 0x300, 0x681, 0x641, 0x621, 0x611, 0x609, 0x605,
|
||||
/* E098 018 TE 038 048 68 068 078 */
|
||||
0x603, 0x302, 0xC00, 0x242, 0x222, 0x212, 0x20A, 0x206,
|
||||
/* TE0 TE091 TE092 TE093 TE094 TE095 TE096 TE097 0x7x */
|
||||
0xE00, 0xF01, 0xE81, 0xE41, 0xE21, 0xE11, 0xE09, 0xE05,
|
||||
/* TE098 18 28 38 48 58 68 78 */
|
||||
0xE03, 0x102, 0x082, 0x042, 0x022, 0x012, 0x00A, 0x006,
|
||||
/* T018 T01 T02 T03 T04 T05 T06 T07 0x8x */
|
||||
0xB02, 0xB00, 0xA80, 0xA40, 0xA20, 0xA10, 0xA08, 0xA04,
|
||||
/* T08 T09 T028 T038 T048 T058 T068 T078 */
|
||||
0xA02, 0xA01, 0xA82, 0xA42, 0xA22, 0xA12, 0xA0A, 0xA06,
|
||||
/* TE18 TE1 TE2 TE3 TE4 TE5 TE6 TE7 0x9x */
|
||||
0xD02, 0xD00, 0xC80, 0xC40, 0xC20, 0xC10, 0xC08, 0xC04,
|
||||
/* TE8 TE9 TE28 TE38 TE48 TE58 TE68 TE78 */
|
||||
0xC02, 0xC01, 0xC82, 0xC42, 0xC22, 0xC12, 0xC0A, 0xC06,
|
||||
/* E018 E01 E02 E03 E04 E05 E06 E07 0xax */
|
||||
0x702, 0x700, 0x680, 0x640, 0x620, 0x610, 0x608, 0x604,
|
||||
/* E08 E09 E028 E038 E048 E058 E068 E078 */
|
||||
0x602, 0x601, 0x682, 0x642, 0x622, 0x612, 0x60A, 0x606,
|
||||
/* TE018 TE01 TE02 TE03 TE04 TE05 TE06 TE07 0xbx */
|
||||
0xF02, 0xF00, 0xE80, 0xE40, 0xE20, 0xE10, 0xE08, 0xE04,
|
||||
/* TE08 TE09 TE028 TE038 TE048 TE058 TE068 TE078 */
|
||||
0xE02, 0xE01, 0xE82, 0xE42, 0xE22, 0xE12, 0xE0A, 0xE06,
|
||||
/* T0 T1 T2 T3 T4 T5 T6 T7 0xcx */
|
||||
0xA00, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804,
|
||||
/* T8 T9 T0928 T0938 T0948 T0958 T0968 T0978 */
|
||||
0x802, 0x801, 0xA83, 0xA43, 0xA23, 0xA13, 0xA0B, 0xA07,
|
||||
/* E0 E1 E2 E3 E4 E5 E6 E7 0xdx */
|
||||
0x600, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
|
||||
/* E8 E9 TE928 TE938 TE948 TE958 TE968 TE978 */
|
||||
0x402, 0x401, 0xC83, 0xC43, 0xC23, 0xC13, 0xC0B, 0xC07,
|
||||
/* 028 E091 02 03 04 05 06 07 0xex */
|
||||
0x282, 0x701, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
|
||||
/* 08 09 E0928 E0938 E0948 E0958 E0968 E0978 */
|
||||
0x202, 0x201, 0x683, 0x643, 0x623, 0x613, 0x60B, 0x607,
|
||||
/* 0 1 2 3 4 5 6 7 0xfx */
|
||||
0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004,
|
||||
/* 8 9 TE0928 TE0938 TE0948 TE0958 TE0968 TE0978 */
|
||||
0x002, 0x001, 0xE83, 0xE43, 0xE23, 0xE13, 0xE0B, 0xE07
|
||||
};
|
||||
|
||||
/* Binary loader */
|
||||
|
||||
t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* sigma_tt.c: Sigma 7012 console teletype
|
||||
|
||||
Copyright (c) 2007-2018, Robert M. Supnik
|
||||
Copyright (c) 2007-2024, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -31,6 +31,8 @@
|
||||
^H input, mapped to EOM and not echoed
|
||||
HT input or output, simulates tabbing with fixed 8 character stops
|
||||
|
||||
18-Feb-2024 RMS Zero delay from SIO to INIT state (Ken Rector)
|
||||
15-Dec-2922 RMS Moved SIO int pending test to devices
|
||||
02-Jun-2018 RMS Defanged clang signed/unsigned whining (Mark Pizzolato)
|
||||
*/
|
||||
|
||||
@@ -134,9 +136,11 @@ switch (op) { /* case on op */
|
||||
|
||||
case OP_SIO: /* start I/O */
|
||||
*dvst = tt_tio_status (); /* get status */
|
||||
if ((*dvst & DVS_DST) == 0) { /* idle? */
|
||||
if (chan_chk_dvi (dva)) /* int pending? */
|
||||
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
|
||||
else if ((*dvst & DVS_DST) == 0) { /* idle? */
|
||||
tt_cmd = TTS_INIT; /* start dev thread */
|
||||
sim_activate (&tt_unit[TTO], chan_ctl_time);
|
||||
sim_activate (&tt_unit[TTO], 0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user