From d51df0eba56181904ebaa68cbc9d8836a1f668f4 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Tue, 6 Nov 2012 17:00:54 -0800 Subject: [PATCH] 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 --- PDP11/pdp11_dmc.c | 3025 +++++++++++++++++++++--------------------- PDP11/pdp11_io_lib.c | 2 +- VAX/vax780_defs.h | 2 +- 3 files changed, 1528 insertions(+), 1501 deletions(-) diff --git a/PDP11/pdp11_dmc.c b/PDP11/pdp11_dmc.c index 7e420b83..3ed1bd42 100644 --- a/PDP11/pdp11_dmc.c +++ b/PDP11/pdp11_dmc.c @@ -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: Test MOP. // 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 #include @@ -83,118 +83,118 @@ The other test was to configure DECnet on VMS 4.6 and do SET HOST. #define TRACE_BYTES_PER_LINE 16 struct csrs { - uint16 sel0; - uint16 sel2; - uint16 sel4; - uint16 sel6; + uint16 sel0; + uint16 sel2; + uint16 sel4; + uint16 sel6; }; typedef struct csrs CSRS; typedef enum { - Initialised, /* after MASTER CLEAR */ - Running /* after any transmit or receive buffer has been supplied */ + Initialised, /* after MASTER CLEAR */ + Running /* after any transmit or receive buffer has been supplied */ } ControllerState; typedef enum { - Idle, - InputTransfer, - OutputTransfer + Idle, + InputTransfer, + OutputTransfer } TransferState; typedef enum { - Available, /* when empty or partially filled on read */ - ContainsData, - TransferInProgress + Available, /* when empty or partially filled on read */ + ContainsData, + TransferInProgress } BufferState; typedef struct { - int isPrimary; - SOCKET socket; // socket used bidirectionally - int receive_readable; - char *receive_port; - int transmit_writeable; - char transmit_host[80]; - int transmit_is_loopback; /* if true the transmit socket is the loopback to the receive */ - int speed; /* bits per second in each direction, 0 for no limit */ - int last_second; - int bytes_sent_in_last_second; - int bytes_received_in_last_second; - time_t last_connect_attempt; + int isPrimary; + SOCKET socket; // socket used bidirectionally + int receive_readable; + char *receive_port; + int transmit_writeable; + char transmit_host[80]; + int transmit_is_loopback; /* if true the transmit socket is the loopback to the receive */ + int speed; /* bits per second in each direction, 0 for no limit */ + int last_second; + int bytes_sent_in_last_second; + int bytes_received_in_last_second; + time_t last_connect_attempt; } LINE; /* A partially filled buffer (during a read from the socket) will have block_len_bytes_read = 1 or actual_bytes_transferred < actual_block_len */ typedef struct buffer { - uint32 address; /* unibus address of the buffer */ - uint16 count; /* size of the buffer passed to the device by the driver */ - uint16 actual_block_len; /* actual length of the received block */ - uint8 *transfer_buffer; /* the buffer into which data is received or from which it is transmitted*/ - int block_len_bytes_read; /* the number of bytes read so far for the block length */ - int actual_bytes_transferred; /* the number of bytes from the actual block that have been read or written so far*/ - struct buffer *next; /* next buffer in the queue */ - BufferState state; /* state of this buffer */ - int is_loopback; /* loopback was requested when this buffer was queued */ + uint32 address; /* unibus address of the buffer */ + uint16 count; /* size of the buffer passed to the device by the driver */ + uint16 actual_block_len; /* actual length of the received block */ + uint8 *transfer_buffer; /* the buffer into which data is received or from which it is transmitted*/ + int block_len_bytes_read; /* the number of bytes read so far for the block length */ + int actual_bytes_transferred; /* the number of bytes from the actual block that have been read or written so far*/ + struct buffer *next; /* next buffer in the queue */ + BufferState state; /* state of this buffer */ + int is_loopback; /* loopback was requested when this buffer was queued */ } BUFFER; typedef struct { - char * name; - BUFFER queue[BUFFER_QUEUE_SIZE]; - int head; - int tail; - int count; - struct dmc_controller *controller; /* back pointer to the containing controller */ + char * name; + BUFFER queue[BUFFER_QUEUE_SIZE]; + int head; + int tail; + int count; + struct dmc_controller *controller; /* back pointer to the containing controller */ } BUFFER_QUEUE; typedef struct { - int started; - clock_t start_time; - clock_t cumulative_time; + int started; + clock_t start_time; + clock_t cumulative_time; } TIMER; typedef struct { - TIMER between_polls_timer; - TIMER poll_timer; - uint32 poll_count; + TIMER between_polls_timer; + TIMER poll_timer; + uint32 poll_count; } UNIT_STATS; typedef enum { - DMC, - DMR, - DMP + DMC, + DMR, + DMP } DEVTYPE; struct dmc_controller { - CSRS *csrs; - DEVICE *device; - ControllerState state; - TransferState transfer_state; /* current transfer state (type of transfer) */ - int transfer_type; - int transfer_in_io; // remembers IN I/O setting at start of input transfer as host changes it during transfer! - LINE *line; - BUFFER_QUEUE *receive_queue; - BUFFER_QUEUE *transmit_queue; - SOCKET master_socket; - int32 svc_poll_interval; - int32 connect_poll_interval; - DEVTYPE dev_type; - uint32 rxi; - uint32 txi; - uint32 buffers_received_from_net; - uint32 buffers_transmitted_to_net; - uint32 receive_buffer_output_transfers_completed; - uint32 transmit_buffer_output_transfers_completed; - uint32 receive_buffer_input_transfers_completed; - uint32 transmit_buffer_input_transfers_completed; + CSRS *csrs; + DEVICE *device; + ControllerState state; + TransferState transfer_state; /* current transfer state (type of transfer) */ + int transfer_type; + int transfer_in_io; // remembers IN I/O setting at start of input transfer as host changes it during transfer! + LINE *line; + BUFFER_QUEUE *receive_queue; + BUFFER_QUEUE *transmit_queue; + SOCKET master_socket; + int32 svc_poll_interval; + int32 connect_poll_interval; + DEVTYPE dev_type; + uint32 rxi; + uint32 txi; + uint32 buffers_received_from_net; + uint32 buffers_transmitted_to_net; + uint32 receive_buffer_output_transfers_completed; + uint32 transmit_buffer_output_transfers_completed; + uint32 receive_buffer_input_transfers_completed; + uint32 transmit_buffer_input_transfers_completed; }; typedef struct dmc_controller CTLR; @@ -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_start_transfer_transmit_buffer(CTLR *controller); 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); int dmc_get_socket(CTLR *controller, int forRead); int dmc_get_receive_socket(CTLR *controller, int forRead); @@ -246,26 +246,26 @@ UNIT_STATS *dmc_get_unit_stats(UNIT *uptr); void dmc_set_unit_stats(UNIT *uptr, UNIT_STATS *stats); DEBTAB dmc_debug[] = { - {"TRACE", DBG_TRC}, - {"WARN", DBG_WRN}, - {"REG", DBG_REG}, - {"INFO", DBG_INF}, - {"DATA", DBG_DAT}, - {"DATASUM",DBG_DTS}, - {"SOCKET", DBG_SOK}, - {"CONNECT", DBG_CON}, - {0} + {"TRACE", DBG_TRC}, + {"WARN", DBG_WRN}, + {"REG", DBG_REG}, + {"INFO", DBG_INF}, + {"DATA", DBG_DAT}, + {"DATASUM",DBG_DTS}, + {"SOCKET", DBG_SOK}, + {"CONNECT", DBG_CON}, + {0} }; UNIT dmc_unit[] = { - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) } + { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, + { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, + { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) }, + { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) } }; UNIT dmp_unit[] = { - { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) } + { UDATA (&dmc_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE, 0) } }; CSRS dmc_csrs[DMC_NUMDEVICE]; @@ -273,164 +273,175 @@ CSRS dmc_csrs[DMC_NUMDEVICE]; CSRS dmp_csrs[DMP_NUMDEVICE]; REG dmca_reg[] = { - { HRDATA (SEL0, dmc_csrs[0].sel0, 16) }, - { HRDATA (SEL2, dmc_csrs[0].sel2, 16) }, - { HRDATA (SEL4, dmc_csrs[0].sel4, 16) }, - { HRDATA (SEL6, dmc_csrs[0].sel6, 16) }, - { GRDATA (BSEL0, dmc_csrs[0].sel0, DEV_RDX, 8, 0) }, - { GRDATA (BSEL1, dmc_csrs[0].sel0, DEV_RDX, 8, 8) }, - { GRDATA (BSEL2, dmc_csrs[0].sel2, DEV_RDX, 8, 0) }, - { GRDATA (BSEL3, dmc_csrs[0].sel2, DEV_RDX, 8, 8) }, - { GRDATA (BSEL4, dmc_csrs[0].sel4, DEV_RDX, 8, 0) }, - { 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) }, - { NULL } }; + { HRDATA (SEL0, dmc_csrs[0].sel0, 16) }, + { HRDATA (SEL2, dmc_csrs[0].sel2, 16) }, + { HRDATA (SEL4, dmc_csrs[0].sel4, 16) }, + { HRDATA (SEL6, dmc_csrs[0].sel6, 16) }, + { GRDATA (BSEL0, dmc_csrs[0].sel0, DEV_RDX, 8, 0) }, + { GRDATA (BSEL1, dmc_csrs[0].sel0, DEV_RDX, 8, 8) }, + { GRDATA (BSEL2, dmc_csrs[0].sel2, DEV_RDX, 8, 0) }, + { GRDATA (BSEL3, dmc_csrs[0].sel2, DEV_RDX, 8, 8) }, + { GRDATA (BSEL4, dmc_csrs[0].sel4, DEV_RDX, 8, 0) }, + { 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) }, + { NULL } }; REG dmcb_reg[] = { - { HRDATA (SEL0, dmc_csrs[1].sel0, 16) }, - { HRDATA (SEL2, dmc_csrs[1].sel2, 16) }, - { HRDATA (SEL4, dmc_csrs[1].sel4, 16) }, - { HRDATA (SEL6, dmc_csrs[1].sel6, 16) }, - { GRDATA (BSEL0, dmc_csrs[1].sel0, DEV_RDX, 8, 0) }, - { GRDATA (BSEL1, dmc_csrs[1].sel0, DEV_RDX, 8, 8) }, - { GRDATA (BSEL2, dmc_csrs[1].sel2, DEV_RDX, 8, 0) }, - { GRDATA (BSEL3, dmc_csrs[1].sel2, DEV_RDX, 8, 8) }, - { GRDATA (BSEL4, dmc_csrs[1].sel4, DEV_RDX, 8, 0) }, - { 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) }, - { NULL } }; + { HRDATA (SEL0, dmc_csrs[1].sel0, 16) }, + { HRDATA (SEL2, dmc_csrs[1].sel2, 16) }, + { HRDATA (SEL4, dmc_csrs[1].sel4, 16) }, + { HRDATA (SEL6, dmc_csrs[1].sel6, 16) }, + { GRDATA (BSEL0, dmc_csrs[1].sel0, DEV_RDX, 8, 0) }, + { GRDATA (BSEL1, dmc_csrs[1].sel0, DEV_RDX, 8, 8) }, + { GRDATA (BSEL2, dmc_csrs[1].sel2, DEV_RDX, 8, 0) }, + { GRDATA (BSEL3, dmc_csrs[1].sel2, DEV_RDX, 8, 8) }, + { GRDATA (BSEL4, dmc_csrs[1].sel4, DEV_RDX, 8, 0) }, + { 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) }, + { NULL } }; REG dmcc_reg[] = { - { HRDATA (SEL0, dmc_csrs[2].sel0, 16) }, - { HRDATA (SEL2, dmc_csrs[2].sel2, 16) }, - { HRDATA (SEL4, dmc_csrs[2].sel4, 16) }, - { HRDATA (SEL6, dmc_csrs[2].sel6, 16) }, - { GRDATA (BSEL0, dmc_csrs[2].sel0, DEV_RDX, 8, 0) }, - { GRDATA (BSEL1, dmc_csrs[2].sel0, DEV_RDX, 8, 8) }, - { GRDATA (BSEL2, dmc_csrs[2].sel2, DEV_RDX, 8, 0) }, - { GRDATA (BSEL3, dmc_csrs[2].sel2, DEV_RDX, 8, 8) }, - { GRDATA (BSEL4, dmc_csrs[2].sel4, DEV_RDX, 8, 0) }, - { 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) }, - { NULL } }; + { HRDATA (SEL0, dmc_csrs[2].sel0, 16) }, + { HRDATA (SEL2, dmc_csrs[2].sel2, 16) }, + { HRDATA (SEL4, dmc_csrs[2].sel4, 16) }, + { HRDATA (SEL6, dmc_csrs[2].sel6, 16) }, + { GRDATA (BSEL0, dmc_csrs[2].sel0, DEV_RDX, 8, 0) }, + { GRDATA (BSEL1, dmc_csrs[2].sel0, DEV_RDX, 8, 8) }, + { GRDATA (BSEL2, dmc_csrs[2].sel2, DEV_RDX, 8, 0) }, + { GRDATA (BSEL3, dmc_csrs[2].sel2, DEV_RDX, 8, 8) }, + { GRDATA (BSEL4, dmc_csrs[2].sel4, DEV_RDX, 8, 0) }, + { 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) }, + { NULL } }; REG dmcd_reg[] = { - { HRDATA (SEL0, dmc_csrs[3].sel0, 16) }, - { HRDATA (SEL2, dmc_csrs[3].sel2, 16) }, - { HRDATA (SEL4, dmc_csrs[3].sel4, 16) }, - { HRDATA (SEL6, dmc_csrs[3].sel6, 16) }, - { GRDATA (BSEL0, dmc_csrs[3].sel0, DEV_RDX, 8, 0) }, - { GRDATA (BSEL1, dmc_csrs[3].sel0, DEV_RDX, 8, 8) }, - { GRDATA (BSEL2, dmc_csrs[3].sel2, DEV_RDX, 8, 0) }, - { GRDATA (BSEL3, dmc_csrs[3].sel2, DEV_RDX, 8, 8) }, - { GRDATA (BSEL4, dmc_csrs[3].sel4, DEV_RDX, 8, 0) }, - { 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) }, - { NULL } }; + { HRDATA (SEL0, dmc_csrs[3].sel0, 16) }, + { HRDATA (SEL2, dmc_csrs[3].sel2, 16) }, + { HRDATA (SEL4, dmc_csrs[3].sel4, 16) }, + { HRDATA (SEL6, dmc_csrs[3].sel6, 16) }, + { GRDATA (BSEL0, dmc_csrs[3].sel0, DEV_RDX, 8, 0) }, + { GRDATA (BSEL1, dmc_csrs[3].sel0, DEV_RDX, 8, 8) }, + { GRDATA (BSEL2, dmc_csrs[3].sel2, DEV_RDX, 8, 0) }, + { GRDATA (BSEL3, dmc_csrs[3].sel2, DEV_RDX, 8, 8) }, + { GRDATA (BSEL4, dmc_csrs[3].sel4, DEV_RDX, 8, 0) }, + { 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) }, + { NULL } }; REG dmp_reg[] = { - { HRDATA (SEL0, dmc_csrs[3].sel0, 16) }, - { HRDATA (SEL2, dmc_csrs[3].sel2, 16) }, - { HRDATA (SEL4, dmc_csrs[3].sel4, 16) }, - { HRDATA (SEL6, dmc_csrs[3].sel6, 16) }, - { GRDATA (BSEL0, dmc_csrs[3].sel0, DEV_RDX, 8, 0) }, - { GRDATA (BSEL1, dmc_csrs[3].sel0, DEV_RDX, 8, 8) }, - { GRDATA (BSEL2, dmc_csrs[3].sel2, DEV_RDX, 8, 0) }, - { GRDATA (BSEL3, dmc_csrs[3].sel2, DEV_RDX, 8, 8) }, - { GRDATA (BSEL4, dmc_csrs[3].sel4, DEV_RDX, 8, 0) }, - { 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) }, - { NULL } }; + { HRDATA (SEL0, dmc_csrs[3].sel0, 16) }, + { HRDATA (SEL2, dmc_csrs[3].sel2, 16) }, + { HRDATA (SEL4, dmc_csrs[3].sel4, 16) }, + { HRDATA (SEL6, dmc_csrs[3].sel6, 16) }, + { GRDATA (BSEL0, dmc_csrs[3].sel0, DEV_RDX, 8, 0) }, + { GRDATA (BSEL1, dmc_csrs[3].sel0, DEV_RDX, 8, 8) }, + { GRDATA (BSEL2, dmc_csrs[3].sel2, DEV_RDX, 8, 0) }, + { GRDATA (BSEL3, dmc_csrs[3].sel2, DEV_RDX, 8, 8) }, + { GRDATA (BSEL4, dmc_csrs[3].sel4, DEV_RDX, 8, 0) }, + { 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) }, + { NULL } }; MTAB dmc_mod[] = { - { MTAB_XTD | MTAB_VDV, 0, "TRANSMIT", "TRANSMIT=address:port" ,&dmc_settransmit, &dmc_showtransmit, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "SPEED", "SPEED" ,&dmc_setspeed, &dmc_showspeed, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "TYPE", "TYPE" ,&dmc_settype, &dmc_showtype, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "LINEMODE", "LINEMODE" ,&dmc_setlinemode, &dmc_showlinemode, NULL }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATS", "STATS" ,&dmc_setstats, &dmc_showstats, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "POLL", "POLL" ,&dmc_setpoll, &dmc_showpoll, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "CONNECTPOLL", "CONNECTPOLL" ,&dmc_setconnectpoll, &dmc_showconnectpoll, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "TRANSMIT", "TRANSMIT=address:port" ,&dmc_settransmit, &dmc_showtransmit, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "SPEED", "SPEED" ,&dmc_setspeed, &dmc_showspeed, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "TYPE", "TYPE" ,&dmc_settype, &dmc_showtype, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "LINEMODE", "LINEMODE" ,&dmc_setlinemode, &dmc_showlinemode, NULL }, + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATS", "STATS" ,&dmc_setstats, &dmc_showstats, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "POLL", "POLL" ,&dmc_setpoll, &dmc_showpoll, NULL }, + { MTAB_XTD | MTAB_VDV, 0, "CONNECTPOLL", "CONNECTPOLL" ,&dmc_setconnectpoll, &dmc_showconnectpoll, NULL }, { MTAB_XTD | MTAB_VDV, 006, "ADDRESS", "ADDRESS", &set_addr, &show_addr, NULL }, { MTAB_XTD |MTAB_VDV, 0, "VECTOR", "VECTOR", &set_vec, &show_vec, NULL }, - { 0 }, + { 0 }, }; DIB dmc_dib[] = { - { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} }, - { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} }, - { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} }, - { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} } + { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} }, + { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} }, + { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} }, + { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} } }; DIB dmp_dib[] = { - { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} } + { IOBA_DMC, IOLN_DMC, &dmc_rd, &dmc_wr, 2, IVCL (DMCRX), VEC_DMCRX, {&dmc_rxint, &dmc_txint} } }; DEVICE dmc_dev[] = { - { "DMA", &dmc_unit[0], dmca_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, - NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc_dib[0], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, - { "DMB", &dmc_unit[1], dmcb_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, - NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc_dib[1], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, - { "DMC", &dmc_unit[2], dmcc_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, - NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc_dib[2], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, - { "DMD", &dmc_unit[3], dmcd_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, - NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmc_dib[3], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug } + { "DMA", &dmc_unit[0], dmca_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, + &dmc_dib[0], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, + { "DMB", &dmc_unit[1], dmcb_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, + &dmc_dib[1], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, + { "DMC", &dmc_unit[2], dmcc_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, + &dmc_dib[2], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug }, + { "DMD", &dmc_unit[3], dmcd_reg, dmc_mod, DMC_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, + &dmc_dib[3], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug } }; DEVICE dmp_dev[] = { - { "DMP", &dmp_unit[0], dmp_reg, dmc_mod, DMP_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, - NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, - &dmp_dib[0], DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_NET | DEV_DEBUG, 0, dmc_debug } + { "DMP", &dmp_unit[0], dmp_reg, dmc_mod, DMP_UNITSPERDEVICE, DMC_RDX, 8, 1, DMC_RDX, 8, + NULL,NULL,&dmc_reset,NULL,&dmc_attach,&dmc_detach, + &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_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_transmit_queues[DMP_NUMDEVICE]; CTLR dmc_ctrls[] = { - { &dmc_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], INVALID_SOCKET, -1, 30, DMC }, - { &dmc_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], INVALID_SOCKET, -1, 30, DMC }, - { &dmc_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], INVALID_SOCKET, -1, 30, DMC }, - { &dmc_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], INVALID_SOCKET, -1, 30, DMC }, - { &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 } + { &dmc_csrs[0], &dmc_dev[0], Initialised, Idle, 0, 0, &dmc_line[0], &dmc_receive_queues[0], &dmc_transmit_queues[0], INVALID_SOCKET, -1, 30, DMC }, + { &dmc_csrs[1], &dmc_dev[1], Initialised, Idle, 0, 0, &dmc_line[1], &dmc_receive_queues[1], &dmc_transmit_queues[1], INVALID_SOCKET, -1, 30, DMC }, + { &dmc_csrs[2], &dmc_dev[2], Initialised, Idle, 0, 0, &dmc_line[2], &dmc_receive_queues[2], &dmc_transmit_queues[2], INVALID_SOCKET, -1, 30, DMC }, + { &dmc_csrs[3], &dmc_dev[3], Initialised, Idle, 0, 0, &dmc_line[3], &dmc_receive_queues[3], &dmc_transmit_queues[3], INVALID_SOCKET, -1, 30, DMC }, + { &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 *ans = NULL; + UNIT_STATS *ans = NULL; #ifdef USE_ADDR64 - ans = (UNIT_STATS *)(((t_uint64)uptr->u3 << 32) | uptr->u4); + ans = (UNIT_STATS *)(((t_uint64)uptr->u3 << 32) | uptr->u4); #else ans = (UNIT_STATS *)(uptr->u3); #endif - return ans; + return ans; } void dmc_set_unit_stats(UNIT *uptr, UNIT_STATS *stats) { #ifdef USE_ADDR64 - uptr->u3 = (int32)((t_uint64)stats >> 32); - uptr->u4 = (int32)((t_uint64)stats & 0xFFFFFFFF); + uptr->u3 = (int32)((t_uint64)stats >> 32); + uptr->u4 = (int32)((t_uint64)stats & 0xFFFFFFFF); #else uptr->u3 = (int32)stats; #endif @@ -439,238 +450,238 @@ void dmc_set_unit_stats(UNIT *uptr, UNIT_STATS *stats) void dmc_reset_unit_stats(UNIT_STATS *s) { s->between_polls_timer.started = FALSE; - s->poll_timer.started = FALSE; - s->poll_count = 0; + s->poll_timer.started = FALSE; + s->poll_count = 0; } int dmc_timer_started(TIMER *t) { - return t->started; + return t->started; } void dmc_timer_start(TIMER *t) { - t->start_time = clock(); - t->cumulative_time = 0; - t->started = TRUE; + t->start_time = clock(); + t->cumulative_time = 0; + t->started = TRUE; } void dmc_timer_stop(TIMER *t) { - clock_t end_time = clock(); - t->cumulative_time += end_time - t->start_time; + clock_t end_time = clock(); + t->cumulative_time += end_time - t->start_time; } void dmc_timer_resume(TIMER *t) { - t->start_time = clock(); + t->start_time = clock(); } double dmc_timer_cumulative_seconds(TIMER *t) { - return (double)t->cumulative_time/CLOCKS_PER_SEC; + return (double)t->cumulative_time/CLOCKS_PER_SEC; } int dmc_is_dmc(CTLR *controller) { - return controller->dev_type != DMP; + return controller->dev_type != DMP; } CTLR *dmc_get_controller_from_unit(UNIT *unit) { - int i; - CTLR *ans = NULL; - for (i = 0; i < DMC_NUMDEVICE + DMP_NUMDEVICE; i++) - { - if (dmc_ctrls[i].device->units == unit) - { - ans = &dmc_ctrls[i]; - break; - } - } + int i; + CTLR *ans = NULL; + for (i = 0; i < DMC_NUMDEVICE + DMP_NUMDEVICE; i++) + { + if (dmc_ctrls[i].device->units == unit) + { + ans = &dmc_ctrls[i]; + break; + } + } - return ans; + return ans; } CTLR* dmc_get_controller_from_address(uint32 address) { - int i; - for (i=0; ictxt; - if ((address >= dib->ba) && (address < (dib->ba + dib->lnt))) - return &dmc_ctrls[i]; - } - /* not found */ - return 0; + int i; + for (i=0; ictxt; + if ((address >= dib->ba) && (address < (dib->ba + dib->lnt))) + return &dmc_ctrls[i]; + } + /* not found */ + return 0; } CTLR *dmc_get_controller_from_device(DEVICE *device) { - int i; - CTLR *ans = NULL; - for (i = 0; i < DMC_NUMDEVICE + DMP_NUMDEVICE; i++) - { - if (dmc_ctrls[i].device == device) - { - ans = &dmc_ctrls[i]; - break; - } - } + int i; + CTLR *ans = NULL; + for (i = 0; i < DMC_NUMDEVICE + DMP_NUMDEVICE; i++) + { + if (dmc_ctrls[i].device == device) + { + ans = &dmc_ctrls[i]; + break; + } + } - return ans; + return ans; } t_stat dmc_showtransmit (FILE* st, UNIT* uptr, int32 val, void* desc) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - fprintf(st, "TRANSMIT=%s", controller->line->transmit_host); - return SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); + fprintf(st, "TRANSMIT=%s", controller->line->transmit_host); + return SCPE_OK; } t_stat dmc_settransmit (UNIT* uptr, int32 val, char* cptr, void* desc) { - t_stat status = SCPE_OK; + t_stat status = SCPE_OK; char host[CBUFSIZE], port[CBUFSIZE]; - CTLR *controller = dmc_get_controller_from_unit(uptr); + CTLR *controller = dmc_get_controller_from_unit(uptr); - if (!cptr) return SCPE_IERR; - if (uptr->flags & UNIT_ATT) return SCPE_ALATT; + if (!cptr) return SCPE_IERR; + if (uptr->flags & UNIT_ATT) return SCPE_ALATT; status = sim_parse_addr (cptr, host, sizeof(host), NULL, port, sizeof(port), NULL); if (status != SCPE_OK) return status; if (host[0] == '\0') return SCPE_ARG; - strncpy(controller->line->transmit_host, cptr, sizeof(controller->line->transmit_host)-1); + strncpy(controller->line->transmit_host, cptr, sizeof(controller->line->transmit_host)-1); - return status; + return status; } t_stat dmc_showspeed (FILE* st, UNIT* uptr, int32 val, void* desc) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - fprintf(st, "SPEED=%d", controller->line->speed); - return SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); + fprintf(st, "SPEED=%d", controller->line->speed); + return SCPE_OK; } t_stat dmc_setspeed (UNIT* uptr, int32 val, char* cptr, void* desc) { - t_stat status = SCPE_OK; - CTLR *controller = dmc_get_controller_from_unit(uptr); + t_stat status = SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); - if (!cptr) return SCPE_IERR; - if (uptr->flags & UNIT_ATT) return SCPE_ALATT; - if (sscanf(cptr, "%d", &controller->line->speed) != 1) - { - status = SCPE_ARG; - } + if (!cptr) return SCPE_IERR; + if (uptr->flags & UNIT_ATT) return SCPE_ALATT; + if (sscanf(cptr, "%d", &controller->line->speed) != 1) + { + status = SCPE_ARG; + } - return status; + return status; } t_stat dmc_showtype (FILE* st, UNIT* uptr, int32 val, void* desc) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - switch (controller->dev_type) - { - case DMC: - { - fprintf(st, "TYPE=DMC"); - break; - } - case DMR: - { - fprintf(st, "TYPE=DMR"); - break; - } - case DMP: - { - fprintf(st, "TYPE=DMP"); - break; - } - default: - { - fprintf(st, "TYPE=???"); - break; - } - } - return SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); + switch (controller->dev_type) + { + case DMC: + { + fprintf(st, "TYPE=DMC"); + break; + } + case DMR: + { + fprintf(st, "TYPE=DMR"); + break; + } + case DMP: + { + fprintf(st, "TYPE=DMP"); + break; + } + default: + { + fprintf(st, "TYPE=???"); + break; + } + } + return SCPE_OK; } t_stat dmc_settype (UNIT* uptr, int32 val, char* cptr, void* desc) { - char buf[80]; - t_stat status = SCPE_OK; - CTLR *controller = dmc_get_controller_from_unit(uptr); + char buf[80]; + t_stat status = SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); - if (!cptr) return SCPE_IERR; - if (uptr->flags & UNIT_ATT) return SCPE_ALATT; - if (sscanf(cptr, "%s", buf) != 1) - { - status = SCPE_ARG; - } - else - { - if (strcmp(buf,"DMC")==0) - { - controller->dev_type = DMC; - } - else if (strcmp(buf,"DMR")==0) - { - controller->dev_type = DMR; - } - else if (strcmp(buf,"DMP")==0) - { - controller->dev_type = DMP; - } - else - { - status = SCPE_ARG; - } - } + if (!cptr) return SCPE_IERR; + if (uptr->flags & UNIT_ATT) return SCPE_ALATT; + if (sscanf(cptr, "%s", buf) != 1) + { + status = SCPE_ARG; + } + else + { + if (strcmp(buf,"DMC")==0) + { + controller->dev_type = DMC; + } + else if (strcmp(buf,"DMR")==0) + { + controller->dev_type = DMR; + } + else if (strcmp(buf,"DMP")==0) + { + controller->dev_type = DMP; + } + else + { + status = SCPE_ARG; + } + } - return status; + return status; } t_stat dmc_showstats (FILE* st, UNIT* uptr, int32 val, void* desc) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; - TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer; - uint32 poll_count = dmc_get_unit_stats(uptr)->poll_count; + CTLR *controller = dmc_get_controller_from_unit(uptr); + TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; + TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer; + uint32 poll_count = dmc_get_unit_stats(uptr)->poll_count; - if (dmc_timer_started(between_polls_timer) && poll_count > 0) - { - fprintf(st, "Average time between polls=%f (sec)\n", dmc_timer_cumulative_seconds(between_polls_timer)/poll_count); - } - else - { - fprintf(st, "Average time between polls=n/a\n"); - } + if (dmc_timer_started(between_polls_timer) && poll_count > 0) + { + fprintf(st, "Average time between polls=%f (sec)\n", dmc_timer_cumulative_seconds(between_polls_timer)/poll_count); + } + else + { + fprintf(st, "Average time between polls=n/a\n"); + } - if (dmc_timer_started(poll_timer) && poll_count > 0) - { - fprintf(st, "Average time within poll=%f (sec)\n", dmc_timer_cumulative_seconds(poll_timer)/poll_count); - } - else - { - fprintf(st, "Average time within poll=n/a\n"); - } + if (dmc_timer_started(poll_timer) && poll_count > 0) + { + fprintf(st, "Average time within poll=%f (sec)\n", dmc_timer_cumulative_seconds(poll_timer)/poll_count); + } + else + { + fprintf(st, "Average time within poll=n/a\n"); + } - fprintf(st, "Buffers received from the network=%d\n", controller->buffers_received_from_net); - fprintf(st, "Buffers sent to the network=%d\n", controller->buffers_transmitted_to_net); - fprintf(st, "Output transfers completed for receive buffers=%d\n", controller->receive_buffer_output_transfers_completed); - fprintf(st, "Output transfers completed for transmit buffers=%d\n", controller->transmit_buffer_output_transfers_completed); - fprintf(st, "Input transfers completed for receive buffers=%d\n", controller->receive_buffer_input_transfers_completed); - fprintf(st, "Input transfers completed for transmit buffers=%d\n", controller->transmit_buffer_input_transfers_completed); + fprintf(st, "Buffers received from the network=%d\n", controller->buffers_received_from_net); + fprintf(st, "Buffers sent to the network=%d\n", controller->buffers_transmitted_to_net); + fprintf(st, "Output transfers completed for receive buffers=%d\n", controller->receive_buffer_output_transfers_completed); + fprintf(st, "Output transfers completed for transmit buffers=%d\n", controller->transmit_buffer_output_transfers_completed); + fprintf(st, "Input transfers completed for receive buffers=%d\n", controller->receive_buffer_input_transfers_completed); + fprintf(st, "Input transfers completed for transmit buffers=%d\n", controller->transmit_buffer_input_transfers_completed); - return SCPE_OK; + return SCPE_OK; } t_stat dmc_setstats (UNIT* uptr, int32 val, char* cptr, void* desc) { - t_stat status = SCPE_OK; - CTLR *controller = dmc_get_controller_from_unit(uptr); + t_stat status = SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); dmc_reset_unit_stats(dmc_get_unit_stats(uptr)); @@ -679,1595 +690,1611 @@ t_stat dmc_setstats (UNIT* uptr, int32 val, char* cptr, void* desc) controller->receive_buffer_input_transfers_completed = 0; controller->transmit_buffer_input_transfers_completed = 0; - printf("Statistics reset\n" ); + printf("Statistics reset\n" ); - return status; + return status; } t_stat dmc_showpoll (FILE* st, UNIT* uptr, int32 val, void* desc) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - fprintf(st, "POLL=%d", controller->svc_poll_interval); - return SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); + fprintf(st, "POLL=%d", controller->svc_poll_interval); + return SCPE_OK; } t_stat dmc_setpoll (UNIT* uptr, int32 val, char* cptr, void* desc) { - t_stat status = SCPE_OK; - CTLR *controller = dmc_get_controller_from_unit(uptr); + t_stat status = SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); - if (!cptr) return SCPE_IERR; - if (sscanf(cptr, "%d", &controller->svc_poll_interval) != 1) - { - status = SCPE_ARG; - } + if (!cptr) return SCPE_IERR; + if (sscanf(cptr, "%d", &controller->svc_poll_interval) != 1) + { + status = SCPE_ARG; + } - return status; + return status; } t_stat dmc_showconnectpoll (FILE* st, UNIT* uptr, int32 val, void* desc) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - fprintf(st, "CONNECTPOLL=%d", controller->connect_poll_interval); - return SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); + fprintf(st, "CONNECTPOLL=%d", controller->connect_poll_interval); + return SCPE_OK; } t_stat dmc_setconnectpoll (UNIT* uptr, int32 val, char* cptr, void* desc) { - t_stat status = SCPE_OK; - CTLR *controller = dmc_get_controller_from_unit(uptr); + t_stat status = SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); - if (!cptr) return SCPE_IERR; - if (sscanf(cptr, "%d", &controller->connect_poll_interval) != 1) - { - status = SCPE_ARG; - } + if (!cptr) return SCPE_IERR; + if (sscanf(cptr, "%d", &controller->connect_poll_interval) != 1) + { + status = SCPE_ARG; + } - return status; + return status; } t_stat dmc_showlinemode (FILE* st, UNIT* uptr, int32 val, void* desc) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - fprintf(st, "LINEMODE=%s", controller->line->isPrimary? "PRIMARY" : "SECONDARY"); - return SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); + fprintf(st, "LINEMODE=%s", controller->line->isPrimary? "PRIMARY" : "SECONDARY"); + return SCPE_OK; } t_stat dmc_setlinemode (UNIT* uptr, int32 val, char* cptr, void* desc) { - t_stat status = SCPE_OK; - CTLR *controller = dmc_get_controller_from_unit(uptr); + t_stat status = SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); - if (!cptr) return SCPE_IERR; - if (uptr->flags & UNIT_ATT) return SCPE_ALATT; + if (!cptr) return SCPE_IERR; + if (uptr->flags & UNIT_ATT) return SCPE_ALATT; - if (strcmp(cptr, "PRIMARY") == 0) - { - controller->line->isPrimary = 1; - } - else if (strcmp(cptr, "SECONDARY") == 0) - { - controller->line->isPrimary = 0; - } - else - { - status = SCPE_ARG; - } + if (MATCH_CMD(cptr, "PRIMARY") == 0) + { + controller->line->isPrimary = 1; + } + else if (MATCH_CMD(cptr, "SECONDARY") == 0) + { + controller->line->isPrimary = 0; + } + else + { + status = SCPE_ARG; + } - return status; + return status; } void dmc_setrxint(CTLR *controller) { - controller->rxi = 1; - SET_INT(DMCRX); + controller->rxi = 1; + SET_INT(DMCRX); } void dmc_clrrxint(CTLR *controller) { - controller->rxi = 0; - CLR_INT(DMCRX); + controller->rxi = 0; + CLR_INT(DMCRX); } void dmc_settxint(CTLR *controller) { - controller->txi = 1; - SET_INT(DMCTX); + controller->txi = 1; + SET_INT(DMCTX); } void dmc_clrtxint(CTLR *controller) { - controller->txi = 0; - CLR_INT(DMCTX); + controller->txi = 0; + CLR_INT(DMCTX); } int dmc_getsel(int addr) { - return (addr >> 1) & 03; + return (addr >> 1) & 03; } uint16 dmc_bitfld(int data, int start_bit, int length) { - uint16 ans = data >> start_bit; - uint32 mask = (1 << (length))-1; - ans &= mask; - return ans; + uint16 ans = data >> start_bit; + uint32 mask = (1 << (length))-1; + ans &= mask; + return ans; } void dmc_dumpregsel0(CTLR *controller, int trace_level, char * prefix, uint16 data) { - char *type_str = ""; - uint16 type = dmc_bitfld(data, SEL0_TYPEI_BIT, 2); + char *type_str = ""; + uint16 type = dmc_bitfld(data, SEL0_TYPEI_BIT, 2); - if (dmc_is_dmc(controller)) - { - if (dmc_is_rqi_set(controller)) - { - if (type==TYPE_BACCI) - type_str = "BA/CC I"; - else if (type==TYPE_CNTLI) - type_str = "CNTL I"; - else if (type==TYPE_BASEI) - type_str = "BASE I"; - else - type_str = "?????"; - } + if (dmc_is_dmc(controller)) + { + if (dmc_is_rqi_set(controller)) + { + if (type==TYPE_BACCI) + type_str = "BA/CC I"; + else if (type==TYPE_CNTLI) + type_str = "CNTL I"; + else if (type==TYPE_BASEI) + type_str = "BASE I"; + else + type_str = "?????"; + } - sim_debug( - trace_level, - controller->device, - "%s SEL0 (0x%04x) %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_RDI_BIT, 1) ? "RDI " : "", - dmc_bitfld(data, SEL0_DMC_IEI_BIT, 1) ? "IEI " : "", - dmc_bitfld(data, SEL0_DMC_RQI_BIT, 1) ? "RQI " : "", - dmc_bitfld(data, SEL0_IN_IO_BIT, 1) ? "IN I/O " : "", - type_str - ); - } - else - { - sim_debug( - trace_level, - controller->device, - "%s SEL0 (0x%04x) %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_DMP_RQI_BIT, 1) ? "RQI " : "", - dmc_bitfld(data, SEL0_DMP_IEO_BIT, 1) ? "IEO " : "", - dmc_bitfld(data, SEL0_DMP_IEI_BIT, 1) ? "IEI " : "" - ); - } + sim_debug( + trace_level, + controller->device, + "%s SEL0 (0x%04x) %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_RDI_BIT, 1) ? "RDI " : "", + dmc_bitfld(data, SEL0_DMC_IEI_BIT, 1) ? "IEI " : "", + dmc_bitfld(data, SEL0_DMC_RQI_BIT, 1) ? "RQI " : "", + dmc_bitfld(data, SEL0_IN_IO_BIT, 1) ? "IN I/O " : "", + type_str + ); + } + else + { + sim_debug( + trace_level, + controller->device, + "%s SEL0 (0x%04x) %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_DMP_RQI_BIT, 1) ? "RQI " : "", + dmc_bitfld(data, SEL0_DMP_IEO_BIT, 1) ? "IEO " : "", + dmc_bitfld(data, SEL0_DMP_IEI_BIT, 1) ? "IEI " : "" + ); + } } void dmc_dumpregsel2(CTLR *controller, int trace_level, char *prefix, uint16 data) { - char *type_str = ""; - uint16 type = dmc_bitfld(data, SEL2_TYPEO_BIT, 2); + char *type_str = ""; + uint16 type = dmc_bitfld(data, SEL2_TYPEO_BIT, 2); - if (type==TYPE_BACCO) - type_str = "BA/CC O"; - else if (type==TYPE_CNTLO) - type_str = "CNTL O"; - else - type_str = "?????"; + if (type==TYPE_BACCO) + type_str = "BA/CC O"; + else if (type==TYPE_CNTLO) + type_str = "CNTL O"; + else + type_str = "?????"; - sim_debug( - trace_level, - controller->device, - "%s SEL2 (0x%04x) PRIO=%d LINE=%d %s%s%s%s\n", - prefix, - data, - dmc_bitfld(data, SEL2_PRIO_BIT, SEL2_PRIO_BIT_LENGTH), - dmc_bitfld(data, SEL2_LINE_BIT, SEL2_LINE_BIT_LENGTH), - dmc_bitfld(data, SEL2_RDO_BIT, 1) ? "RDO " : "", - dmc_bitfld(data, SEL2_IEO_BIT, 1) ? "IEO " : "", - dmc_bitfld(data, SEL2_OUT_IO_BIT, 1) ? "OUT I/O " : "", - type_str - ); + sim_debug( + trace_level, + controller->device, + "%s SEL2 (0x%04x) PRIO=%d LINE=%d %s%s%s%s\n", + prefix, + data, + dmc_bitfld(data, SEL2_PRIO_BIT, SEL2_PRIO_BIT_LENGTH), + dmc_bitfld(data, SEL2_LINE_BIT, SEL2_LINE_BIT_LENGTH), + dmc_bitfld(data, SEL2_RDO_BIT, 1) ? "RDO " : "", + dmc_bitfld(data, SEL2_IEO_BIT, 1) ? "IEO " : "", + dmc_bitfld(data, SEL2_OUT_IO_BIT, 1) ? "OUT I/O " : "", + type_str + ); } void dmc_dumpregsel4(CTLR *controller, int trace_level, char *prefix, uint16 data) { - sim_debug(trace_level, controller->device, "%s SEL4 (0x%04x)\n", prefix, data); + sim_debug(trace_level, controller->device, "%s SEL4 (0x%04x)\n", prefix, data); } void dmc_dumpregsel6(CTLR *controller, int trace_level, char *prefix, uint16 data) { - sim_debug( - trace_level, - controller->device, - "%s SEL6 (0x%04x) %s\n", - prefix, - data, - dmc_bitfld(data, SEL6_LOST_DATA_BIT, 1) ? "LOST_DATA " : ""); + sim_debug( + trace_level, + controller->device, + "%s SEL6 (0x%04x) %s\n", + prefix, + data, + dmc_bitfld(data, SEL6_LOST_DATA_BIT, 1) ? "LOST_DATA " : ""); } uint16 dmc_getreg(CTLR *controller, int reg, int ext) { - uint16 ans = 0; - switch (dmc_getsel(reg)) - { - case 00: - ans = controller->csrs->sel0; - if (ext) dmc_dumpregsel0(controller, DBG_REG, "Getting", ans); - break; - case 01: - ans = controller->csrs->sel2; - if (ext) dmc_dumpregsel2(controller, DBG_REG, "Getting", ans); - break; - case 02: - ans = controller->csrs->sel4; - if (ext) dmc_dumpregsel4(controller, DBG_REG, "Getting", ans); - break; - case 03: - ans = controller->csrs->sel6; - if (ext) dmc_dumpregsel6(controller, DBG_REG, "Getting", ans); - break; - default: - { - sim_debug(DBG_WRN, controller->device, "dmc_getreg(). Invalid register %d", reg); - } - } + uint16 ans = 0; + switch (dmc_getsel(reg)) + { + case 00: + ans = controller->csrs->sel0; + if (ext) dmc_dumpregsel0(controller, DBG_REG, "Getting", ans); + break; + case 01: + ans = controller->csrs->sel2; + if (ext) dmc_dumpregsel2(controller, DBG_REG, "Getting", ans); + break; + case 02: + ans = controller->csrs->sel4; + if (ext) dmc_dumpregsel4(controller, DBG_REG, "Getting", ans); + break; + case 03: + ans = controller->csrs->sel6; + if (ext) dmc_dumpregsel6(controller, DBG_REG, "Getting", ans); + break; + default: + { + sim_debug(DBG_WRN, controller->device, "dmc_getreg(). Invalid register %d", reg); + } + } - return ans; + return ans; } void dmc_setreg(CTLR *controller, int reg, uint16 data, int ext) { - char *trace = (ext) ? "Writing" : "Setting"; - switch (dmc_getsel(reg)) - { - case 00: - dmc_dumpregsel0(controller, DBG_REG, trace, data); - controller->csrs->sel0 = data; - break; - case 01: - dmc_dumpregsel2(controller, DBG_REG, trace, data); - controller->csrs->sel2 = data; - break; - case 02: - dmc_dumpregsel4(controller, DBG_REG, trace, data); - controller->csrs->sel4 = data; - break; - case 03: - dmc_dumpregsel6(controller, DBG_REG, trace, data); - controller->csrs->sel6 = data; - break; - default: - { - sim_debug(DBG_WRN, controller->device, "dmc_setreg(). Invalid register %d", reg); - } - } + char *trace = (ext) ? "Writing" : "Setting"; + switch (dmc_getsel(reg)) + { + case 00: + dmc_dumpregsel0(controller, DBG_REG, trace, data); + controller->csrs->sel0 = data; + break; + case 01: + dmc_dumpregsel2(controller, DBG_REG, trace, data); + controller->csrs->sel2 = data; + break; + case 02: + dmc_dumpregsel4(controller, DBG_REG, trace, data); + controller->csrs->sel4 = data; + break; + case 03: + dmc_dumpregsel6(controller, DBG_REG, trace, data); + controller->csrs->sel6 = data; + break; + default: + { + sim_debug(DBG_WRN, controller->device, "dmc_setreg(). Invalid register %d", reg); + } + } } int dmc_is_master_clear_set(CTLR *controller) { - return controller->csrs->sel0 & MASTER_CLEAR_MASK; + return controller->csrs->sel0 & MASTER_CLEAR_MASK; } int dmc_is_lu_loop_set(CTLR *controller) { - return controller->csrs->sel0 & LU_LOOP_MASK; + return controller->csrs->sel0 & LU_LOOP_MASK; } int dmc_is_rqi_set(CTLR *controller) { - int ans = 0; - if (dmc_is_dmc(controller)) - { - ans = controller->csrs->sel0 & DMC_RQI_MASK; - } - else - { - ans = controller->csrs->sel0 & DMP_RQI_MASK; - } - return ans; + int ans = 0; + if (dmc_is_dmc(controller)) + { + ans = controller->csrs->sel0 & DMC_RQI_MASK; + } + else + { + ans = controller->csrs->sel0 & DMP_RQI_MASK; + } + return ans; } int dmc_is_rdyi_set(CTLR *controller) { - int ans = 0; - if (dmc_is_dmc(controller)) - { - ans = controller->csrs->sel0 & DMC_RDYI_MASK; - } - else - { - ans = controller->csrs->sel2 & DMP_RDYI_MASK; - } - return ans; + int ans = 0; + if (dmc_is_dmc(controller)) + { + ans = controller->csrs->sel0 & DMC_RDYI_MASK; + } + else + { + ans = controller->csrs->sel2 & DMP_RDYI_MASK; + } + return ans; } int dmc_is_iei_set(CTLR *controller) { - int ans = 0; - if (dmc_is_dmc(controller)) - { - ans = controller->csrs->sel0 & DMC_IEI_MASK; - } - else - { - ans = controller->csrs->sel0 & DMP_IEI_MASK; - } + int ans = 0; + if (dmc_is_dmc(controller)) + { + ans = controller->csrs->sel0 & DMC_IEI_MASK; + } + else + { + ans = controller->csrs->sel0 & DMP_IEI_MASK; + } - return ans; + return ans; } int dmc_is_ieo_set(CTLR *controller) { - int ans = 0; - if (dmc_is_dmc(controller)) - { - ans = controller->csrs->sel2 & DMC_IEO_MASK; - } - else - { - ans = controller->csrs->sel0 & DMP_IEO_MASK; - } + int ans = 0; + if (dmc_is_dmc(controller)) + { + ans = controller->csrs->sel2 & DMC_IEO_MASK; + } + else + { + ans = controller->csrs->sel0 & DMP_IEO_MASK; + } - return ans; + return ans; } int dmc_is_in_io_set(CTLR *controller) { - int ans = 0; - if (dmc_is_dmc(controller)) + int ans = 0; + if (dmc_is_dmc(controller)) { - ans = controller->csrs->sel0 & DMC_IN_IO_MASK; - } - else - { - ans = !controller->csrs->sel2 & DMP_IN_IO_MASK; - } + ans = controller->csrs->sel0 & DMC_IN_IO_MASK; + } + else + { + ans = !controller->csrs->sel2 & DMP_IN_IO_MASK; + } - return ans; + return ans; } int dmc_is_out_io_set(CTLR *controller) { - int ans = controller->csrs->sel2 & OUT_IO_MASK; - return ans; + int ans = controller->csrs->sel2 & OUT_IO_MASK; + return ans; } int dmc_is_rdyo_set(CTLR *controller) { - return controller->csrs->sel2 & DMC_RDYO_MASK; + return controller->csrs->sel2 & DMC_RDYO_MASK; } void dmc_set_rdyi(CTLR *controller) { - if (dmc_is_dmc(controller)) - { - dmc_setreg(controller, 0, controller->csrs->sel0 | DMC_RDYI_MASK, 0); - } - else - { - dmc_setreg(controller, 2, controller->csrs->sel2 | DMP_RDYI_MASK, 0); - } + if (dmc_is_dmc(controller)) + { + dmc_setreg(controller, 0, controller->csrs->sel0 | DMC_RDYI_MASK, 0); + } + else + { + dmc_setreg(controller, 2, controller->csrs->sel2 | DMP_RDYI_MASK, 0); + } - if (dmc_is_iei_set(controller)) - { - dmc_setrxint(controller); - } + if (dmc_is_iei_set(controller)) + { + dmc_setrxint(controller); + } } void dmc_clear_rdyi(CTLR *controller) { - if (dmc_is_dmc(controller)) - { + if (dmc_is_dmc(controller)) + { dmc_setreg(controller, 0, controller->csrs->sel0 & ~DMC_RDYI_MASK, 0); - } - else - { + } + else + { dmc_setreg(controller, 2, controller->csrs->sel2 & ~DMP_RDYI_MASK, 0); - } + } } void dmc_set_rdyo(CTLR *controller) { - dmc_setreg(controller, 2, controller->csrs->sel2 | DMC_RDYO_MASK, 0); + dmc_setreg(controller, 2, controller->csrs->sel2 | DMC_RDYO_MASK, 0); - if (dmc_is_ieo_set(controller)) - { - dmc_settxint(controller); - } + if (dmc_is_ieo_set(controller)) + { + dmc_settxint(controller); + } } void dmc_set_lost_data(CTLR *controller) { - dmc_setreg(controller, 6, controller->csrs->sel6 | LOST_DATA_MASK, 0); + dmc_setreg(controller, 6, controller->csrs->sel6 | LOST_DATA_MASK, 0); } void dmc_clear_master_clear(CTLR *controller) { - dmc_setreg(controller, 0, controller->csrs->sel0 & ~MASTER_CLEAR_MASK, 0); + dmc_setreg(controller, 0, controller->csrs->sel0 & ~MASTER_CLEAR_MASK, 0); } void dmc_set_run(CTLR *controller) { - dmc_setreg(controller, 0, controller->csrs->sel0 | RUN_MASK, 0); + dmc_setreg(controller, 0, controller->csrs->sel0 | RUN_MASK, 0); } int dmc_get_input_transfer_type(CTLR *controller) { - int ans = 0; + int ans = 0; - if (dmc_is_dmc(controller)) - { - ans = controller->csrs->sel0 & DMC_TYPE_INPUT_MASK; - } - else - { - ans = controller->csrs->sel2 & DMP_TYPE_INPUT_MASK; - } + if (dmc_is_dmc(controller)) + { + ans = controller->csrs->sel0 & DMC_TYPE_INPUT_MASK; + } + else + { + ans = controller->csrs->sel2 & DMP_TYPE_INPUT_MASK; + } - return ans; + return ans; } int dmc_get_output_transfer_type(CTLR *controller) { - return controller->csrs->sel2 & TYPE_OUTPUT_MASK; + return controller->csrs->sel2 & TYPE_OUTPUT_MASK; } void dmc_set_type_output(CTLR *controller, int type) { - dmc_setreg(controller, 2, controller->csrs->sel2 | (type & TYPE_OUTPUT_MASK), 0); + dmc_setreg(controller, 2, controller->csrs->sel2 | (type & TYPE_OUTPUT_MASK), 0); } void dmc_set_out_io(CTLR *controller) { - dmc_setreg(controller, 2, controller->csrs->sel2 | OUT_IO_MASK, 0); + dmc_setreg(controller, 2, controller->csrs->sel2 | OUT_IO_MASK, 0); } void dmc_clear_out_io(CTLR *controller) { - dmc_setreg(controller, 2, controller->csrs->sel2 & ~OUT_IO_MASK, 0); + dmc_setreg(controller, 2, controller->csrs->sel2 & ~OUT_IO_MASK, 0); } void dmc_process_master_clear(CTLR *controller) { - sim_debug(DBG_INF, controller->device, "Master clear\n"); - dmc_clear_master_clear(controller); - controller->state = Initialised; - dmc_setreg(controller, 0, 0, 0); - if (controller->dev_type == DMR) - { - /* DMR-11 indicates microdiagnostics complete when this is set */ - dmc_setreg(controller, 2, 0x8000, 0); - } - else - { - /* preserve contents of BSEL3 if DMC-11 */ - dmc_setreg(controller, 2, controller->csrs->sel2 & 0xFF00, 0); - } - if (controller->dev_type == DMP) - { - dmc_setreg(controller, 4, 077, 0); - } - else - { - dmc_setreg(controller, 4, 0, 0); - } + sim_debug(DBG_INF, controller->device, "Master clear\n"); + dmc_clear_master_clear(controller); + controller->state = Initialised; + dmc_setreg(controller, 0, 0, 0); + if (controller->dev_type == DMR) + { + /* DMR-11 indicates microdiagnostics complete when this is set */ + dmc_setreg(controller, 2, 0x8000, 0); + } + else + { + /* preserve contents of BSEL3 if DMC-11 */ + dmc_setreg(controller, 2, controller->csrs->sel2 & 0xFF00, 0); + } + if (controller->dev_type == DMP) + { + dmc_setreg(controller, 4, 077, 0); + } + else + { + dmc_setreg(controller, 4, 0, 0); + } - if (controller->dev_type == DMP) - { - dmc_setreg(controller, 6, 0305, 0); - } - else - { - dmc_setreg(controller, 6, 0, 0); - } - dmc_buffer_queue_init(controller, controller->receive_queue, "receive"); - dmc_buffer_queue_init(controller, controller->transmit_queue, "transmit"); - //dmc_close_receive(controller, "master clear"); - //dmc_close_transmit(controller, "master clear"); + if (controller->dev_type == DMP) + { + dmc_setreg(controller, 6, 0305, 0); + } + else + { + dmc_setreg(controller, 6, 0, 0); + } + dmc_buffer_queue_init(controller, controller->receive_queue, "receive"); + dmc_buffer_queue_init(controller, controller->transmit_queue, "transmit"); + //dmc_close_receive(controller, "master clear", NULL); + //dmc_close_transmit(controller, "master clear"); - controller->transfer_state = Idle; - dmc_set_run(controller); + controller->transfer_state = Idle; + dmc_set_run(controller); - sim_cancel (controller->device->units); /* stop poll */ - sim_activate_abs(controller->device->units, clk_cosched (controller->svc_poll_interval)); + sim_cancel (controller->device->units); /* stop poll */ + sim_activate_abs(controller->device->units, clk_cosched (controller->svc_poll_interval)); } void dmc_start_input_transfer(CTLR *controller) { - int ok = 1; - int type = dmc_get_input_transfer_type(controller); + int ok = 1; + int type = dmc_get_input_transfer_type(controller); - /* if this is a BA/CC I then check that the relevant queue has room first */ - if (type == TYPE_BACCI) - { - ok = (dmc_is_in_io_set(controller) && !dmc_buffer_queue_full(controller->receive_queue)) - || - (!dmc_is_in_io_set(controller) && !dmc_buffer_queue_full(controller->transmit_queue)); - } + /* if this is a BA/CC I then check that the relevant queue has room first */ + if (type == TYPE_BACCI) + { + ok = (dmc_is_in_io_set(controller) && !dmc_buffer_queue_full(controller->receive_queue)) + || + (!dmc_is_in_io_set(controller) && !dmc_buffer_queue_full(controller->transmit_queue)); + } - if (ok) - { - sim_debug(DBG_INF, controller->device, "Starting input transfer\n"); - controller->transfer_state = InputTransfer; - controller->transfer_type = type; - controller->transfer_in_io = dmc_is_in_io_set(controller); - dmc_set_rdyi(controller); - } - else - { - sim_debug(DBG_WRN, controller->device, "Input transfer request not granted as queue is full\n"); - } + if (ok) + { + sim_debug(DBG_INF, controller->device, "Starting input transfer\n"); + controller->transfer_state = InputTransfer; + controller->transfer_type = type; + controller->transfer_in_io = dmc_is_in_io_set(controller); + dmc_set_rdyi(controller); + } + else + { + sim_debug(DBG_WRN, controller->device, "Input transfer request not granted as queue is full\n"); + } } void dmc_start_data_output_transfer(CTLR *controller, uint32 addr, int16 count, int is_receive) { - if (is_receive) - { - sim_debug(DBG_INF, controller->device, "Starting data output transfer for receive, address=0x%08x, count=%d\n", addr, count); - dmc_set_out_io(controller); - } - else - { - sim_debug(DBG_INF, controller->device, "Starting data output transfer for transmit, address=0x%08x, count=%d\n", addr, count); - dmc_clear_out_io(controller); - } + if (is_receive) + { + sim_debug(DBG_INF, controller->device, "Starting data output transfer for receive, address=0x%08x, count=%d\n", addr, count); + dmc_set_out_io(controller); + } + else + { + sim_debug(DBG_INF, controller->device, "Starting data output transfer for transmit, address=0x%08x, count=%d\n", addr, count); + dmc_clear_out_io(controller); + } - dmc_setreg(controller, 4, addr & 0xFFFF, 0); - dmc_setreg(controller, 6, (((addr & 0x30000)) >> 2) | count, 0); - controller->transfer_state = OutputTransfer; - dmc_set_type_output(controller, TYPE_BACCO); - dmc_set_rdyo(controller); + dmc_setreg(controller, 4, addr & 0xFFFF, 0); + dmc_setreg(controller, 6, (((addr & 0x30000)) >> 2) | count, 0); + controller->transfer_state = OutputTransfer; + dmc_set_type_output(controller, TYPE_BACCO); + dmc_set_rdyo(controller); } void dmc_start_control_output_transfer(CTLR *controller) { - sim_debug(DBG_INF, controller->device, "Starting control output transfer\n"); - controller->transfer_state = OutputTransfer; - dmc_set_type_output(controller, TYPE_CNTLO); - dmc_set_rdyo(controller); + sim_debug(DBG_INF, controller->device, "Starting control output transfer\n"); + controller->transfer_state = OutputTransfer; + dmc_set_type_output(controller, TYPE_CNTLO); + dmc_set_rdyo(controller); } t_stat dmc_svc(UNIT* uptr) { - CTLR *controller; + CTLR *controller; + int32 poll; - TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; - TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer; + TIMER *poll_timer = &dmc_get_unit_stats(uptr)->poll_timer; + TIMER *between_polls_timer = &dmc_get_unit_stats(uptr)->between_polls_timer; - if (dmc_timer_started(between_polls_timer)) - { - dmc_timer_stop(between_polls_timer); - } + poll = clk_cosched (tmxr_poll); - if (dmc_timer_started(poll_timer)) - { - dmc_timer_resume(poll_timer); - } - else - { - dmc_timer_start(poll_timer); - } + if (dmc_timer_started(between_polls_timer)) + { + dmc_timer_stop(between_polls_timer); + } - controller = dmc_get_controller_from_unit(uptr); + if (dmc_timer_started(poll_timer)) + { + dmc_timer_resume(poll_timer); + } + else + { + dmc_timer_start(poll_timer); + } - dmc_line_update_speed_stats(controller->line); + controller = dmc_get_controller_from_unit(uptr); - if (dmc_buffer_fill_receive_buffers(controller)) - { -// poll = 200; /* if we received data then lets poll quicker as there seems to be some activity */ - } - if (controller->transfer_state == Idle) dmc_start_transfer_receive_buffer(controller); + dmc_line_update_speed_stats(controller->line); - if (dmc_buffer_send_transmit_buffers(controller)) - { -// poll = 200; /* if we transmitted data then lets poll quicker as there seems to be some activity */ - } - if (controller->transfer_state == Idle) dmc_start_transfer_transmit_buffer(controller); + if (dmc_buffer_fill_receive_buffers(controller)) + { +// poll = 200; /* if we received data then lets poll quicker as there seems to be some activity */ + } + if (controller->transfer_state == Idle) dmc_start_transfer_receive_buffer(controller); - /* resubmit service timer */ - sim_activate(controller->device->units, controller->svc_poll_interval); + if (dmc_buffer_send_transmit_buffers(controller)) + { +// poll = 200; /* if we transmitted data then lets poll quicker as there seems to be some activity */ + } + if (controller->transfer_state == Idle) dmc_start_transfer_transmit_buffer(controller); - dmc_timer_stop(poll_timer); - if (dmc_timer_started(between_polls_timer)) - { - dmc_timer_resume(between_polls_timer); - } - else - { - dmc_timer_start(between_polls_timer); - } + /* resubmit service timer */ + sim_activate(controller->device->units, poll/*controller->svc_poll_interval*/); + + dmc_timer_stop(poll_timer); + if (dmc_timer_started(between_polls_timer)) + { + dmc_timer_resume(between_polls_timer); + } + else + { + dmc_timer_start(between_polls_timer); + } dmc_get_unit_stats(uptr)->poll_count++; - return SCPE_OK; + return SCPE_OK; } void dmc_line_update_speed_stats(LINE *line) { - clock_t current = clock(); - int current_second = current / CLOCKS_PER_SEC; - if (current_second != line->last_second) - { - line->bytes_received_in_last_second = 0; - line->bytes_sent_in_last_second = 0; - line->last_second = current_second; - } + clock_t current = clock(); + int current_second = current / CLOCKS_PER_SEC; + if (current_second != line->last_second) + { + line->bytes_received_in_last_second = 0; + line->bytes_sent_in_last_second = 0; + line->last_second = current_second; + } } /* given the number of bytes sent/received in the last second, the number of bytes to send or receive and the line speed, calculate how many bytes can be sent/received now */ int dmc_line_speed_calculate_byte_length(int bytes_in_last_second, int num_bytes, int speed) { - int ans; + int ans; - if (speed == 0) - { - ans = num_bytes; - } - else - { - int clocks_this_second = clock() % CLOCKS_PER_SEC; - int allowable_bytes_to_date = ((speed/8) * clocks_this_second)/CLOCKS_PER_SEC; - int allowed_bytes = allowable_bytes_to_date - bytes_in_last_second; - if (allowed_bytes < 0) - { - allowed_bytes = 0; - } + if (speed == 0) + { + ans = num_bytes; + } + else + { + int clocks_this_second = clock() % CLOCKS_PER_SEC; + int allowable_bytes_to_date = ((speed/8) * clocks_this_second)/CLOCKS_PER_SEC; + int allowed_bytes = allowable_bytes_to_date - bytes_in_last_second; + if (allowed_bytes < 0) + { + allowed_bytes = 0; + } - if (num_bytes > allowed_bytes) - { - ans = allowed_bytes; - } - else - { - ans = num_bytes; - } + if (num_bytes > allowed_bytes) + { + ans = allowed_bytes; + } + else + { + ans = num_bytes; + } //sim_debug(DBG_WRN, dmc_ctrls[0].device, "Bytes in last second %4d, clocks this sec %3d allowable bytes %4d, requested %4d allowed %4d\n", bytes_in_last_second, clocks_this_second, allowable_bytes_to_date, num_bytes, ans); - } + } - return ans; + return ans; } void dmc_buffer_trace_line(int tracelevel, CTLR *controller, uint8 *buf, int length, char *prefix) { - char hex[TRACE_BYTES_PER_LINE*3+1]; - char ascii[TRACE_BYTES_PER_LINE+1]; - //char ts[9]; - //time_t t; - int i; - hex[0] = 0; - ascii[TRACE_BYTES_PER_LINE] = 0; + char hex[TRACE_BYTES_PER_LINE*3+1]; + char ascii[TRACE_BYTES_PER_LINE+1]; + //char ts[9]; + //time_t t; + int i; + hex[0] = 0; + ascii[TRACE_BYTES_PER_LINE] = 0; - //t = time(NULL); - //strftime(ts, 9, "%H:%M:%S", localtime(&t)); - for (i = 0; i=length) - { - strcat(hex, " "); - ascii[i] = ' '; - } - else - { - char hexByte[4]; - sprintf(hexByte, "%02X ", buf[i]); - strcat(hex, hexByte); - if (isprint(buf[i])) - { - ascii[i] = (char)buf[i]; - } - else - { - ascii[i] = '.'; - } - } - } + //t = time(NULL); + //strftime(ts, 9, "%H:%M:%S", localtime(&t)); + for (i = 0; i=length) + { + strcat(hex, " "); + ascii[i] = ' '; + } + else + { + char hexByte[4]; + sprintf(hexByte, "%02X ", buf[i]); + strcat(hex, hexByte); + if (isprint(buf[i])) + { + ascii[i] = (char)buf[i]; + } + else + { + ascii[i] = '.'; + } + } + } - 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; - if (length >= 0 && controller->device->dctrl & DBG_DAT) - { - 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); - } + int i; + 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++) + { + dmc_buffer_trace_line(DBG_DAT, controller, buf + i*TRACE_BYTES_PER_LINE, TRACE_BYTES_PER_LINE, prefix); + } - if (length %TRACE_BYTES_PER_LINE > 0) - { - dmc_buffer_trace_line(DBG_DAT, controller, buf + length/TRACE_BYTES_PER_LINE, length % TRACE_BYTES_PER_LINE, prefix); - } - } - else if (length >= 0 && controller->device->dctrl & DBG_DTS) - { - char prefix2[80]; - sprintf(prefix2, "%s (len=%d)", prefix, length); - dmc_buffer_trace_line(DBG_DTS, controller, buf, (length > TRACE_BYTES_PER_LINE)? TRACE_BYTES_PER_LINE : length, prefix2); - } + if (length %TRACE_BYTES_PER_LINE > 0) + { + dmc_buffer_trace_line(DBG_DAT, controller, buf + length/TRACE_BYTES_PER_LINE, length % TRACE_BYTES_PER_LINE, prefix); + } + } + else if (length >= 0 && controller->device->dctrl & DBG_DTS) + { + char prefix2[80]; + sprintf(prefix2, "%s (len=%d)", prefix, length); + dmc_buffer_trace_line(DBG_DTS, controller, buf, (length > TRACE_BYTES_PER_LINE)? TRACE_BYTES_PER_LINE : length, prefix2); + } } void dmc_buffer_queue_init(CTLR *controller, BUFFER_QUEUE *q, char *name) { - q->name = name; - q->head = 0; - q->tail = 0; - q->count = 0; - q->controller = controller; + q->name = name; + q->head = 0; + q->tail = 0; + q->count = 0; + q->controller = controller; } int dmc_buffer_queue_full(BUFFER_QUEUE *q) { - return q->count > BUFFER_QUEUE_SIZE; + return q->count > BUFFER_QUEUE_SIZE; } void dmc_buffer_queue_add(BUFFER_QUEUE *q, uint32 address, uint16 count) { - if (!dmc_buffer_queue_full(q)) - { - int new_buffer = 0; - if (q->count > 0) - { - int last_buffer = q->tail; - new_buffer = (q->tail +1) % BUFFER_QUEUE_SIZE; + if (!dmc_buffer_queue_full(q)) + { + int new_buffer = 0; + if (q->count > 0) + { + int last_buffer = q->tail; + new_buffer = (q->tail +1) % BUFFER_QUEUE_SIZE; - /* Link last buffer to the new buffer */ - q->queue[last_buffer].next = &q->queue[new_buffer]; - } - else - { - q->head = 0; - new_buffer = 0; - } + /* Link last buffer to the new buffer */ + q->queue[last_buffer].next = &q->queue[new_buffer]; + } + else + { + q->head = 0; + new_buffer = 0; + } - q->tail = new_buffer; - q->queue[new_buffer].address = address; - q->queue[new_buffer].count = count; - q->queue[new_buffer].actual_block_len = 0; - q->queue[new_buffer].transfer_buffer = NULL; - q->queue[new_buffer].block_len_bytes_read = 0; - q->queue[new_buffer].actual_bytes_transferred = 0; - q->queue[new_buffer].next = NULL; - q->queue[new_buffer].state = Available; - q->queue[new_buffer].is_loopback = dmc_is_lu_loop_set(q->controller); - q->count++; - sim_debug(DBG_INF, q->controller->device, "Queued %s buffer address=0x%08x count=%d\n", q->name, address, count); - } - else - { - sim_debug(DBG_WRN, q->controller->device, "Failed to queue %s buffer, queue full\n", q->name); - // TODO: Report error here. - } + q->tail = new_buffer; + q->queue[new_buffer].address = address; + q->queue[new_buffer].count = count; + q->queue[new_buffer].actual_block_len = 0; + q->queue[new_buffer].transfer_buffer = NULL; + q->queue[new_buffer].block_len_bytes_read = 0; + q->queue[new_buffer].actual_bytes_transferred = 0; + q->queue[new_buffer].next = NULL; + q->queue[new_buffer].state = Available; + q->queue[new_buffer].is_loopback = dmc_is_lu_loop_set(q->controller); + q->count++; + sim_debug(DBG_INF, q->controller->device, "Queued %s buffer address=0x%08x count=%d\n", q->name, address, count); + } + else + { + 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. + } } void dmc_buffer_queue_release_head(BUFFER_QUEUE *q) { - if (q->count > 0) - { - q->head = (q->head + 1) % BUFFER_QUEUE_SIZE; - q->count--; - } - else - { - sim_debug(DBG_INF, q->controller->device, "Failed to release %s buffer, queue already empty\n", q->name); - } + if (q->count > 0) + { + q->head = (q->head + 1) % BUFFER_QUEUE_SIZE; + q->count--; + } + else + { + sim_debug(DBG_INF, q->controller->device, "Failed to release %s buffer, queue already empty\n", q->name); + } } BUFFER *dmc_buffer_queue_head(BUFFER_QUEUE *q) { - BUFFER *ans = NULL; - if (q->count >0) - { - ans = &q->queue[q->head]; - } + BUFFER *ans = NULL; + if (q->count >0) + { + ans = &q->queue[q->head]; + } - return ans; + return ans; } BUFFER *dmc_buffer_queue_find_first_available(BUFFER_QUEUE *q) { - BUFFER *ans = dmc_buffer_queue_head(q); - while (ans != NULL) - { - if (ans->state == Available) - { - break; - } + BUFFER *ans = dmc_buffer_queue_head(q); + while (ans != NULL) + { + if (ans->state == Available) + { + break; + } - ans = ans->next; - } + ans = ans->next; + } - return ans; + return ans; } BUFFER *dmc_buffer_queue_find_first_contains_data(BUFFER_QUEUE *q) { - BUFFER *ans = dmc_buffer_queue_head(q); - while (ans != NULL) - { - if (ans->state == ContainsData) - { - break; - } + BUFFER *ans = dmc_buffer_queue_head(q); + while (ans != NULL) + { + if (ans->state == ContainsData) + { + break; + } - ans = ans->next; - } + ans = ans->next; + } - return ans; + return ans; } void dmc_buffer_queue_get_stats(BUFFER_QUEUE *q, int *available, int *contains_data, int *transfer_in_progress) { - BUFFER *buf = dmc_buffer_queue_head(q); + BUFFER *buf = dmc_buffer_queue_head(q); *available = 0; - *contains_data = 0; - *transfer_in_progress = 0; + *contains_data = 0; + *transfer_in_progress = 0; - while (buf != NULL) - { - switch (buf->state) - { - case Available: - { - (*available)++; - break; - } + while (buf != NULL) + { + switch (buf->state) + { + case Available: + { + (*available)++; + break; + } - case ContainsData: - { - (*contains_data)++; - break; - } + case ContainsData: + { + (*contains_data)++; + break; + } - case TransferInProgress: - { - (*transfer_in_progress)++; - break; - } - } + case TransferInProgress: + { + (*transfer_in_progress)++; + break; + } + } - buf = buf->next; - } + buf = buf->next; + } } t_stat dmc_open_master_socket(CTLR *controller, char *port) { - t_stat ans; - ans = SCPE_OK; - if (controller->master_socket == INVALID_SOCKET) - { - controller->master_socket = sim_master_sock(port, &ans); - if (controller->master_socket == INVALID_SOCKET) - { - sim_debug(DBG_WRN, controller->device, "Failed to open master socket\n"); - ans = SCPE_OPENERR; - } - else - { - printf ("DMC-11 %s listening on port %s (socket %d)\n", controller->device->name, port, controller->master_socket); - } - } + t_stat ans; + ans = SCPE_OK; + if (controller->master_socket == INVALID_SOCKET) + { + controller->master_socket = sim_master_sock(port, &ans); + if (controller->master_socket == INVALID_SOCKET) + { + sim_debug(DBG_WRN, controller->device, "Failed to open master socket on port %s\n", port); + ans = SCPE_OPENERR; + } + else + { + printf ("DMC-11 %s listening on port %s\n", controller->device->name, port); + } + } - return ans; + return ans; } t_stat dmc_close_master_socket(CTLR *controller) { - sim_close_sock (controller->master_socket, TRUE); - controller->master_socket = INVALID_SOCKET; - return SCPE_OK; + sim_close_sock (controller->master_socket, TRUE); + controller->master_socket = INVALID_SOCKET; + return SCPE_OK; } // Gets the bidirectional socket and handles arbitration of determining which socket to use. int dmc_get_socket(CTLR *controller, int forRead) { - static int lastans = 0; - int ans = 0; +// static int lastans = 0; + int ans = 0; if (controller->line->isPrimary) - { - ans = dmc_get_transmit_socket(controller, 0, forRead); // TODO: After change to single socket, loopback may not work. - } - else - { - ans = dmc_get_receive_socket(controller, forRead); // TODO: After change to single socket, loopback may not work. - } - - if (lastans != ans) - { -sim_debug(DBG_SOK, controller->device, "Get Socket forread=%d, changed to %d\n", forRead, ans); - } - lastans = ans; + { + ans = dmc_get_transmit_socket(controller, 0, forRead); // TODO: After change to single socket, loopback may not work. + } + else + { + ans = dmc_get_receive_socket(controller, forRead); // TODO: After change to single socket, loopback may not work. + } +// if (lastans != ans) +// { +//sim_debug(DBG_SOK, controller->device, "Get Socket forread=%d, changed to %d\n", forRead, ans); +// } +// lastans = ans; +// return ans; } int dmc_get_receive_socket(CTLR *controller, int forRead) { - int ans = 0; - if (controller->line->socket == INVALID_SOCKET) - { - char *ipaddr; - //sim_debug(DBG_SOK, controller->device, "Trying to open receive socket\n"); - controller->line->socket = sim_accept_conn (controller->master_socket, &ipaddr); /* poll connect */ - if (controller->line->socket != INVALID_SOCKET) - { - if (strcmp(ipaddr, controller->line->transmit_host)) - { - sim_debug(DBG_WRN, controller->device, "Received connection from unexpected source IP %s. Closing the connection.\n", ipaddr); - dmc_close_receive(controller, "Unathorized connection"); - } - else - { - sim_debug(DBG_SOK, controller->device, "Opened receive socket %d\n", controller->line->socket); - controller->line->receive_readable = FALSE; - } + int ans = 0; + if (controller->line->socket == INVALID_SOCKET) + { + char *ipaddr; + //sim_debug(DBG_SOK, controller->device, "Trying to open receive socket\n"); + controller->line->socket = sim_accept_conn (controller->master_socket, &ipaddr); /* poll connect */ + if (controller->line->socket != INVALID_SOCKET) + { + 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); + dmc_close_receive(controller, "Unathorized connection", ipaddr); + } + else + { + sim_debug(DBG_SOK, controller->device, "Opened receive socket %d\n", controller->line->socket); + controller->line->receive_readable = FALSE; + } free(ipaddr); - } - } + } + } - if (controller->line->socket != INVALID_SOCKET) - { - int readable = sim_check_conn(controller->line->socket, forRead); - if (readable == 0) /* Still opening */ - { - // Socket is still being opened, or is open but there is no data ready to be read. - ans = 0; - } - else if (readable == -1) /* Failed to open */ - { - dmc_close_receive(controller, "failed to connect"); - ans = 0; - } - else /* connected */ - { - if (!controller->line->receive_readable) - { - sim_debug(DBG_CON, controller->device, "Receive socket is now readable\n"); - } - controller->line->receive_readable = TRUE; - ans = 1; - } - } + if (controller->line->socket != INVALID_SOCKET) + { + int readable = sim_check_conn(controller->line->socket, forRead); + if (readable == 0) /* Still opening */ + { + // Socket is still being opened, or is open but there is no data ready to be read. + ans = 0; + } + else if (readable == -1) /* Failed to open */ + { + dmc_close_receive(controller, "failed to connect", NULL); + ans = 0; + } + else /* connected */ + { + if (!controller->line->receive_readable) + { + sim_debug(DBG_CON, controller->device, "Receive socket is now readable\n"); + } + controller->line->receive_readable = TRUE; + ans = 1; + } + } - return ans; + return ans; } int dmc_get_transmit_socket(CTLR *controller, int is_loopback, int forRead) { - int ans = 0; - /* close transmit socket if there is a change in the loopback setting */ - if (is_loopback ^ controller->line->transmit_is_loopback) - { - dmc_close_transmit(controller, "loopback change"); - } + int ans = 0; + /* close transmit socket if there is a change in the loopback setting */ + if (is_loopback ^ controller->line->transmit_is_loopback) + { + dmc_close_transmit(controller, "loopback change"); + } - if (controller->line->socket == INVALID_SOCKET && (time(NULL) - controller->line->last_connect_attempt) > controller->connect_poll_interval) - { - char hostport[CBUFSIZE]; + if (controller->line->socket == INVALID_SOCKET && ((int32)(time(NULL) - controller->line->last_connect_attempt)) > controller->connect_poll_interval) + { + char hostport[CBUFSIZE]; - controller->line->transmit_is_loopback = is_loopback; - - controller->line->last_connect_attempt = time(NULL); + controller->line->transmit_is_loopback = is_loopback; + + controller->line->last_connect_attempt = time(NULL); if (is_loopback) sprintf(hostport, "localhost:%s", controller->line->receive_port); else sprintf(hostport, "%s", controller->line->transmit_host); 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); - 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); - controller->line->transmit_writeable = FALSE; - } - } + if (controller->line->socket != INVALID_SOCKET) + { + sim_debug(DBG_SOK, controller->device, "Opened transmit socket to port %s\n", hostport); + controller->line->transmit_writeable = FALSE; + } + } - if (controller->line->socket != INVALID_SOCKET) - { - int writeable = sim_check_conn(controller->line->socket, forRead); - if (writeable == 0) /* Still opening */ - { - //sim_debug(DBG_SOK, controller->device, "Waiting for transmit socket to become writeable\n"); - ans = 0; - } - else if (writeable == -1) /* Failed to open */ - { - dmc_close_transmit(controller, "failed to connect"); - ans = 0; - } - else /* connected */ - { - if (!controller->line->transmit_writeable) - { - sim_debug(DBG_CON, controller->device, "Transmit socket is now writeable\n"); - } - controller->line->transmit_writeable = TRUE; - ans = 1; - } - } + if (controller->line->socket != INVALID_SOCKET) + { + int writeable = sim_check_conn(controller->line->socket, forRead); + if (writeable == 0) /* Still opening */ + { + //sim_debug(DBG_SOK, controller->device, "Waiting for transmit socket to become writeable\n"); + ans = 0; + } + else if (writeable == -1) /* Failed to open */ + { + dmc_close_transmit(controller, "failed to connect"); + ans = 0; + } + else /* connected */ + { + if (!controller->line->transmit_writeable) + { + sim_debug(DBG_CON, controller->device, "Transmit socket is now writeable\n"); + } + controller->line->transmit_writeable = TRUE; + ans = 1; + } + } - 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_close_sock(controller->line->socket, FALSE); - controller->line->socket = INVALID_SOCKET; +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); + controller->line->socket = INVALID_SOCKET; - if (controller->line->receive_readable) - { - sim_debug(DBG_CON, controller->device, "Readable receive socket closed, reason: %s\n", reason); - } - controller->line->receive_readable = FALSE; + if (controller->line->receive_readable) + { + sim_debug(DBG_CON, controller->device, "Readable receive socket closed, reason: %s\n", reason); + } + controller->line->receive_readable = FALSE; } void dmc_error_and_close_receive(CTLR *controller, char *format) { int err = WSAGetLastError(); - char errmsg[80]; - sprintf(errmsg, format, err); - if (controller->line->isPrimary) - { + char errmsg[80]; + sprintf(errmsg, format, err); + if (controller->line->isPrimary) + { dmc_close_transmit(controller, errmsg); - } - else - { - dmc_close_receive(controller, errmsg); - } + } + else + { + dmc_close_receive(controller, errmsg, NULL); + } } void dmc_close_transmit(CTLR *controller, char *reason) { - sim_debug(DBG_SOK, controller->device, "Closing transmit socket to port %s, socket %d, reason: %s\n", controller->line->transmit_host, controller->line->socket, reason); - sim_close_sock(controller->line->socket, FALSE); - controller->line->socket = INVALID_SOCKET; + sim_debug(DBG_SOK, controller->device, "Closing transmit socket to port %s, socket %d, reason: %s\n", controller->line->transmit_host, controller->line->socket, reason); + sim_close_sock(controller->line->socket, FALSE); + controller->line->socket = INVALID_SOCKET; - if (controller->line->transmit_writeable) - { - sim_debug(DBG_CON, controller->device, "Writeable transmit socket closed, reason: %s\n", reason); - } - controller->line->transmit_writeable = FALSE; + if (controller->line->transmit_writeable) + { + sim_debug(DBG_CON, controller->device, "Writeable transmit socket closed, reason: %s\n", reason); + } + controller->line->transmit_writeable = FALSE; } /* returns true if some data was received */ int dmc_buffer_fill_receive_buffers(CTLR *controller) { - int ans = FALSE; - int 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) - { -printf("Socket error was when trying to fill receive buffers when controller initialised.\n"); - //dmc_error_and_close_receive(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 - { - BUFFER *buffer = dmc_buffer_queue_find_first_available(controller->receive_queue); - while (buffer != NULL && buffer->state == Available) - { - if (dmc_get_socket(controller, TRUE)) - { - int bytes_read = 0; - int lost_data = 0; + 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_receive(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 + { + BUFFER *buffer = dmc_buffer_queue_find_first_available(controller->receive_queue); + while (buffer != NULL && buffer->state == Available) + { + if (dmc_get_socket(controller, TRUE)) + { + int bytes_read = 0; + int lost_data = 0; - socket = controller->line->socket; - /* read block length and allocate buffer */ - if (buffer->block_len_bytes_read < sizeof(buffer->actual_block_len)) - { - char *start_addr = ((char *)&buffer->actual_block_len) + buffer->block_len_bytes_read; - bytes_read = sim_read_sock(socket, start_addr, sizeof(buffer->actual_block_len) - buffer->block_len_bytes_read); - if (bytes_read >= 0) - { - buffer->block_len_bytes_read += bytes_read; - if (buffer->block_len_bytes_read == sizeof(buffer->actual_block_len)) - { - buffer->actual_block_len = ntohs(buffer->actual_block_len); - if (buffer->actual_block_len > buffer->count) - { - sim_debug(DBG_WRN, controller->device, "LOST DATA, buffer available has %d bytes, but the block is %d bytes\n", buffer->count, buffer->actual_block_len); - dmc_setreg(controller, 4, 0, 0); - dmc_setreg(controller, 6, 0, 0); - dmc_set_lost_data(controller); - dmc_start_control_output_transfer(controller); - lost_data = 1; - } + socket = controller->line->socket; + /* read block length and allocate buffer */ + if (buffer->block_len_bytes_read < sizeof(buffer->actual_block_len)) + { + char *start_addr = ((char *)&buffer->actual_block_len) + buffer->block_len_bytes_read; + bytes_read = sim_read_sock(socket, start_addr, sizeof(buffer->actual_block_len) - buffer->block_len_bytes_read); + if (bytes_read >= 0) + { + buffer->block_len_bytes_read += bytes_read; + if (buffer->block_len_bytes_read == sizeof(buffer->actual_block_len)) + { + buffer->actual_block_len = ntohs(buffer->actual_block_len); + if (buffer->actual_block_len > buffer->count) + { + sim_debug(DBG_WRN, controller->device, "LOST DATA, buffer available has %d bytes, but the block is %d bytes\n", buffer->count, buffer->actual_block_len); + dmc_setreg(controller, 4, 0, 0); + dmc_setreg(controller, 6, 0, 0); + dmc_set_lost_data(controller); + dmc_start_control_output_transfer(controller); + lost_data = 1; + } - if (buffer->actual_block_len > 0) - { - buffer->transfer_buffer = (uint8 *)malloc(buffer->actual_block_len); /* read full buffer regardless, so bad buffer is flushed */ - } - } - } - else - { + if (buffer->actual_block_len > 0) + { + buffer->transfer_buffer = (uint8 *)malloc(buffer->actual_block_len); /* read full buffer regardless, so bad buffer is flushed */ + } + } + } + else + { //printf("Socket error was when trying to read the header.\n"); - } - } - else - { - lost_data = buffer->actual_block_len > buffer->count; /* need to preserve this variable if need more than one attempt to read the buffer */ - } + } + } + else + { + lost_data = buffer->actual_block_len > buffer->count; /* need to preserve this variable if need more than one attempt to read the buffer */ + } - /* read the actual block */ - if (buffer->block_len_bytes_read == sizeof(buffer->actual_block_len)) - { - bytes_read = 0; - if (buffer->actual_block_len > 0) - { - 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) - { - bytes_read = sim_read_sock(controller->line->socket, buffer->transfer_buffer + buffer->actual_bytes_transferred, bytes_to_read); - } - } + /* read the actual block */ + if (buffer->block_len_bytes_read == sizeof(buffer->actual_block_len)) + { + bytes_read = 0; + if (buffer->actual_block_len > 0) + { + 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) + { + bytes_read = sim_read_sock(controller->line->socket, (char *)(buffer->transfer_buffer + buffer->actual_bytes_transferred), bytes_to_read); + } + } - if (bytes_read >= 0) - { - buffer->actual_bytes_transferred += bytes_read; - controller->line->bytes_received_in_last_second += bytes_read; + if (bytes_read >= 0) + { + buffer->actual_bytes_transferred += bytes_read; + controller->line->bytes_received_in_last_second += bytes_read; - if (buffer->actual_bytes_transferred >= buffer->actual_block_len) - { - dmc_buffer_trace(controller, buffer->transfer_buffer, buffer->actual_bytes_transferred, "REC "); - controller->buffers_received_from_net++; - buffer->state = ContainsData; - if (!lost_data) - { - Map_WriteB(buffer->address, buffer->actual_bytes_transferred, buffer->transfer_buffer); - } - else - { - buffer->actual_block_len = 0; /* so an empty buffer is returned to the driver */ - } + if (buffer->actual_bytes_transferred >= buffer->actual_block_len) + { + dmc_buffer_trace(controller, buffer->transfer_buffer, buffer->actual_bytes_transferred, "REC ", buffer->address); + controller->buffers_received_from_net++; + buffer->state = ContainsData; + if (!lost_data) + { + Map_WriteB(buffer->address, buffer->actual_bytes_transferred, buffer->transfer_buffer); + } + else + { + buffer->actual_block_len = 0; /* so an empty buffer is returned to the driver */ + } - if (buffer->actual_block_len > 0) - { - free(buffer->transfer_buffer); - buffer->transfer_buffer = NULL; - } + if (buffer->actual_block_len > 0) + { + free(buffer->transfer_buffer); + buffer->transfer_buffer = NULL; + } - ans = TRUE; - } - } - else - { + ans = TRUE; + } + } + else + { printf("Socket error was when trying to fill receive buffers when trying to read the body.\n"); - } - } + } + } - /* Only close the socket if there was an error or no more data */ - if (bytes_read < 0) - { - dmc_error_and_close_receive(controller, "read error, code=%d"); - break; - } + /* Only close the socket if there was an error or no more data */ + if (bytes_read < 0) + { + dmc_error_and_close_receive(controller, "read error, code=%d"); + break; + } - /* if buffer is incomplete do not try to read any more buffers and continue filling this one later */ - if (buffer->state == Available) - { - break; /* leave buffer available and continue filling it later */ - } - } - else - { - break; - } + /* if buffer is incomplete do not try to read any more buffers and continue filling this one later */ + if (buffer->state == Available) + { + break; /* leave buffer available and continue filling it later */ + } + } + else + { + break; + } - buffer = buffer ->next; - } - } + buffer = buffer ->next; + } + } - return ans; + return ans; } /* returns true if some data was actually sent */ int dmc_buffer_send_transmit_buffers(CTLR *controller) { - int ans = FALSE; - int socket; - /* when transmit buffer is queued it is marked as available, not as ContainsData */ - BUFFER *buffer = dmc_buffer_queue_find_first_available(controller->transmit_queue); - while (buffer != NULL) - { - if (dmc_get_socket(controller, FALSE)) // TODO: , buffer->is_loopback); - { - int bytes = 0; - uint16 block_len; - int total_buffer_len = (buffer->count > 0) ? buffer->count + sizeof(block_len) : 0; + int ans = FALSE; + /* when transmit buffer is queued it is marked as available, not as ContainsData */ + BUFFER *buffer = dmc_buffer_queue_find_first_available(controller->transmit_queue); + while (buffer != NULL) + { + if (dmc_get_socket(controller, FALSE)) // TODO: , buffer->is_loopback); + { + int bytes = 0; + int bytes_to_send; + uint16 block_len; + 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 */ - if (total_buffer_len > 0) - { - if (buffer->actual_bytes_transferred <= 0) - { - /* construct buffer and include block length bytes */ - buffer->transfer_buffer = (uint8 *)malloc(total_buffer_len); - block_len = htons(buffer->count); - memcpy(buffer->transfer_buffer, (char *)&block_len, sizeof(block_len)); - Map_ReadB(buffer->address, buffer->count, buffer->transfer_buffer + sizeof(block_len)); - } + /* 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 (buffer->transfer_buffer == NULL) + { + int n; + /* construct buffer and include block length bytes */ + buffer->transfer_buffer = (uint8 *)malloc(total_buffer_len); + block_len = htons(buffer->count); + memcpy(buffer->transfer_buffer, (char *)&block_len, 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); - if (bytes >= 0) - { - buffer->actual_bytes_transferred += bytes; - } + 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) + { + buffer->actual_bytes_transferred += bytes; + controller->line->bytes_sent_in_last_second += bytes; + } - if (buffer->actual_bytes_transferred >= total_buffer_len || bytes < 0) - { - dmc_buffer_trace(controller, buffer->transfer_buffer+sizeof(block_len), buffer->count, "TRAN"); - free(buffer->transfer_buffer); - } - } + if (buffer->actual_bytes_transferred >= total_buffer_len || bytes < 0) + { + dmc_buffer_trace(controller, buffer->transfer_buffer+sizeof(block_len), buffer->count, "TRAN", buffer->address); + free(buffer->transfer_buffer); + } + } + } - if (buffer->actual_bytes_transferred >= total_buffer_len) - { - controller->buffers_transmitted_to_net++; - buffer->state = ContainsData; // so won't try to transmit again - ans = TRUE; - } - else if (bytes < 0) - { - int err = WSAGetLastError (); - char errmsg[80]; - sprintf(errmsg, "write failure, code=%d", err); + if (buffer->actual_bytes_transferred >= total_buffer_len) + { + controller->buffers_transmitted_to_net++; + buffer->state = ContainsData; // so won't try to transmit again + ans = TRUE; + } + else if (bytes < 0) + { + int err = WSAGetLastError (); + char errmsg[80]; + sprintf(errmsg, "write failure, code=%d", err); - dmc_close_transmit(controller, errmsg); - break; - } - else - { - break; /* poll again later to send more bytes */ - } + dmc_close_transmit(controller, errmsg); + break; + } + else + { + break; /* poll again later to send more bytes */ + } - } - else - { - break; - } + } + else + { + break; + } - buffer = buffer ->next; - } + buffer = buffer ->next; + } - return ans; + return ans; } void dmc_start_transfer_receive_buffer(CTLR *controller) { - BUFFER *head = dmc_buffer_queue_head(controller->receive_queue); - if (head != NULL) - { - if (head->state == ContainsData) - { - head->state = TransferInProgress; - dmc_start_data_output_transfer(controller, head->address, head->actual_block_len, TRUE); - } - } + BUFFER *head = dmc_buffer_queue_head(controller->receive_queue); + if (head != NULL) + { + if (head->state == ContainsData) + { + head->state = TransferInProgress; + dmc_start_data_output_transfer(controller, head->address, head->actual_block_len, TRUE); + } + } } void dmc_start_transfer_transmit_buffer(CTLR *controller) { - BUFFER *head = dmc_buffer_queue_head(controller->transmit_queue); - if (head != NULL) - { - if (head->state == ContainsData) - { - head->state = TransferInProgress; - dmc_start_data_output_transfer(controller, head->address, head->count, FALSE); - } - } + BUFFER *head = dmc_buffer_queue_head(controller->transmit_queue); + if (head != NULL) + { + if (head->state == ContainsData) + { + head->state = TransferInProgress; + dmc_start_data_output_transfer(controller, head->address, head->count, FALSE); + } + } } void dmc_check_for_output_transfer_completion(CTLR *controller) { - if (!dmc_is_rdyo_set(controller)) - { - sim_debug(DBG_INF, controller->device, "Output transfer completed\n"); - controller->transfer_state = Idle; - if (dmc_get_output_transfer_type(controller) == TYPE_BACCO) - { - if (dmc_is_out_io_set(controller)) - { - dmc_buffer_queue_release_head(controller->receive_queue); - controller->receive_buffer_output_transfers_completed++; - } - else - { - dmc_buffer_queue_release_head(controller->transmit_queue); - controller->transmit_buffer_output_transfers_completed++; - } - } - dmc_process_command(controller); // check for any input transfers - } + if (!dmc_is_rdyo_set(controller)) + { + sim_debug(DBG_INF, controller->device, "Output transfer completed\n"); + controller->transfer_state = Idle; + if (dmc_get_output_transfer_type(controller) == TYPE_BACCO) + { + if (dmc_is_out_io_set(controller)) + { + dmc_buffer_queue_release_head(controller->receive_queue); + controller->receive_buffer_output_transfers_completed++; + } + else + { + dmc_buffer_queue_release_head(controller->transmit_queue); + controller->transmit_buffer_output_transfers_completed++; + } + } + dmc_process_command(controller); // check for any input transfers + } } void dmc_process_input_transfer_completion(CTLR *controller) { - if (dmc_is_dmc(controller)) - { - if (!dmc_is_rqi_set(controller)) - { - uint16 sel4 = controller->csrs->sel4; - uint16 sel6 = controller->csrs->sel6; - dmc_clear_rdyi(controller); - //dmc_clrrxint(); - if (controller->transfer_type == TYPE_BASEI) - { - //int i; - uint32 baseaddr = sel6 >> 14 | sel4; - uint16 count = sel6 & 0x3FFF; - 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++) - //{ - // uint8 t = ((uint8)i + 1)*2; - // Map_WriteB(baseaddr + i, 1, &t); - //} - } - else if (controller->transfer_type == TYPE_BACCI) - { - uint32 addr = sel6 >> 14 | sel4; - uint16 count = sel6 & 0x3FFF; - if (controller->transfer_in_io != dmc_is_in_io_set(controller)) - { - sim_debug(DBG_TRC, controller->device, "IN IO MISMATCH\n"); - } + if (dmc_is_dmc(controller)) + { + if (!dmc_is_rqi_set(controller)) + { + uint16 sel4 = controller->csrs->sel4; + uint16 sel6 = controller->csrs->sel6; + dmc_clear_rdyi(controller); + //dmc_clrrxint(); + if (controller->transfer_type == TYPE_BASEI) + { + //int i; + uint32 baseaddr = ((sel6 >> 14) << 16) | sel4; + uint16 count = sel6 & 0x3FFF; + 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++) + //{ + // uint8 t = ((uint8)i + 1)*2; + // Map_WriteB(baseaddr + i, 1, &t); + //} + } + else if (controller->transfer_type == TYPE_BACCI) + { + uint32 addr = ((sel6 >> 14) << 16) | sel4; + uint16 count = sel6 & 0x3FFF; + if (controller->transfer_in_io != dmc_is_in_io_set(controller)) + { + sim_debug(DBG_TRC, controller->device, "IN IO MISMATCH\n"); + } - controller->transfer_in_io = dmc_is_in_io_set(controller); // using evdmc the flag is set when the transfer completes - not when it starts, evdca seems to set in only at the start of the transfer - clearing it when it completes - controller->state = Running; - if (controller->transfer_in_io) - { - dmc_buffer_queue_add(controller->receive_queue, addr, count); - dmc_buffer_fill_receive_buffers(controller); - controller->receive_buffer_input_transfers_completed++; - } - else - { - dmc_buffer_queue_add(controller->transmit_queue, addr, count); - dmc_buffer_send_transmit_buffers(controller); - controller->transmit_buffer_input_transfers_completed++; - } - } + controller->transfer_in_io = dmc_is_in_io_set(controller); // using evdmc the flag is set when the transfer completes - not when it starts, evdca seems to set in only at the start of the transfer - clearing it when it completes + controller->state = Running; + if (controller->transfer_in_io) + { + dmc_buffer_queue_add(controller->receive_queue, addr, count); + dmc_buffer_fill_receive_buffers(controller); + controller->receive_buffer_input_transfers_completed++; + } + else + { + dmc_buffer_queue_add(controller->transmit_queue, addr, count); + dmc_buffer_send_transmit_buffers(controller); + controller->transmit_buffer_input_transfers_completed++; + } + } - controller->transfer_state = Idle; - } - } - else - { - if (!dmc_is_rdyi_set(controller)) - { - uint16 sel4 = controller->csrs->sel4; - uint16 sel6 = controller->csrs->sel6; - //dmc_clrrxint(); - if (controller->transfer_type == TYPE_DMP_MODE) - { - uint16 mode = sel6 & DMP_TYPE_INPUT_MASK; - char * duplex = (mode & 1) ? "Full-Duplex" : "Half-Duplex"; - char * config; - if (mode & 4) - { - config = "Point-to-point"; - } - else - { - config = (mode & 2) ? "Tributary station" : "Control Station"; - } + controller->transfer_state = Idle; + } + } + else + { + if (!dmc_is_rdyi_set(controller)) + { + uint16 sel4 = controller->csrs->sel4; + uint16 sel6 = controller->csrs->sel6; + //dmc_clrrxint(); + if (controller->transfer_type == TYPE_DMP_MODE) + { + uint16 mode = sel6 & DMP_TYPE_INPUT_MASK; + char * duplex = (mode & 1) ? "Full-Duplex" : "Half-Duplex"; + char * config; + if (mode & 4) + { + config = "Point-to-point"; + } + else + { + config = (mode & 2) ? "Tributary station" : "Control Station"; + } - sim_debug(DBG_INF, controller->device, "Completing Mode input transfer, %s %s\n", duplex, config); - } - else if (controller->transfer_type == TYPE_DMP_CONTROL) - { - sim_debug(DBG_WRN, controller->device, "Control command (not processed yet)\n"); - } - else if (controller->transfer_type == TYPE_DMP_RECEIVE) - { - sim_debug(DBG_WRN, controller->device, "Receive Buffer command (not processed yet)\n"); - } - else if (controller->transfer_type == TYPE_DMP_TRANSMIT) - { - sim_debug(DBG_WRN, controller->device, "Transmit Buffer command (not processed yet)\n"); - } - else - { - sim_debug(DBG_WRN, controller->device, "Unrecognised command code %hu\n", controller->transfer_type); - } + sim_debug(DBG_INF, controller->device, "Completing Mode input transfer, %s %s\n", duplex, config); + } + else if (controller->transfer_type == TYPE_DMP_CONTROL) + { + sim_debug(DBG_WRN, controller->device, "Control command (not processed yet)\n"); + } + else if (controller->transfer_type == TYPE_DMP_RECEIVE) + { + sim_debug(DBG_WRN, controller->device, "Receive Buffer command (not processed yet)\n"); + } + else if (controller->transfer_type == TYPE_DMP_TRANSMIT) + { + sim_debug(DBG_WRN, controller->device, "Transmit Buffer command (not processed yet)\n"); + } + else + { + sim_debug(DBG_WRN, controller->device, "Unrecognised command code %hu\n", controller->transfer_type); + } - controller->transfer_state = Idle; - } - } + controller->transfer_state = Idle; + } + } } void dmc_process_command(CTLR *controller) { - if (dmc_is_master_clear_set(controller)) - { - dmc_process_master_clear(controller); - } - else - { - if (controller->transfer_state == InputTransfer) - { - dmc_process_input_transfer_completion(controller); - } - else if (controller->transfer_state == OutputTransfer) - { - dmc_check_for_output_transfer_completion(controller); - } - else if (dmc_is_rqi_set(controller)) - { - dmc_start_input_transfer(controller); - } - } + if (dmc_is_master_clear_set(controller)) + { + dmc_process_master_clear(controller); + } + else + { + if (controller->transfer_state == InputTransfer) + { + dmc_process_input_transfer_completion(controller); + } + else if (controller->transfer_state == OutputTransfer) + { + dmc_check_for_output_transfer_completion(controller); + } + else if (dmc_is_rqi_set(controller)) + { + dmc_start_input_transfer(controller); + } + } } t_stat dmc_rd(int32 *data, int32 PA, int32 access) { - CTLR *controller = dmc_get_controller_from_address(PA); - int reg = PA & 07; - sim_debug(DBG_TRC, controller->device, "dmc_rd(), addr=0x%x access=%d\n", PA, access); - *data = dmc_getreg(controller, PA, 1); + CTLR *controller = dmc_get_controller_from_address(PA); + int reg = PA & 07; + sim_debug(DBG_TRC, controller->device, "dmc_rd(), addr=0x%x access=%d\n", PA, access); + *data = dmc_getreg(controller, PA, 1); - return SCPE_OK; + return SCPE_OK; } t_stat dmc_wr(int32 data, int32 PA, int32 access) { - CTLR *controller = dmc_get_controller_from_address(PA); - int reg = PA & 07; - uint16 oldValue = dmc_getreg(controller, PA, 0); - if (access == WRITE) - { - sim_debug(DBG_TRC, controller->device, "dmc_wr(), addr=0x%08x, SEL%d, data=0x%04x\n", PA, reg, data); - } - else - { - sim_debug(DBG_TRC, controller->device, "dmc_wr(), addr=0x%08x, BSEL%d, data=%04x\n", PA, reg, data); - } + CTLR *controller = dmc_get_controller_from_address(PA); + int reg = PA & 07; + uint16 oldValue = dmc_getreg(controller, PA, 0); + if (access == WRITE) + { + sim_debug(DBG_TRC, controller->device, "dmc_wr(), addr=0x%08x, SEL%d, data=0x%04x\n", PA, reg, data); + } + else + { + sim_debug(DBG_TRC, controller->device, "dmc_wr(), addr=0x%08x, BSEL%d, data=%04x\n", PA, reg, data); + } - if (access == WRITE) - { - if (PA & 1) - sim_debug(DBG_WRN, controller->device, "dmc_wr(), Unexpected non-16-bit write access to SEL%d\n", reg); - dmc_setreg(controller, PA, data, 1); - } - else - { - uint16 mask; - if (PA & 1) - { - mask = 0xFF00; - data = data << 8; - } - else - { - mask = 0x00FF; - } + if (access == WRITE) + { + if (PA & 1) + sim_debug(DBG_WRN, controller->device, "dmc_wr(), Unexpected non-16-bit write access to SEL%d\n", reg); + dmc_setreg(controller, PA, data, 1); + } + else + { + uint16 mask; + if (PA & 1) + { + mask = 0xFF00; + data = data << 8; + } + else + { + mask = 0x00FF; + } - dmc_setreg(controller, PA, (oldValue & ~mask) | (data & mask), 1); - } + dmc_setreg(controller, PA, (oldValue & ~mask) | (data & mask), 1); + } - if (dmc_getsel(reg) == 0 || dmc_getsel(reg) == 1) - { - dmc_process_command(controller); - } + if (dmc_getsel(reg) == 0 || dmc_getsel(reg) == 1) + { + dmc_process_command(controller); + } - return SCPE_OK; + return SCPE_OK; } int32 dmc_rxint (void) { - int i; - int32 ans = 0; /* no interrupt request active */ - for (i=0; irxi != 0) - { - DIB *dib = (DIB *)controller->device->ctxt; - ans = dib->vec; - dmc_clrrxint(controller); - break; - } - } + int i; + int32 ans = 0; /* no interrupt request active */ + for (i=0; irxi != 0) + { + DIB *dib = (DIB *)controller->device->ctxt; + ans = dib->vec; + dmc_clrrxint(controller); + break; + } + } - return ans; - } + return ans; + } int32 dmc_txint (void) { - int i; - int32 ans = 0; /* no interrupt request active */ - for (i=0; itxi != 0) - { - DIB *dib = (DIB *)controller->device->ctxt; - ans = dib->vec + 4; - dmc_clrtxint(controller); - break; - } - } + int i; + int32 ans = 0; /* no interrupt request active */ + for (i=0; itxi != 0) + { + DIB *dib = (DIB *)controller->device->ctxt; + ans = dib->vec + 4; + dmc_clrtxint(controller); + break; + } + } - return ans; + return ans; - //int32 ans = 0; /* no interrupt request active */ - //if (controller->txi != 0) - //{ - // DIB *dib = (DIB *)controller->device->ctxt; - // ans = dib->vec + 4; - // dmc_clrtxint(); - //} + //int32 ans = 0; /* no interrupt request active */ + //if (controller->txi != 0) + //{ + // DIB *dib = (DIB *)controller->device->ctxt; + // ans = dib->vec + 4; + // dmc_clrtxint(); + //} - //return ans; + //return ans; } t_stat dmc_reset (DEVICE *dptr) { - t_stat ans = SCPE_OK; - //int32 ndev; - CTLR *controller = dmc_get_controller_from_device(dptr); + t_stat ans = SCPE_OK; + //int32 ndev; + CTLR *controller = dmc_get_controller_from_device(dptr); - sim_debug(DBG_TRC, dptr, "dmc_reset()\n"); + sim_debug(DBG_TRC, dptr, "dmc_reset()\n"); - if (dmc_get_unit_stats(dptr->units) == NULL) - { - dmc_set_unit_stats(dptr->units, (UNIT_STATS *)malloc(sizeof(UNIT_STATS))); - dmc_reset_unit_stats(dmc_get_unit_stats(dptr->units)); - } + if (dmc_get_unit_stats(dptr->units) == NULL) + { + dmc_set_unit_stats(dptr->units, (UNIT_STATS *)malloc(sizeof(UNIT_STATS))); + dmc_reset_unit_stats(dmc_get_unit_stats(dptr->units)); + } - dmc_clrrxint(controller); - dmc_clrtxint(controller); - sim_cancel (controller->device->units); /* stop poll */ - if (controller->svc_poll_interval == -1) controller->svc_poll_interval = POLL; + dmc_clrrxint(controller); + dmc_clrtxint(controller); + sim_cancel (controller->device->units); /* stop poll */ + if (controller->svc_poll_interval == -1) controller->svc_poll_interval = POLL; - if (!(dptr->flags & DEV_DIS)) - { + if (!(dptr->flags & DEV_DIS)) + { ans = auto_config (dptr->name, DMC_UNITSPERDEVICE); - } - return ans; + } + return ans; } t_stat dmc_attach (UNIT *uptr, char *cptr) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - t_stat ans = SCPE_OK; + CTLR *controller = dmc_get_controller_from_unit(uptr); + t_stat ans = SCPE_OK; ans = dmc_open_master_socket(controller, cptr); - if (ans == SCPE_OK) - { - controller->line->socket = INVALID_SOCKET; - uptr->flags = uptr->flags | UNIT_ATT; /* set unit attached flag */ - uptr->filename = (char *)malloc(strlen(cptr)+1); - strcpy(uptr->filename, cptr); - controller->line->receive_port = uptr->filename; - } + if (ans == SCPE_OK) + { + controller->line->socket = INVALID_SOCKET; + uptr->flags = uptr->flags | UNIT_ATT; /* set unit attached flag */ + uptr->filename = (char *)malloc(strlen(cptr)+1); + strcpy(uptr->filename, cptr); + controller->line->receive_port = uptr->filename; + } - return ans; + return ans; } t_stat dmc_detach (UNIT *uptr) { - CTLR *controller = dmc_get_controller_from_unit(uptr); - dmc_close_master_socket(controller); - uptr->flags = uptr->flags & ~UNIT_ATT; /* clear unit attached flag */ - free(uptr->filename); - uptr->filename = NULL; + CTLR *controller = dmc_get_controller_from_unit(uptr); + dmc_close_master_socket(controller); + uptr->flags = uptr->flags & ~UNIT_ATT; /* clear unit attached flag */ + free(uptr->filename); + uptr->filename = NULL; - return SCPE_OK; + return SCPE_OK; } diff --git a/PDP11/pdp11_io_lib.c b/PDP11/pdp11_io_lib.c index 167d5d10..fdbb6cd9 100644 --- a/PDP11/pdp11_io_lib.c +++ b/PDP11/pdp11_io_lib.c @@ -352,7 +352,7 @@ AUTO_CON auto_tab[] = { { { NULL }, 1, 2, 8, 8 }, /* DU11 */ { { NULL }, 1, 2, 8, 8 }, /* DUP11 */ { { 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 */ { { NULL }, 1, 2, 8, 8 }, /* KMC11 */ { { NULL }, 1, 2, 8, 8 }, /* LPP11 */ diff --git a/VAX/vax780_defs.h b/VAX/vax780_defs.h index f47b8656..7700ac3c 100644 --- a/VAX/vax780_defs.h +++ b/VAX/vax780_defs.h @@ -313,7 +313,7 @@ typedef struct { #define IOLN_PTR 004 #define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */ #define IOLN_PTP 004 -#define IOBA_DMC (IOPAGEBASE + 0760060) +#define IOBA_DMC (IOPAGEBASE + 0760060) /* DMC11 */ #define IOLN_DMC 010 /* Interrupt assignments; within each level, priority is right to left */