Merge branch 'master' of github.com:simh/simh

This commit is contained in:
Mark Pizzolato 2013-01-23 13:17:26 -08:00
commit 552d6803d7
8 changed files with 199 additions and 41 deletions

View file

@ -1244,7 +1244,7 @@ static const int32 boot_rom[] = {
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
{
int32 i;
size_t i;
for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
saved_PC = BOOT_START;

View file

@ -1085,7 +1085,7 @@ static const int32 boot_rom[] = {
t_stat dkp_boot (int32 unitno, DEVICE *dptr)
{
int32 i;
size_t i;
for (i = 0; i < BOOT_LEN; i++)
M[BOOT_START + i] = (uint16) boot_rom[i];

View file

@ -297,7 +297,7 @@ static const int32 boot_rom[] = {
t_stat dsk_boot (int32 unitno, DEVICE *dptr)
{
int32 i;
size_t i;
for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = (uint16) boot_rom[i];
saved_PC = BOOT_START;

View file

@ -26,6 +26,23 @@
------------------------------------------------------------------------------
Modification history:
23-Jan-13 RJ Clock co-scheduling move to generic framework (from Mark Pizzolato)
21-Jan-13 RJ Added help.
15-Jan-13 RJ Contribution from Paul Koning:
Support for RSTS using the ROM INPUT (ROM I) command to get
the DMC11 to report DSR status.
Don't accept any data from the peer until a buffer has been
made available.
Also added shadow CSRs. The code was using the CSRs to check
the command being executed, but the driver could end up
changing the bits, so a shadow set is used to do this.
------------------------------------------------------------------------------
I/O is done through sockets so that the remote system can be on the same host machine. The device starts polling for
incoming connections when it receives its first read buffer. The device opens the connection for writing when it receives
@ -173,6 +190,7 @@ typedef enum
struct dmc_controller {
CSRS *csrs;
CSRS *shadow_csrs;
DEVICE *device;
ControllerState state;
TransferState transfer_state; /* current transfer state (type of transfer) */
@ -218,6 +236,8 @@ t_stat dmc_setconnectpoll (UNIT* uptr, int32 val, char* cptr, void* desc);
t_stat dmc_showconnectpoll (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat dmc_setlinemode (UNIT* uptr, int32 val, char* cptr, void* desc);
t_stat dmc_showlinemode (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat dmc_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat dmc_help_attach (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
int dmc_is_dmc(CTLR *controller);
int dmc_is_rqi_set(CTLR *controller);
int dmc_is_rdyi_set(CTLR *controller);
@ -262,8 +282,10 @@ UNIT dmc3_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) };
UNIT dmpa_unit = { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) };
CSRS dmc_csrs[DMC_NUMDEVICE];
CSRS dmc_shadow_csrs[DMC_NUMDEVICE];
CSRS dmp_csrs[DMP_NUMDEVICE];
CSRS dmp_shadow_csrs[DMP_NUMDEVICE];
LINE dmc_line[DMC_NUMDEVICE] =
{
@ -300,6 +322,10 @@ REG dmca_reg[] = {
{ GRDATA (BSEL5, dmc_csrs[0].sel4, DEV_RDX, 8, 8) },
{ GRDATA (BSEL6, dmc_csrs[0].sel6, DEV_RDX, 8, 0) },
{ GRDATA (BSEL7, dmc_csrs[0].sel6, DEV_RDX, 8, 8) },
{ HRDATA (SHADOWSEL0, dmc_shadow_csrs[0].sel0, 16), REG_HRO },
{ HRDATA (SHADOWSEL2, dmc_shadow_csrs[0].sel2, 16), REG_HRO },
{ HRDATA (SHADOWSEL4, dmc_shadow_csrs[0].sel4, 16), REG_HRO },
{ HRDATA (SHADOWSEL6, dmc_shadow_csrs[0].sel6, 16), REG_HRO },
{ BRDATA (PEER, dmc_line[0].peer, 16, 8, sizeof(dmc_line[0].peer)), REG_HRO},
{ HRDATA (MODE, dmc_line[0].isPrimary, 32), REG_HRO },
{ HRDATA (SPEED, dmc_line[0].speed, 32), REG_HRO },
@ -318,6 +344,10 @@ REG dmcb_reg[] = {
{ GRDATA (BSEL5, dmc_csrs[1].sel4, DEV_RDX, 8, 8) },
{ GRDATA (BSEL6, dmc_csrs[1].sel6, DEV_RDX, 8, 0) },
{ GRDATA (BSEL7, dmc_csrs[1].sel6, DEV_RDX, 8, 8) },
{ HRDATA (SHADOWSEL0, dmc_shadow_csrs[1].sel0, 16), REG_HRO },
{ HRDATA (SHADOWSEL2, dmc_shadow_csrs[1].sel2, 16), REG_HRO },
{ HRDATA (SHADOWSEL4, dmc_shadow_csrs[1].sel4, 16), REG_HRO },
{ HRDATA (SHADOWSEL6, dmc_shadow_csrs[1].sel6, 16), REG_HRO },
{ BRDATA (PEER, dmc_line[1].peer, 16, 8, sizeof(dmc_line[1].peer)), REG_HRO},
{ HRDATA (MODE, dmc_line[1].isPrimary, 32), REG_HRO },
{ HRDATA (SPEED, dmc_line[1].speed, 32), REG_HRO },
@ -336,6 +366,10 @@ REG dmcc_reg[] = {
{ GRDATA (BSEL5, dmc_csrs[2].sel4, DEV_RDX, 8, 8) },
{ GRDATA (BSEL6, dmc_csrs[2].sel6, DEV_RDX, 8, 0) },
{ GRDATA (BSEL7, dmc_csrs[2].sel6, DEV_RDX, 8, 8) },
{ HRDATA (SHADOWSEL0, dmc_shadow_csrs[2].sel0, 16), REG_HRO },
{ HRDATA (SHADOWSEL2, dmc_shadow_csrs[2].sel2, 16), REG_HRO },
{ HRDATA (SHADOWSEL4, dmc_shadow_csrs[2].sel4, 16), REG_HRO },
{ HRDATA (SHADOWSEL6, dmc_shadow_csrs[2].sel6, 16), REG_HRO },
{ BRDATA (PEER, dmc_line[2].peer, 16, 8, sizeof(dmc_line[2].peer)), REG_HRO},
{ HRDATA (MODE, dmc_line[2].isPrimary, 32), REG_HRO },
{ HRDATA (SPEED, dmc_line[2].speed, 32), REG_HRO },
@ -354,6 +388,10 @@ REG dmcd_reg[] = {
{ GRDATA (BSEL5, dmc_csrs[3].sel4, DEV_RDX, 8, 8) },
{ GRDATA (BSEL6, dmc_csrs[3].sel6, DEV_RDX, 8, 0) },
{ GRDATA (BSEL7, dmc_csrs[3].sel6, DEV_RDX, 8, 8) },
{ HRDATA (SHADOWSEL0, dmc_shadow_csrs[3].sel0, 16), REG_HRO },
{ HRDATA (SHADOWSEL2, dmc_shadow_csrs[3].sel2, 16), REG_HRO },
{ HRDATA (SHADOWSEL4, dmc_shadow_csrs[3].sel4, 16), REG_HRO },
{ HRDATA (SHADOWSEL6, dmc_shadow_csrs[3].sel6, 16), REG_HRO },
{ BRDATA (PEER, dmc_line[3].peer, 16, 8, sizeof(dmc_line[3].peer)), REG_HRO},
{ HRDATA (MODE, dmc_line[3].isPrimary, 32), REG_HRO },
{ HRDATA (SPEED, dmc_line[3].speed, 32), REG_HRO },
@ -372,6 +410,10 @@ REG dmp_reg[] = {
{ GRDATA (BSEL5, dmc_csrs[3].sel4, DEV_RDX, 8, 8) },
{ GRDATA (BSEL6, dmc_csrs[3].sel6, DEV_RDX, 8, 0) },
{ GRDATA (BSEL7, dmc_csrs[3].sel6, DEV_RDX, 8, 8) },
{ HRDATA (SHADOWSEL0, dmp_shadow_csrs[0].sel0, 16), REG_HRO },
{ HRDATA (SHADOWSEL2, dmp_shadow_csrs[0].sel2, 16), REG_HRO },
{ HRDATA (SHADOWSEL4, dmp_shadow_csrs[0].sel4, 16), REG_HRO },
{ HRDATA (SHADOWSEL6, dmp_shadow_csrs[0].sel6, 16), REG_HRO },
{ BRDATA (PEER, dmp_line[0].peer, 16, 8, sizeof(dmp_line[0].peer)), REG_HRO},
{ HRDATA (MODE, dmp_line[0].isPrimary, 32), REG_HRO },
{ HRDATA (SPEED, dmp_line[0].speed, 32), REG_HRO },
@ -405,16 +447,20 @@ DEVICE dmc_dev[] =
{
{ "DMC0", &dmc0_unit, dmca_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc0_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug },
&dmc0_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug,
NULL, NULL, &dmc_help, &dmc_help_attach, NULL },
{ "DMC1", &dmc1_unit, dmcb_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc1_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug },
&dmc1_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug,
NULL, NULL, &dmc_help, &dmc_help_attach, NULL },
{ "DMC2", &dmc2_unit, dmcc_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc2_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug },
&dmc2_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug,
NULL, NULL, &dmc_help, &dmc_help_attach, NULL },
{ "DMC3", &dmc3_unit, dmcd_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmc3_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }
&dmc3_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug,
NULL, NULL, &dmc_help, &dmc_help_attach, NULL }
};
#ifdef DMP
@ -422,18 +468,19 @@ DEVICE dmp_dev[] =
{
{ "DMP", &dmp_unit, dmp_reg, dmc_mod, DMP_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8,
NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach,
&dmp_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug }
&dmp_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0, dmc_debug,
NULL, NULL, &dmc_help, &dmc_help_attach, NULL }
};
#endif
CTLR dmc_ctrls[] =
{
{ &dmc_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], &dmc_stats[0], INVALID_SOCKET, 30, DMC },
{ &dmc_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], &dmc_stats[1], INVALID_SOCKET, 30, DMC },
{ &dmc_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], &dmc_stats[2], INVALID_SOCKET, 30, DMC },
{ &dmc_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], &dmc_stats[3], INVALID_SOCKET, 30, DMC },
{ &dmc_csrs[0], &dmc_shadow_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], &dmc_stats[0], INVALID_SOCKET, 30, DMC },
{ &dmc_csrs[1], &dmc_shadow_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], &dmc_stats[1], INVALID_SOCKET, 30, DMC },
{ &dmc_csrs[2], &dmc_shadow_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], &dmc_stats[2], INVALID_SOCKET, 30, DMC },
{ &dmc_csrs[3], &dmc_shadow_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], &dmc_stats[3], INVALID_SOCKET, 30, DMC },
#ifdef DMP
{ &dmp_csrs[0], &dmp_dev[0], Initialised, Idle, 0, 0, &dmp_line[0], &dmp_receive_queues[0], &dmp_transmit_queues[0], &dmp_stats[0], INVALID_SOCKET, -1, 30, DMP }
{ &dmp_csrs[0], &dmp_shadow_csrs[0], &dmp_dev[0], Initialised, Idle, 0, 0, &dmp_line[0], &dmp_receive_queues[0], &dmp_transmit_queues[0], &dmp_stats[0], INVALID_SOCKET, -1, 30, DMP }
#endif
};
@ -751,6 +798,98 @@ t_stat dmc_setlinemode (UNIT* uptr, int32 val, char* cptr, void* desc)
return status;
}
t_stat dmc_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
fprintf(st, "The DMC11 is a synchronous serial point-to-point communications device.");
fprintf(st, "A real DMC11 transports data using DDCMP, the emulated device makes a");
fprintf(st, "TCP/IP connection to another emulated device and sends length-prefixed");
fprintf(st, "messages across the connection, each message representing a single buffer");
fprintf(st, "passed to the DMC11. The DMC11 can be used for point-to-point DDCMP");
fprintf(st, "connections carrying DECnet and other types of networking, e.g. from ULTRIX or DSM.\n");
fprintf(st, "\n");
fprintf(st, "The line mode of the two ends of the link must be set. One end must always");
fprintf(st, "be primary and one end always secondary, setting both to primary or both");
fprintf(st, "to secondary will not work. If there are firewall problems at one side, set");
fprintf(st, "that side to be primary as the primary always initiates the TCP/IP connection.\n");
fprintf(st, "\n");
fprintf(st, "SET DMC0 LINEMODE= {PRIMARY|SECONDARY}\n");
fprintf(st, "\n");
fprintf(st, "To set the host and port to which data is to be transmitted use the following");
fprintf(st, "command (required for PRIMARY and SECONDARY, secondary will check it is");
fprintf(st, "receiving from the configured primary):\n");
fprintf(st, "\n");
fprintf(st, "SET DMC0 PEER=host:port\n");
fprintf(st, "\n");
fprintf(st, "The device must be attached to a receive port, use the ATTACH command specifying");
fprintf(st, "the receive port number, even if the line mode is primary.\n");
fprintf(st, "\n");
fprintf(st, "The minimum interval between attempts to connect to the other side is set using");
fprintf(st, "the following command:\n");
fprintf(st, "\n");
fprintf(st, "SET DMC0 CONNECTPOLL=n\n");
fprintf(st, "\n");
fprintf(st, "Where n is the number of seconds. The default is 30 seconds.\n");
fprintf(st, "\n");
fprintf(st, "If you want to experience the actual data rates of the physical hardware you can");
fprintf(st, "set the bit rate of the simulated line can be set using the following command:\n");
fprintf(st, "\n");
fprintf(st, "SET DMC0 SPEED=n\n");
fprintf(st, "\n");
fprintf(st, "Where n is the number of data bits per second that the simulated line runs at.");
fprintf(st, "In practice this is implemented as a delay in reading the bytes from the socket.");
fprintf(st, "Use a value of zero to run at full speed with no artificial throttling.\n");
fprintf(st, "\n");
fprintf(st, "To configure two simulators to talk to each other use the following example:\n");
fprintf(st, "\n");
fprintf(st, "Machine 1\n");
fprintf(st, "SET DMC0 ENABLE\n");
fprintf(st, "SET DMC0 PRIMARY\n");
fprintf(st, "SET DMC0 PEER=LOCALHOST:2222\n");
fprintf(st, "ATTACH DMC0 1111\n");
fprintf(st, "\n");
fprintf(st, "Machine 2\n");
fprintf(st, "SET DMC0 ENABLE\n");
fprintf(st, "SET DMC0 SECONDARY\n");
fprintf(st, "SET DMC0 PEER= LOCALHOST:1111\n");
fprintf(st, "ATTACH DMC0 2222\n");
fprintf(st, "\n");
fprintf(st, "Debugging\n");
fprintf(st, "=========\n");
fprintf(st, "The simulator has a number of debug options, these are:\n");
fprintf(st, "• REG. Shows whenever a CSR is read or written and the current value.\n");
fprintf(st, "• INFO. Shows higher-level tracing only.\n");
fprintf(st, "• WARN. Shows any warnings.\n");
fprintf(st, "• TRACE. Shows more detailed trace information.\n");
fprintf(st, "• DATA. Shows the actual data sent and received.\n");
fprintf(st, "• DATASUM. Brief summary of each received and transmitted buffer. Ignored if DATA is set.\n");
fprintf(st, "• SOCKET. Shows socket opens and closes.\n");
fprintf(st, "• CONNECT. Shows sockets actually connecting.\n");
fprintf(st, "\n");
fprintf(st, "To get a full trace use\n");
fprintf(st, "\n");
fprintf(st, "SET DMC0 DEBUG\n");
fprintf(st, "\n");
fprintf(st, "However it is recommended to use the following when sending traces:\n");
fprintf(st, "\n");
fprintf(st, "SET DMC0 DEBUG=REG;INFO;WARN\n");
fprintf(st, "\n");
fprintf(st, "\n");
return SCPE_OK;
}
t_stat dmc_help_attach (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
//tmxr_attach_help (st, dptr, uptr, flag, cptr);
fprintf (st, "The communication line performs input and output through a TCP session\n");
fprintf (st, "connected to a user-specified port. The ATTACH command specifies the");
fprintf (st, "port to be used:\n\n");
fprintf (st, " sim> ATTACH %s {interface:}port set up listening port\n\n", dptr->name);
fprintf (st, "where port is a decimal number between 1 and 65535 that is not being used for\n");
fprintf (st, "other TCP/IP activities. An ATTACH is required even if in PRIMARY mode. \n\n");
return SCPE_OK;
}
void dmc_setrxint(CTLR *controller)
{
controller->rxi = 1;
@ -810,12 +949,13 @@ void dmc_dumpregsel0(CTLR *controller, int trace_level, char * prefix, uint16 da
sim_debug(
trace_level,
controller->device,
"%s SEL0 (0x%04x) %s%s%s%s%s%s%s%s\n",
"%s SEL0 (0x%04x) %s%s%s%s%s%s%s%s%s\n",
prefix,
data,
dmc_bitfld(data, SEL0_RUN_BIT, 1) ? "RUN " : "",
dmc_bitfld(data, SEL0_MCLR_BIT, 1) ? "MCLR " : "",
dmc_bitfld(data, SEL0_LU_LOOP_BIT, 1) ? "LU LOOP " : "",
dmc_bitfld(data, SEL0_ROMI_BIT, 1) ? "ROMI " : "",
dmc_bitfld(data, SEL0_RDI_BIT, 1) ? "RDI " : "",
dmc_bitfld(data, SEL0_DMC_IEI_BIT, 1) ? "IEI " : "",
dmc_bitfld(data, SEL0_DMC_RQI_BIT, 1) ? "RQI " : "",
@ -922,18 +1062,34 @@ void dmc_setreg(CTLR *controller, int reg, uint16 data, int ext)
case 00:
dmc_dumpregsel0(controller, DBG_REG, trace, data);
controller->csrs->sel0 = data;
if (!ext)
{
controller->shadow_csrs->sel0 = data;
}
break;
case 01:
dmc_dumpregsel2(controller, DBG_REG, trace, data);
controller->csrs->sel2 = data;
if (!ext)
{
controller->shadow_csrs->sel2 = data;
}
break;
case 02:
dmc_dumpregsel4(controller, DBG_REG, trace, data);
controller->csrs->sel4 = data;
if (!ext)
{
controller->shadow_csrs->sel4 = data;
}
break;
case 03:
dmc_dumpregsel6(controller, DBG_REG, trace, data);
controller->csrs->sel6 = data;
if (!ext)
{
controller->shadow_csrs->sel6 = data;
}
break;
default:
{
@ -1024,7 +1180,7 @@ int dmc_is_in_io_set(CTLR *controller)
}
int dmc_is_out_io_set(CTLR *controller)
{
int ans = controller->csrs->sel2 & OUT_IO_MASK;
int ans = controller->shadow_csrs->sel2 & OUT_IO_MASK;
return ans;
}
@ -1104,7 +1260,7 @@ int dmc_get_input_transfer_type(CTLR *controller)
}
int dmc_get_output_transfer_type(CTLR *controller)
{
return controller->csrs->sel2 & TYPE_OUTPUT_MASK;
return controller->shadow_csrs->sel2 & TYPE_OUTPUT_MASK;
}
void dmc_set_type_output(CTLR *controller, int type)
{
@ -1747,26 +1903,7 @@ int dmc_buffer_fill_receive_buffers(CTLR *controller)
{
int ans = FALSE;
SOCKET socket;
if (controller->state == Initialised)
{
/* accept any inbound connection but just throw away any data */
if (dmc_get_socket(controller, TRUE))
{
char buffer[1000];
int bytes_read = 0;
socket = controller->line->socket;
bytes_read = sim_read_sock(socket, buffer, sizeof(buffer));
if (bytes_read < 0)
{
dmc_error_and_close_socket(controller, "read error, code=%d");
}
else if (bytes_read > 0)
{
sim_debug(DBG_SOK, controller->device, "Discarding received data while controller is not running\n");
}
}
}
else
if (controller->state == Running)
{
BUFFER *buffer = dmc_buffer_queue_find_first_available(controller->receive_queue);
while (buffer != NULL && buffer->state == Available)
@ -1796,6 +1933,7 @@ int dmc_buffer_fill_receive_buffers(CTLR *controller)
dmc_set_lost_data(controller);
dmc_start_control_output_transfer(controller);
lost_data = 1;
dmc_error_and_close_socket(controller, "oversized packet");
}
if (buffer->actual_block_len > 0)
@ -2115,6 +2253,14 @@ void dmc_process_command(CTLR *controller)
{
dmc_start_input_transfer(controller);
}
else if (dmc_is_dmc (controller) &&
controller->csrs->sel0 & ROMI_MASK &&
controller->csrs->sel6 == DSPDSR)
/* DMC-11 or DMR-11, see if ROMI bit is set. If so, if SEL6 is
0x22b3 (read line status instruction), set the DTR bit in SEL2. */
{
dmc_setreg (controller, 2, 0x800, 0);
}
}
}

View file

@ -24,6 +24,12 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author.
------------------------------------------------------------------------------
Modification history:
15-Jan-13 RJ Contribution from Paul Koning of support for RSTS using the ROM
INPUT (ROM I) command to get the DMC11 to report DSR status.
------------------------------------------------------------------------------*/
// Notes
@ -90,6 +96,7 @@ extern int32 int_req[IPL_HLVL];
#define DMC_RDYI_MASK 0x0080
#define DMC_IEI_MASK 0x0040
#define DMP_IEI_MASK 0x0001
#define ROMI_MASK 0x0200
#define LU_LOOP_MASK 0x0800
#define MASTER_CLEAR_MASK 0x4000
#define RUN_MASK 0x8000
@ -107,9 +114,12 @@ extern int32 int_req[IPL_HLVL];
#define LOST_DATA_MASK 0x0010
#define DISCONNECT_MASK 0x0040
#define DSPDSR 0x22b3 /* KMC opcode to move line unit status to SEL2 */
#define SEL0_RUN_BIT 15
#define SEL0_MCLR_BIT 14
#define SEL0_LU_LOOP_BIT 11
#define SEL0_ROMI_BIT 9
#define SEL0_RDI_BIT 7
#define SEL0_DMC_IEI_BIT 6
#define SEL0_DMP_IEI_BIT 0

View file

@ -717,7 +717,7 @@ static const uint16 boot_rom[] = {
t_stat ct_boot (int32 unitno, DEVICE *dptr)
{
int32 i;
size_t i;
extern int32 saved_PC;
extern uint16 M[];

View file

@ -1019,6 +1019,8 @@ switch (rlcs_state) {
if (sim_fseek (uptr->fileref, da, SEEK_SET))
return SCPE_IOERR;
bcnt = sim_fread (rlcs_buf, sizeof (int16), RL_NUMBY, uptr->fileref);
if (bcnt != (sizeof (int16) * RL_NUMBY))
return SCPE_IOERR;
}
if (rlcs_bcnt < RL_NUMBY) { /* more data in buffer? */
cso_buf = rlcs_buf[rlcs_bcnt++]; /* return next word */
@ -1048,6 +1050,8 @@ switch (rlcs_state) {
if (sim_fseek (uptr->fileref, da, SEEK_SET))
return SCPE_IOERR;
bcnt = sim_fwrite (rlcs_buf, sizeof (int16), RL_NUMBY, uptr->fileref);
if (bcnt != (sizeof (int16) * RL_NUMBY))
return SCPE_IOERR;
rlcs_state = RL_IDLE; /* now idle */
rlcs_bcnt = 0;
cso_csr = cso_csr | CSR_DONE | /* complete */

View file

@ -502,8 +502,7 @@ int32 fdctrk(int32 io, int32 data)
dsk_unit[cur_dsk].u4 = data & 0xFF;
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdctrk: Drive %d track set to %d", cur_dsk, dsk_unit[cur_dsk].u4);
} else
;
}
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdctrk: Drive %d track read as %d", cur_dsk, dsk_unit[cur_dsk].u4);
return dsk_unit[cur_dsk].u4;
@ -519,8 +518,7 @@ int32 fdcsec(int32 io, int32 data)
dsk_unit[cur_dsk].u5 = 1;
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcsec: Drive %d sector set to %d", cur_dsk, dsk_unit[cur_dsk].u5);
} else
;
}
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcsec: Drive %d sector read as %d", cur_dsk, dsk_unit[cur_dsk].u5);
return dsk_unit[cur_dsk].u5;