Merge of working DMC-11 device from Rob Jarratt.
pdp11_dmc.c - Fixed DMA bug which wrote data into the wrong simulated memory address. - Fixed incoming IP address checking. pdp11_io_lib.c - Added the DMC device to the autoconfigure device table vax780_defs.h - Added comment for DMC11
This commit is contained in:
parent
c9b31427b4
commit
d51df0eba5
3 changed files with 1528 additions and 1501 deletions
|
@ -72,7 +72,7 @@ The other test was to configure DECnet on VMS 4.6 and do SET HOST.
|
||||||
// TODO: Show active connections like DZ does, for multipoint.
|
// TODO: Show active connections like DZ does, for multipoint.
|
||||||
// TODO: Test MOP.
|
// TODO: Test MOP.
|
||||||
// TODO: Implement actual DDCMP protocol and run over UDP.
|
// TODO: Implement actual DDCMP protocol and run over UDP.
|
||||||
// TODO: Allow NCP SHOW COUNTERS to work (think this is the base address thing)
|
// TODO: Allow NCP SHOW COUNTERS to work (think this is the base address thing). Since fixing how I get the addresses this should work now.
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -236,7 +236,7 @@ int dmc_buffer_queue_full(BUFFER_QUEUE *q);
|
||||||
void dmc_buffer_queue_get_stats(BUFFER_QUEUE *q, int *available, int *contains_data, int *transfer_in_progress);
|
void dmc_buffer_queue_get_stats(BUFFER_QUEUE *q, int *available, int *contains_data, int *transfer_in_progress);
|
||||||
void dmc_start_transfer_transmit_buffer(CTLR *controller);
|
void dmc_start_transfer_transmit_buffer(CTLR *controller);
|
||||||
void dmc_error_and_close_receive(CTLR *controller, char *format);
|
void dmc_error_and_close_receive(CTLR *controller, char *format);
|
||||||
void dmc_close_receive(CTLR *controller, char *reason);
|
void dmc_close_receive(CTLR *controller, char *reason, char *from);
|
||||||
void dmc_close_transmit(CTLR *controller, char *reason);
|
void dmc_close_transmit(CTLR *controller, char *reason);
|
||||||
int dmc_get_socket(CTLR *controller, int forRead);
|
int dmc_get_socket(CTLR *controller, int forRead);
|
||||||
int dmc_get_receive_socket(CTLR *controller, int forRead);
|
int dmc_get_receive_socket(CTLR *controller, int forRead);
|
||||||
|
@ -396,12 +396,21 @@ DEVICE dmp_dev[] =
|
||||||
&dmp_dib[0], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }
|
&dmp_dib[0], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }
|
||||||
};
|
};
|
||||||
|
|
||||||
LINE dmc_line[DMC_NUMDEVICE];
|
LINE dmc_line[DMC_NUMDEVICE] =
|
||||||
|
{
|
||||||
|
{ 0, INVALID_SOCKET },
|
||||||
|
{ 0, INVALID_SOCKET },
|
||||||
|
{ 0, INVALID_SOCKET },
|
||||||
|
{ 0, INVALID_SOCKET }
|
||||||
|
};
|
||||||
|
|
||||||
BUFFER_QUEUE dmc_receive_queues[DMC_NUMDEVICE];
|
BUFFER_QUEUE dmc_receive_queues[DMC_NUMDEVICE];
|
||||||
BUFFER_QUEUE dmc_transmit_queues[DMC_NUMDEVICE];
|
BUFFER_QUEUE dmc_transmit_queues[DMC_NUMDEVICE];
|
||||||
|
|
||||||
LINE dmp_line[DMP_NUMDEVICE];
|
LINE dmp_line[DMP_NUMDEVICE] =
|
||||||
|
{
|
||||||
|
{ 0, INVALID_SOCKET }
|
||||||
|
};
|
||||||
|
|
||||||
BUFFER_QUEUE dmp_receive_queues[DMP_NUMDEVICE];
|
BUFFER_QUEUE dmp_receive_queues[DMP_NUMDEVICE];
|
||||||
BUFFER_QUEUE dmp_transmit_queues[DMP_NUMDEVICE];
|
BUFFER_QUEUE dmp_transmit_queues[DMP_NUMDEVICE];
|
||||||
|
@ -415,6 +424,8 @@ CTLR dmc_ctrls[] =
|
||||||
{ &dmp_csrs[0], &dmp_dev[0], Initialised, Idle, 0, 0, &dmp_line[0], &dmp_receive_queues[0], &dmp_transmit_queues[0], INVALID_SOCKET, -1, 30, DMP }
|
{ &dmp_csrs[0], &dmp_dev[0], Initialised, Idle, 0, 0, &dmp_line[0], &dmp_receive_queues[0], &dmp_transmit_queues[0], INVALID_SOCKET, -1, 30, DMP }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern int32 tmxr_poll; /* calibrated delay */
|
||||||
|
|
||||||
UNIT_STATS *dmc_get_unit_stats(UNIT *uptr)
|
UNIT_STATS *dmc_get_unit_stats(UNIT *uptr)
|
||||||
{
|
{
|
||||||
UNIT_STATS *ans = NULL;
|
UNIT_STATS *ans = NULL;
|
||||||
|
@ -741,11 +752,11 @@ t_stat dmc_setlinemode (UNIT* uptr, int32 val, char* cptr, void* desc)
|
||||||
if (!cptr) return SCPE_IERR;
|
if (!cptr) return SCPE_IERR;
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||||
|
|
||||||
if (strcmp(cptr, "PRIMARY") == 0)
|
if (MATCH_CMD(cptr, "PRIMARY") == 0)
|
||||||
{
|
{
|
||||||
controller->line->isPrimary = 1;
|
controller->line->isPrimary = 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(cptr, "SECONDARY") == 0)
|
else if (MATCH_CMD(cptr, "SECONDARY") == 0)
|
||||||
{
|
{
|
||||||
controller->line->isPrimary = 0;
|
controller->line->isPrimary = 0;
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1173,7 @@ void dmc_process_master_clear(CTLR *controller)
|
||||||
}
|
}
|
||||||
dmc_buffer_queue_init(controller, controller->receive_queue, "receive");
|
dmc_buffer_queue_init(controller, controller->receive_queue, "receive");
|
||||||
dmc_buffer_queue_init(controller, controller->transmit_queue, "transmit");
|
dmc_buffer_queue_init(controller, controller->transmit_queue, "transmit");
|
||||||
//dmc_close_receive(controller, "master clear");
|
//dmc_close_receive(controller, "master clear", NULL);
|
||||||
//dmc_close_transmit(controller, "master clear");
|
//dmc_close_transmit(controller, "master clear");
|
||||||
|
|
||||||
controller->transfer_state = Idle;
|
controller->transfer_state = Idle;
|
||||||
|
@ -1230,10 +1241,13 @@ void dmc_start_control_output_transfer(CTLR *controller)
|
||||||
t_stat dmc_svc(UNIT* uptr)
|
t_stat dmc_svc(UNIT* uptr)
|
||||||
{
|
{
|
||||||
CTLR *controller;
|
CTLR *controller;
|
||||||
|
int32 poll;
|
||||||
|
|
||||||
TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer;
|
TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer;
|
||||||
TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer;
|
TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer;
|
||||||
|
|
||||||
|
poll = clk_cosched (tmxr_poll);
|
||||||
|
|
||||||
if (dmc_timer_started(between_polls_timer))
|
if (dmc_timer_started(between_polls_timer))
|
||||||
{
|
{
|
||||||
dmc_timer_stop(between_polls_timer);
|
dmc_timer_stop(between_polls_timer);
|
||||||
|
@ -1265,7 +1279,7 @@ t_stat dmc_svc(UNIT* uptr)
|
||||||
if (controller->transfer_state == Idle) dmc_start_transfer_transmit_buffer(controller);
|
if (controller->transfer_state == Idle) dmc_start_transfer_transmit_buffer(controller);
|
||||||
|
|
||||||
/* resubmit service timer */
|
/* resubmit service timer */
|
||||||
sim_activate(controller->device->units, controller->svc_poll_interval);
|
sim_activate(controller->device->units, poll/*controller->svc_poll_interval*/);
|
||||||
|
|
||||||
dmc_timer_stop(poll_timer);
|
dmc_timer_stop(poll_timer);
|
||||||
if (dmc_timer_started(between_polls_timer))
|
if (dmc_timer_started(between_polls_timer))
|
||||||
|
@ -1364,11 +1378,12 @@ void dmc_buffer_trace_line(int tracelevel, CTLR *controller, uint8 *buf, int len
|
||||||
sim_debug(tracelevel, controller->device, "%s %s %s\n", prefix, hex, ascii);
|
sim_debug(tracelevel, controller->device, "%s %s %s\n", prefix, hex, ascii);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmc_buffer_trace(CTLR *controller, uint8 *buf, int length, char *prefix)
|
void dmc_buffer_trace(CTLR *controller, uint8 *buf, int length, char *prefix, uint32 address)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (length >= 0 && controller->device->dctrl & DBG_DAT)
|
if (length >= 0 && controller->device->dctrl & DBG_DAT)
|
||||||
{
|
{
|
||||||
|
sim_debug(DBG_DAT, controller->device, "%s Buffer address 0x%08x (%d bytes)\n", prefix, address, length);
|
||||||
for(i = 0; i < length / TRACE_BYTES_PER_LINE; i++)
|
for(i = 0; i < length / TRACE_BYTES_PER_LINE; i++)
|
||||||
{
|
{
|
||||||
dmc_buffer_trace_line(DBG_DAT, controller, buf + i*TRACE_BYTES_PER_LINE, TRACE_BYTES_PER_LINE, prefix);
|
dmc_buffer_trace_line(DBG_DAT, controller, buf + i*TRACE_BYTES_PER_LINE, TRACE_BYTES_PER_LINE, prefix);
|
||||||
|
@ -1435,7 +1450,7 @@ void dmc_buffer_queue_add(BUFFER_QUEUE *q, uint32 address, uint16 count)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sim_debug(DBG_WRN, q->controller->device, "Failed to queue %s buffer, queue full\n", q->name);
|
sim_debug(DBG_WRN, q->controller->device, "Failed to queue %s buffer address=0x%08x, queue full\n", q->name, address);
|
||||||
// TODO: Report error here.
|
// TODO: Report error here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1539,12 +1554,12 @@ t_stat dmc_open_master_socket(CTLR *controller, char *port)
|
||||||
controller->master_socket = sim_master_sock(port, &ans);
|
controller->master_socket = sim_master_sock(port, &ans);
|
||||||
if (controller->master_socket == INVALID_SOCKET)
|
if (controller->master_socket == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
sim_debug(DBG_WRN, controller->device, "Failed to open master socket\n");
|
sim_debug(DBG_WRN, controller->device, "Failed to open master socket on port %s\n", port);
|
||||||
ans = SCPE_OPENERR;
|
ans = SCPE_OPENERR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("DMC-11 %s listening on port %s (socket %d)\n", controller->device->name, port, controller->master_socket);
|
printf ("DMC-11 %s listening on port %s\n", controller->device->name, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,7 +1576,7 @@ t_stat dmc_close_master_socket(CTLR *controller)
|
||||||
// Gets the bidirectional socket and handles arbitration of determining which socket to use.
|
// Gets the bidirectional socket and handles arbitration of determining which socket to use.
|
||||||
int dmc_get_socket(CTLR *controller, int forRead)
|
int dmc_get_socket(CTLR *controller, int forRead)
|
||||||
{
|
{
|
||||||
static int lastans = 0;
|
// static int lastans = 0;
|
||||||
int ans = 0;
|
int ans = 0;
|
||||||
if (controller->line->isPrimary)
|
if (controller->line->isPrimary)
|
||||||
{
|
{
|
||||||
|
@ -1572,12 +1587,12 @@ int dmc_get_socket(CTLR *controller, int forRead)
|
||||||
ans = dmc_get_receive_socket(controller, forRead); // TODO: After change to single socket, loopback may not work.
|
ans = dmc_get_receive_socket(controller, forRead); // TODO: After change to single socket, loopback may not work.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastans != ans)
|
// if (lastans != ans)
|
||||||
{
|
// {
|
||||||
sim_debug(DBG_SOK, controller->device, "Get Socket forread=%d, changed to %d\n", forRead, ans);
|
//sim_debug(DBG_SOK, controller->device, "Get Socket forread=%d, changed to %d\n", forRead, ans);
|
||||||
}
|
// }
|
||||||
lastans = ans;
|
// lastans = ans;
|
||||||
|
//
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1591,10 +1606,13 @@ int dmc_get_receive_socket(CTLR *controller, int forRead)
|
||||||
controller->line->socket = sim_accept_conn (controller->master_socket, &ipaddr); /* poll connect */
|
controller->line->socket = sim_accept_conn (controller->master_socket, &ipaddr); /* poll connect */
|
||||||
if (controller->line->socket != INVALID_SOCKET)
|
if (controller->line->socket != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
if (strcmp(ipaddr, controller->line->transmit_host))
|
char host[sizeof(controller->line->transmit_host)];
|
||||||
|
|
||||||
|
sim_parse_addr (controller->line->transmit_host, host, sizeof(host), NULL, NULL, 0, NULL);
|
||||||
|
if (strcmp(ipaddr, host))
|
||||||
{
|
{
|
||||||
sim_debug(DBG_WRN, controller->device, "Received connection from unexpected source IP %s. Closing the connection.\n", ipaddr);
|
sim_debug(DBG_WRN, controller->device, "Received connection from unexpected source IP %s. Closing the connection.\n", ipaddr);
|
||||||
dmc_close_receive(controller, "Unathorized connection");
|
dmc_close_receive(controller, "Unathorized connection", ipaddr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1615,7 +1633,7 @@ int dmc_get_receive_socket(CTLR *controller, int forRead)
|
||||||
}
|
}
|
||||||
else if (readable == -1) /* Failed to open */
|
else if (readable == -1) /* Failed to open */
|
||||||
{
|
{
|
||||||
dmc_close_receive(controller, "failed to connect");
|
dmc_close_receive(controller, "failed to connect", NULL);
|
||||||
ans = 0;
|
ans = 0;
|
||||||
}
|
}
|
||||||
else /* connected */
|
else /* connected */
|
||||||
|
@ -1641,7 +1659,7 @@ int dmc_get_transmit_socket(CTLR *controller, int is_loopback, int forRead)
|
||||||
dmc_close_transmit(controller, "loopback change");
|
dmc_close_transmit(controller, "loopback change");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller->line->socket == INVALID_SOCKET && (time(NULL) - controller->line->last_connect_attempt) > controller->connect_poll_interval)
|
if (controller->line->socket == INVALID_SOCKET && ((int32)(time(NULL) - controller->line->last_connect_attempt)) > controller->connect_poll_interval)
|
||||||
{
|
{
|
||||||
char hostport[CBUFSIZE];
|
char hostport[CBUFSIZE];
|
||||||
|
|
||||||
|
@ -1653,10 +1671,11 @@ int dmc_get_transmit_socket(CTLR *controller, int is_loopback, int forRead)
|
||||||
else
|
else
|
||||||
sprintf(hostport, "%s", controller->line->transmit_host);
|
sprintf(hostport, "%s", controller->line->transmit_host);
|
||||||
sim_debug(DBG_SOK, controller->device, "Trying to open transmit socket to address:port %s\n", hostport);
|
sim_debug(DBG_SOK, controller->device, "Trying to open transmit socket to address:port %s\n", hostport);
|
||||||
|
controller->line->last_connect_attempt = time(NULL);
|
||||||
controller->line->socket = sim_connect_sock(hostport, NULL, NULL);
|
controller->line->socket = sim_connect_sock(hostport, NULL, NULL);
|
||||||
if (controller->line->socket != INVALID_SOCKET)
|
if (controller->line->socket != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
sim_debug(DBG_SOK, controller->device, "Opened transmit socket to port %d, socket %d\n", hostport, controller->line->socket);
|
sim_debug(DBG_SOK, controller->device, "Opened transmit socket to port %s\n", hostport);
|
||||||
controller->line->transmit_writeable = FALSE;
|
controller->line->transmit_writeable = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1688,9 +1707,9 @@ int dmc_get_transmit_socket(CTLR *controller, int is_loopback, int forRead)
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmc_close_receive(CTLR *controller, char *reason)
|
void dmc_close_receive(CTLR *controller, char *reason, char *from)
|
||||||
{
|
{
|
||||||
sim_debug(DBG_SOK, controller->device, "Closing receive socket on port %d, socket %d, reason: %s\n", controller->line->receive_port, controller->line->socket, reason);
|
sim_debug(DBG_SOK, controller->device, "Closing receive socket on port %s, reason: %s%s%s\n", controller->line->receive_port, reason, from ? " from " : "", from ? from : "");
|
||||||
sim_close_sock(controller->line->socket, FALSE);
|
sim_close_sock(controller->line->socket, FALSE);
|
||||||
controller->line->socket = INVALID_SOCKET;
|
controller->line->socket = INVALID_SOCKET;
|
||||||
|
|
||||||
|
@ -1712,7 +1731,7 @@ void dmc_error_and_close_receive(CTLR *controller, char *format)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dmc_close_receive(controller, errmsg);
|
dmc_close_receive(controller, errmsg, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1733,7 +1752,7 @@ void dmc_close_transmit(CTLR *controller, char *reason)
|
||||||
int dmc_buffer_fill_receive_buffers(CTLR *controller)
|
int dmc_buffer_fill_receive_buffers(CTLR *controller)
|
||||||
{
|
{
|
||||||
int ans = FALSE;
|
int ans = FALSE;
|
||||||
int socket;
|
SOCKET socket;
|
||||||
if (controller->state == Initialised)
|
if (controller->state == Initialised)
|
||||||
{
|
{
|
||||||
/* accept any inbound connection but just throw away any data */
|
/* accept any inbound connection but just throw away any data */
|
||||||
|
@ -1745,8 +1764,7 @@ int dmc_buffer_fill_receive_buffers(CTLR *controller)
|
||||||
bytes_read = sim_read_sock(socket, buffer, sizeof(buffer));
|
bytes_read = sim_read_sock(socket, buffer, sizeof(buffer));
|
||||||
if (bytes_read < 0)
|
if (bytes_read < 0)
|
||||||
{
|
{
|
||||||
printf("Socket error was when trying to fill receive buffers when controller initialised.\n");
|
dmc_error_and_close_receive(controller, "read error, code=%d");
|
||||||
//dmc_error_and_close_receive(controller, "read error, code=%d");
|
|
||||||
}
|
}
|
||||||
else if (bytes_read > 0)
|
else if (bytes_read > 0)
|
||||||
{
|
{
|
||||||
|
@ -1811,7 +1829,7 @@ printf("Socket error was when trying to fill receive buffers when controller ini
|
||||||
int bytes_to_read = dmc_line_speed_calculate_byte_length(controller->line->bytes_received_in_last_second, buffer->actual_block_len - buffer->actual_bytes_transferred, controller->line->speed);
|
int bytes_to_read = dmc_line_speed_calculate_byte_length(controller->line->bytes_received_in_last_second, buffer->actual_block_len - buffer->actual_bytes_transferred, controller->line->speed);
|
||||||
if (bytes_to_read > 0)
|
if (bytes_to_read > 0)
|
||||||
{
|
{
|
||||||
bytes_read = sim_read_sock(controller->line->socket, buffer->transfer_buffer + buffer->actual_bytes_transferred, bytes_to_read);
|
bytes_read = sim_read_sock(controller->line->socket, (char *)(buffer->transfer_buffer + buffer->actual_bytes_transferred), bytes_to_read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1822,7 +1840,7 @@ printf("Socket error was when trying to fill receive buffers when controller ini
|
||||||
|
|
||||||
if (buffer->actual_bytes_transferred >= buffer->actual_block_len)
|
if (buffer->actual_bytes_transferred >= buffer->actual_block_len)
|
||||||
{
|
{
|
||||||
dmc_buffer_trace(controller, buffer->transfer_buffer, buffer->actual_bytes_transferred, "REC ");
|
dmc_buffer_trace(controller, buffer->transfer_buffer, buffer->actual_bytes_transferred, "REC ", buffer->address);
|
||||||
controller->buffers_received_from_net++;
|
controller->buffers_received_from_net++;
|
||||||
buffer->state = ContainsData;
|
buffer->state = ContainsData;
|
||||||
if (!lost_data)
|
if (!lost_data)
|
||||||
|
@ -1878,7 +1896,6 @@ printf("Socket error was when trying to fill receive buffers when trying to read
|
||||||
int dmc_buffer_send_transmit_buffers(CTLR *controller)
|
int dmc_buffer_send_transmit_buffers(CTLR *controller)
|
||||||
{
|
{
|
||||||
int ans = FALSE;
|
int ans = FALSE;
|
||||||
int socket;
|
|
||||||
/* when transmit buffer is queued it is marked as available, not as ContainsData */
|
/* when transmit buffer is queued it is marked as available, not as ContainsData */
|
||||||
BUFFER *buffer = dmc_buffer_queue_find_first_available(controller->transmit_queue);
|
BUFFER *buffer = dmc_buffer_queue_find_first_available(controller->transmit_queue);
|
||||||
while (buffer != NULL)
|
while (buffer != NULL)
|
||||||
|
@ -1886,34 +1903,44 @@ int dmc_buffer_send_transmit_buffers(CTLR *controller)
|
||||||
if (dmc_get_socket(controller, FALSE)) // TODO: , buffer->is_loopback);
|
if (dmc_get_socket(controller, FALSE)) // TODO: , buffer->is_loopback);
|
||||||
{
|
{
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
|
int bytes_to_send;
|
||||||
uint16 block_len;
|
uint16 block_len;
|
||||||
int total_buffer_len = (buffer->count > 0) ? buffer->count + sizeof(block_len) : 0;
|
int total_buffer_len = (buffer->count > 0) ? buffer->count + sizeof(block_len) : 0;
|
||||||
|
|
||||||
socket = controller->line->socket;
|
|
||||||
/* only send the buffer if it actually has some data, sometimes get zero length buffers - don't send these */
|
/* only send the buffer if it actually has some data, sometimes get zero length buffers - don't send these */
|
||||||
if (total_buffer_len > 0)
|
if (total_buffer_len > 0)
|
||||||
{
|
{
|
||||||
if (buffer->actual_bytes_transferred <= 0)
|
if (buffer->transfer_buffer == NULL)
|
||||||
{
|
{
|
||||||
|
int n;
|
||||||
/* construct buffer and include block length bytes */
|
/* construct buffer and include block length bytes */
|
||||||
buffer->transfer_buffer = (uint8 *)malloc(total_buffer_len);
|
buffer->transfer_buffer = (uint8 *)malloc(total_buffer_len);
|
||||||
block_len = htons(buffer->count);
|
block_len = htons(buffer->count);
|
||||||
memcpy(buffer->transfer_buffer, (char *)&block_len, sizeof(block_len));
|
memcpy(buffer->transfer_buffer, (char *)&block_len, sizeof(block_len));
|
||||||
Map_ReadB(buffer->address, buffer->count, buffer->transfer_buffer + sizeof(block_len));
|
n = Map_ReadB(buffer->address, buffer->count, buffer->transfer_buffer + sizeof(block_len));
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
sim_debug(DBG_WRN, controller->device, "DMA error\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = sim_write_sock (controller->line->socket, buffer->transfer_buffer + buffer->actual_bytes_transferred, buffer->count + sizeof(block_len) - buffer->actual_bytes_transferred);
|
bytes_to_send = dmc_line_speed_calculate_byte_length(controller->line->bytes_sent_in_last_second, buffer->count + sizeof(block_len) - buffer->actual_bytes_transferred, controller->line->speed);
|
||||||
|
if (bytes_to_send > 0)
|
||||||
|
{
|
||||||
|
bytes = sim_write_sock (controller->line->socket, (char *)(buffer->transfer_buffer + buffer->actual_bytes_transferred), bytes_to_send);
|
||||||
if (bytes >= 0)
|
if (bytes >= 0)
|
||||||
{
|
{
|
||||||
buffer->actual_bytes_transferred += bytes;
|
buffer->actual_bytes_transferred += bytes;
|
||||||
|
controller->line->bytes_sent_in_last_second += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer->actual_bytes_transferred >= total_buffer_len || bytes < 0)
|
if (buffer->actual_bytes_transferred >= total_buffer_len || bytes < 0)
|
||||||
{
|
{
|
||||||
dmc_buffer_trace(controller, buffer->transfer_buffer+sizeof(block_len), buffer->count, "TRAN");
|
dmc_buffer_trace(controller, buffer->transfer_buffer+sizeof(block_len), buffer->count, "TRAN", buffer->address);
|
||||||
free(buffer->transfer_buffer);
|
free(buffer->transfer_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer->actual_bytes_transferred >= total_buffer_len)
|
if (buffer->actual_bytes_transferred >= total_buffer_len)
|
||||||
{
|
{
|
||||||
|
@ -2009,7 +2036,7 @@ void dmc_process_input_transfer_completion(CTLR *controller)
|
||||||
if (controller->transfer_type == TYPE_BASEI)
|
if (controller->transfer_type == TYPE_BASEI)
|
||||||
{
|
{
|
||||||
//int i;
|
//int i;
|
||||||
uint32 baseaddr = sel6 >> 14 | sel4;
|
uint32 baseaddr = ((sel6 >> 14) << 16) | sel4;
|
||||||
uint16 count = sel6 & 0x3FFF;
|
uint16 count = sel6 & 0x3FFF;
|
||||||
sim_debug(DBG_INF, controller->device, "Completing Base In input transfer, base address=0x%08x count=%d\n", baseaddr, count);
|
sim_debug(DBG_INF, controller->device, "Completing Base In input transfer, base address=0x%08x count=%d\n", baseaddr, count);
|
||||||
//for (i = 0; i < count; i++)
|
//for (i = 0; i < count; i++)
|
||||||
|
@ -2020,7 +2047,7 @@ void dmc_process_input_transfer_completion(CTLR *controller)
|
||||||
}
|
}
|
||||||
else if (controller->transfer_type == TYPE_BACCI)
|
else if (controller->transfer_type == TYPE_BACCI)
|
||||||
{
|
{
|
||||||
uint32 addr = sel6 >> 14 | sel4;
|
uint32 addr = ((sel6 >> 14) << 16) | sel4;
|
||||||
uint16 count = sel6 & 0x3FFF;
|
uint16 count = sel6 & 0x3FFF;
|
||||||
if (controller->transfer_in_io != dmc_is_in_io_set(controller))
|
if (controller->transfer_in_io != dmc_is_in_io_set(controller))
|
||||||
{
|
{
|
||||||
|
|
|
@ -352,7 +352,7 @@ AUTO_CON auto_tab[] = {
|
||||||
{ { NULL }, 1, 2, 8, 8 }, /* DU11 */
|
{ { NULL }, 1, 2, 8, 8 }, /* DU11 */
|
||||||
{ { NULL }, 1, 2, 8, 8 }, /* DUP11 */
|
{ { NULL }, 1, 2, 8, 8 }, /* DUP11 */
|
||||||
{ { NULL }, 10, 2, 8, 8 }, /* LK11A */
|
{ { NULL }, 10, 2, 8, 8 }, /* LK11A */
|
||||||
{ { NULL }, 1, 2, 8, 8 }, /* DMC11 */
|
{ { "DMC" }, 1, 2, 8, 8 }, /* DMC11 */
|
||||||
{ { "DZ" }, DZ_MUXES, 2, 8, 8 }, /* DZ11 */
|
{ { "DZ" }, DZ_MUXES, 2, 8, 8 }, /* DZ11 */
|
||||||
{ { NULL }, 1, 2, 8, 8 }, /* KMC11 */
|
{ { NULL }, 1, 2, 8, 8 }, /* KMC11 */
|
||||||
{ { NULL }, 1, 2, 8, 8 }, /* LPP11 */
|
{ { NULL }, 1, 2, 8, 8 }, /* LPP11 */
|
||||||
|
|
|
@ -313,7 +313,7 @@ typedef struct {
|
||||||
#define IOLN_PTR 004
|
#define IOLN_PTR 004
|
||||||
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
|
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
|
||||||
#define IOLN_PTP 004
|
#define IOLN_PTP 004
|
||||||
#define IOBA_DMC (IOPAGEBASE + 0760060)
|
#define IOBA_DMC (IOPAGEBASE + 0760060) /* DMC11 */
|
||||||
#define IOLN_DMC 010
|
#define IOLN_DMC 010
|
||||||
|
|
||||||
/* Interrupt assignments; within each level, priority is right to left */
|
/* Interrupt assignments; within each level, priority is right to left */
|
||||||
|
|
Loading…
Add table
Reference in a new issue