mirror of
https://github.com/simh/simh.git
synced 2026-01-26 04:01:38 +00:00
Notes For V3.5-0
The source set has been extensively overhauled. For correct viewing, set Visual C++ or Emacs to have tab stops every 4 characters. 1. New Features in 3.4-1 1.1 All Ethernet devices - Added Windows user-defined adapter names (from Timothe Litt) 1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors - Added support for SET <unit>n DISCONNECT 1.3 VAX - Added latent QDSS support - Revised autoconfigure to handle QDSS 1.4 PDP-11 - Revised autoconfigure to handle more casees 2. Bugs Fixed in 3.4-1 2.1 SCP and libraries - Trim trailing spaces on all input (for example, attach file names) - Fixed sim_sock spurious SIGPIPE error in Unix/Linux - Fixed sim_tape misallocation of TPC map array for 64b simulators 2.2 1401 - Fixed bug, CPU reset was clearing SSB through SSG 2.3 PDP-11 - Fixed bug in VH vector display routine - Fixed XU runt packet processing (found by Tim Chapman) 2.4 Interdata - Fixed bug in SHOW PAS CONN/STATS - Fixed potential integer overflow exception in divide 2.5 SDS - Fixed bug in SHOW MUX CONN/STATS 2.6 HP - Fixed bug in SHOW MUX CONN/STATS 2.7 PDP-8 - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.8 PDP-18b - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.9 Nova, Eclipse - Fixed potential integer overflow exception in divide
This commit is contained in:
committed by
Mark Pizzolato
parent
ec60bbf329
commit
b7c1eae41f
2651
PDP18B/pdp18b_cpu.c
2651
PDP18B/pdp18b_cpu.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/* pdp18b_defs.h: 18b PDP simulator definitions
|
||||
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,28 +19,28 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
18-Oct-03 RMS Added DECtape off reel message
|
||||
18-Jul-03 RMS Added FP15 support
|
||||
Added XVM support
|
||||
Added EAE option for PDP-4
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
04-Feb-03 RMS Added RB09, LP09 support
|
||||
22-Nov-02 RMS Added PDP-4 drum support
|
||||
05-Oct-02 RMS Added DIB structure
|
||||
25-Jul-02 RMS Added PDP-4 DECtape support
|
||||
10-Feb-02 RMS Added PDP-7 DECtape support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
27-May-01 RMS Added second Teletype support
|
||||
21-Jan-01 RMS Added DECtape support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
02-Jan-96 RMS Added fixed head and moving head disks
|
||||
31-Dec-95 RMS Added memory management
|
||||
19-Mar-95 RMS Added dynamic memory size
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
18-Oct-03 RMS Added DECtape off reel message
|
||||
18-Jul-03 RMS Added FP15 support
|
||||
Added XVM support
|
||||
Added EAE option for PDP-4
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
04-Feb-03 RMS Added RB09, LP09 support
|
||||
22-Nov-02 RMS Added PDP-4 drum support
|
||||
05-Oct-02 RMS Added DIB structure
|
||||
25-Jul-02 RMS Added PDP-4 DECtape support
|
||||
10-Feb-02 RMS Added PDP-7 DECtape support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
27-May-01 RMS Added second Teletype support
|
||||
21-Jan-01 RMS Added DECtape support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
02-Jan-96 RMS Added fixed head and moving head disks
|
||||
31-Dec-95 RMS Added memory management
|
||||
19-Mar-95 RMS Added dynamic memory size
|
||||
|
||||
The author gratefully acknowledges the help of Craig St. Clair and
|
||||
Deb Tevonian in locating archival material about the 18b PDP's, and of
|
||||
@@ -48,230 +48,228 @@
|
||||
*/
|
||||
|
||||
#ifndef _PDP18B_DEFS_H_
|
||||
#define _PDP18B_DEFS_H_ 0
|
||||
#define _PDP18B_DEFS_H_ 0
|
||||
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
||||
/* Models: only one should be defined
|
||||
|
||||
model memory CPU options I/O options
|
||||
model memory CPU options I/O options
|
||||
|
||||
PDP4 8K Type 18 EAE Type 65 KSR-28 Teletype (Baudot)
|
||||
??Type 16 mem extension integral paper tape reader
|
||||
Type 75 paper tape punch
|
||||
integral real time clock
|
||||
Type 62 line printer (Hollerith)
|
||||
Type 550/555 DECtape
|
||||
Type 24 serial drum
|
||||
PDP4 8K Type 18 EAE Type 65 KSR-28 Teletype (Baudot)
|
||||
??Type 16 mem extension integral paper tape reader
|
||||
Type 75 paper tape punch
|
||||
integral real time clock
|
||||
Type 62 line printer (Hollerith)
|
||||
Type 550/555 DECtape
|
||||
Type 24 serial drum
|
||||
|
||||
PDP7 32K Type 177 EAE Type 649 KSR-33 Teletype
|
||||
Type 148 mem extension Type 444 paper tape reader
|
||||
Type 75 paper tape punch
|
||||
integral real time clock
|
||||
Type 647B line printer (sixbit)
|
||||
Type 550/555 DECtape
|
||||
Type 24 serial drum
|
||||
PDP7 32K Type 177 EAE Type 649 KSR-33 Teletype
|
||||
Type 148 mem extension Type 444 paper tape reader
|
||||
Type 75 paper tape punch
|
||||
integral real time clock
|
||||
Type 647B line printer (sixbit)
|
||||
Type 550/555 DECtape
|
||||
Type 24 serial drum
|
||||
|
||||
PDP9 32K KE09A EAE KSR-33 Teletype
|
||||
KF09A auto pri intr PC09A paper tape reader and punch
|
||||
KG09B mem extension integral real time clock
|
||||
KP09A power detection Type 647D/E line printer (sixbit)
|
||||
KX09A mem protection LP09 line printer (ASCII)
|
||||
RF09/RS09 fixed head disk
|
||||
RB09 fixed head disk
|
||||
TC59 magnetic tape
|
||||
TC02/TU55 DECtape
|
||||
LT09A additional Teletypes
|
||||
PDP9 32K KE09A EAE KSR-33 Teletype
|
||||
KF09A auto pri intr PC09A paper tape reader and punch
|
||||
KG09B mem extension integral real time clock
|
||||
KP09A power detection Type 647D/E line printer (sixbit)
|
||||
KX09A mem protection LP09 line printer (ASCII)
|
||||
RF09/RS09 fixed head disk
|
||||
RB09 fixed head disk
|
||||
TC59 magnetic tape
|
||||
TC02/TU55 DECtape
|
||||
LT09A additional Teletypes
|
||||
|
||||
PDP15 128K KE15 EAE KSR-35 Teletype
|
||||
KA15 auto pri intr PC15 paper tape reader and punch
|
||||
KF15 power detection KW15 real time clock
|
||||
KM15 mem protection LP09 line printer
|
||||
KT15 mem relocation LP15 line printer
|
||||
FP15 floating point RP15 disk pack
|
||||
XVM option RF15/RF09 fixed head disk
|
||||
TC59D magnetic tape
|
||||
TC15/TU56 DECtape
|
||||
LT15/LT19 additional Teletypes
|
||||
PDP15 128K KE15 EAE KSR-35 Teletype
|
||||
KA15 auto pri intr PC15 paper tape reader and punch
|
||||
KF15 power detection KW15 real time clock
|
||||
KM15 mem protection LP09 line printer
|
||||
KT15 mem relocation LP15 line printer
|
||||
FP15 floating point RP15 disk pack
|
||||
XVM option RF15/RF09 fixed head disk
|
||||
TC59D magnetic tape
|
||||
TC15/TU56 DECtape
|
||||
LT15/LT19 additional Teletypes
|
||||
|
||||
??Indicates not implemented. The PDP-4 manual refers to a memory
|
||||
??extension control; there is no documentation on it.
|
||||
*/
|
||||
|
||||
#if !defined (PDP4) && !defined (PDP7) && !defined (PDP9) && !defined (PDP15)
|
||||
#define PDP15 0 /* default to PDP-15 */
|
||||
#define PDP15 0 /* default to PDP-15 */
|
||||
#endif
|
||||
|
||||
|
||||
/* Simulator stop codes */
|
||||
|
||||
#define STOP_RSRV 1 /* must be 1 */
|
||||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
#define STOP_XCT 4 /* nested XCT's */
|
||||
#define STOP_API 5 /* invalid API int */
|
||||
#define STOP_NONSTD 6 /* non-std dev num */
|
||||
#define STOP_MME 7 /* mem mgt error */
|
||||
#define STOP_FPDIS 8 /* fp inst, fpp disabled */
|
||||
#define STOP_DTOFF 9 /* DECtape off reel */
|
||||
#define STOP_RSRV 1 /* must be 1 */
|
||||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
#define STOP_XCT 4 /* nested XCT's */
|
||||
#define STOP_API 5 /* invalid API int */
|
||||
#define STOP_NONSTD 6 /* non-std dev num */
|
||||
#define STOP_MME 7 /* mem mgt error */
|
||||
#define STOP_FPDIS 8 /* fp inst, fpp disabled */
|
||||
#define STOP_DTOFF 9 /* DECtape off reel */
|
||||
|
||||
/* Peripheral configuration */
|
||||
|
||||
#if defined (PDP4)
|
||||
#define ADDRSIZE 13
|
||||
#define KSR28 0 /* Baudot terminal */
|
||||
#define TYPE62 0 /* Hollerith printer */
|
||||
#define TYPE550 0 /* DECtape */
|
||||
#define DRM 0 /* drum */
|
||||
#define ADDRSIZE 13
|
||||
#define KSR28 0 /* Baudot terminal */
|
||||
#define TYPE62 0 /* Hollerith printer */
|
||||
#define TYPE550 0 /* DECtape */
|
||||
#define DRM 0 /* drum */
|
||||
#elif defined (PDP7)
|
||||
#define ADDRSIZE 15
|
||||
#define TYPE647 0 /* sixbit printer */
|
||||
#define TYPE550 0 /* DECtape */
|
||||
#define DRM 0 /* drum */
|
||||
#define ADDRSIZE 15
|
||||
#define TYPE647 0 /* sixbit printer */
|
||||
#define TYPE550 0 /* DECtape */
|
||||
#define DRM 0 /* drum */
|
||||
#elif defined (PDP9)
|
||||
#define ADDRSIZE 15
|
||||
#define TYPE647 0 /* sixbit printer */
|
||||
#define LP09 0 /* ASCII printer */
|
||||
#define RB 0 /* fixed head disk */
|
||||
#define RF 0 /* fixed head disk */
|
||||
#define MTA 0 /* magtape */
|
||||
#define TC02 0 /* DECtape */
|
||||
#define TTY1 4 /* second Teletype(s) */
|
||||
#define BRMASK 0076000 /* bounds mask */
|
||||
#define ADDRSIZE 15
|
||||
#define TYPE647 0 /* sixbit printer */
|
||||
#define LP09 0 /* ASCII printer */
|
||||
#define RB 0 /* fixed head disk */
|
||||
#define RF 0 /* fixed head disk */
|
||||
#define MTA 0 /* magtape */
|
||||
#define TC02 0 /* DECtape */
|
||||
#define TTY1 4 /* second Teletype(s) */
|
||||
#define BRMASK 0076000 /* bounds mask */
|
||||
#elif defined (PDP15)
|
||||
#define ADDRSIZE 17
|
||||
#define LP09 0 /* ASCII printer */
|
||||
#define LP15 0 /* DMA printer */
|
||||
#define RF 0 /* fixed head disk */
|
||||
#define RP 0 /* disk pack */
|
||||
#define MTA 0 /* magtape */
|
||||
#define TC02 0 /* DECtape */
|
||||
#define TTY1 16 /* second Teletype(s) */
|
||||
#define BRMASK 0377400 /* bounds mask */
|
||||
#define BRMASK_XVM 0777400 /* bounds mask, XVM */
|
||||
#define ADDRSIZE 17
|
||||
#define LP09 0 /* ASCII printer */
|
||||
#define LP15 0 /* DMA printer */
|
||||
#define RF 0 /* fixed head disk */
|
||||
#define RP 0 /* disk pack */
|
||||
#define MTA 0 /* magtape */
|
||||
#define TC02 0 /* DECtape */
|
||||
#define TTY1 16 /* second Teletype(s) */
|
||||
#define BRMASK 0377400 /* bounds mask */
|
||||
#define BRMASK_XVM 0777400 /* bounds mask, XVM */
|
||||
#endif
|
||||
|
||||
/* Memory */
|
||||
|
||||
#define AMASK ((1 << ADDRSIZE) - 1) /* address mask */
|
||||
#define IAMASK 077777 /* ind address mask */
|
||||
#define BLKMASK (AMASK & (~IAMASK)) /* block mask */
|
||||
#define MAXMEMSIZE (1 << ADDRSIZE) /* max memory size */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
#define AMASK ((1 << ADDRSIZE) - 1) /* address mask */
|
||||
#define IAMASK 077777 /* ind address mask */
|
||||
#define BLKMASK (AMASK & (~IAMASK)) /* block mask */
|
||||
#define MAXMEMSIZE (1 << ADDRSIZE) /* max memory size */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
|
||||
/* Instructions */
|
||||
|
||||
#define I_V_OP 14 /* opcode */
|
||||
#define I_M_OP 017
|
||||
#define I_V_IND 13 /* indirect */
|
||||
#define I_V_IDX 12 /* index */
|
||||
#define I_IND (1 << I_V_IND)
|
||||
#define I_IDX (1 << I_V_IDX)
|
||||
#define B_DAMASK 017777 /* bank mode address */
|
||||
#define B_EPCMASK (AMASK & ~B_DAMASK)
|
||||
#define P_DAMASK 007777 /* page mode address */
|
||||
#define P_EPCMASK (AMASK & ~P_DAMASK)
|
||||
#define I_V_OP 14 /* opcode */
|
||||
#define I_M_OP 017
|
||||
#define I_V_IND 13 /* indirect */
|
||||
#define I_V_IDX 12 /* index */
|
||||
#define I_IND (1 << I_V_IND)
|
||||
#define I_IDX (1 << I_V_IDX)
|
||||
#define B_DAMASK 017777 /* bank mode address */
|
||||
#define B_EPCMASK (AMASK & ~B_DAMASK)
|
||||
#define P_DAMASK 007777 /* page mode address */
|
||||
#define P_EPCMASK (AMASK & ~P_DAMASK)
|
||||
|
||||
/* Memory cycles */
|
||||
|
||||
#define FE 0
|
||||
#define DF 1
|
||||
#define RD 2
|
||||
#define WR 3
|
||||
#define FE 0
|
||||
#define DF 1
|
||||
#define RD 2
|
||||
#define WR 3
|
||||
|
||||
/* Memory status codes */
|
||||
|
||||
#define MM_OK 0
|
||||
#define MM_ERR 1
|
||||
#define MM_OK 0
|
||||
#define MM_ERR 1
|
||||
|
||||
/* Memory management relocation checks (PDP-15 KT15 and XVM only) */
|
||||
|
||||
#define REL_C -1 /* console */
|
||||
#define REL_R 0 /* read */
|
||||
#define REL_W 1 /* write */
|
||||
#define REL_C -1 /* console */
|
||||
#define REL_R 0 /* read */
|
||||
#define REL_W 1 /* write */
|
||||
|
||||
/* Architectural constants */
|
||||
|
||||
#define DMASK 0777777 /* data mask */
|
||||
#define LINK (DMASK + 1) /* link */
|
||||
#define LACMASK (LINK | DMASK) /* link + data */
|
||||
#define SIGN 0400000 /* sign bit */
|
||||
#define OP_JMS 0100000 /* JMS */
|
||||
#define OP_JMP 0600000 /* JMP */
|
||||
#define OP_HLT 0740040 /* HLT */
|
||||
#define DMASK 0777777 /* data mask */
|
||||
#define LINK (DMASK + 1) /* link */
|
||||
#define LACMASK (LINK | DMASK) /* link + data */
|
||||
#define SIGN 0400000 /* sign bit */
|
||||
#define OP_JMS 0100000 /* JMS */
|
||||
#define OP_JMP 0600000 /* JMP */
|
||||
#define OP_HLT 0740040 /* HLT */
|
||||
|
||||
/* IOT subroutine return codes */
|
||||
|
||||
#define IOT_V_SKP 18 /* skip */
|
||||
#define IOT_V_REASON 19 /* reason */
|
||||
#define IOT_SKP (1 << IOT_V_SKP)
|
||||
#define IOT_REASON (1 << IOT_V_REASON)
|
||||
#define IOT_V_SKP 18 /* skip */
|
||||
#define IOT_V_REASON 19 /* reason */
|
||||
#define IOT_SKP (1 << IOT_V_SKP)
|
||||
#define IOT_REASON (1 << IOT_V_REASON)
|
||||
|
||||
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
|
||||
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
|
||||
|
||||
/* PC change queue */
|
||||
|
||||
#define PCQ_SIZE 64 /* must be 2**n */
|
||||
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC
|
||||
#define PCQ_SIZE 64 /* must be 2**n */
|
||||
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC
|
||||
|
||||
/* XVM memory management registers */
|
||||
|
||||
#define MM_RDIS 0400000 /* reloc disabled */
|
||||
#define MM_V_GM 15 /* G mode */
|
||||
#define MM_M_GM 03
|
||||
#define MM_GM (MM_M_GM << MM_V_GM)
|
||||
#define MM_G_W0 0077777 /* virt addr width */
|
||||
#define MM_G_W1 0177777
|
||||
#define MM_G_W2 0777777
|
||||
#define MM_G_W3 0377777
|
||||
#define MM_G_B0 0060000 /* SAS base */
|
||||
#define MM_G_B1 0160000
|
||||
#define MM_G_B2 0760000
|
||||
#define MM_G_B3 0360000
|
||||
#define MM_UIOT 0040000 /* user mode IOT's */
|
||||
#define MM_WP 0020000 /* share write prot */
|
||||
#define MM_SH 0010000 /* share enabled */
|
||||
#define MM_V_SLR 10 /* segment length reg */
|
||||
#define MM_M_SLR 03
|
||||
#define MM_SLR_L0 001000 /* SAS length */
|
||||
#define MM_SLR_L1 002000
|
||||
#define MM_SLR_L2 010000
|
||||
#define MM_SLR_L3 020000
|
||||
#define MM_SBR_MASK 01777 /* share base reg */
|
||||
#define MM_GETGM(x) (((x) >> MM_V_GM) & MM_M_GM)
|
||||
#define MM_GETSLR(x) (((x) >> MM_V_SLR) & MM_M_SLR)
|
||||
|
||||
#define MM_RDIS 0400000 /* reloc disabled */
|
||||
#define MM_V_GM 15 /* G mode */
|
||||
#define MM_M_GM 03
|
||||
#define MM_GM (MM_M_GM << MM_V_GM)
|
||||
#define MM_G_W0 0077777 /* virt addr width */
|
||||
#define MM_G_W1 0177777
|
||||
#define MM_G_W2 0777777
|
||||
#define MM_G_W3 0377777
|
||||
#define MM_G_B0 0060000 /* SAS base */
|
||||
#define MM_G_B1 0160000
|
||||
#define MM_G_B2 0760000
|
||||
#define MM_G_B3 0360000
|
||||
#define MM_UIOT 0040000 /* user mode IOT's */
|
||||
#define MM_WP 0020000 /* share write prot */
|
||||
#define MM_SH 0010000 /* share enabled */
|
||||
#define MM_V_SLR 10 /* segment length reg */
|
||||
#define MM_M_SLR 03
|
||||
#define MM_SLR_L0 001000 /* SAS length */
|
||||
#define MM_SLR_L1 002000
|
||||
#define MM_SLR_L2 010000
|
||||
#define MM_SLR_L3 020000
|
||||
#define MM_SBR_MASK 01777 /* share base reg */
|
||||
#define MM_GETGM(x) (((x) >> MM_V_GM) & MM_M_GM)
|
||||
#define MM_GETSLR(x) (((x) >> MM_V_SLR) & MM_M_SLR)
|
||||
|
||||
/* Device information block */
|
||||
|
||||
#define DEV_MAXBLK 8 /* max dev block */
|
||||
#define DEV_MAX 64 /* total devices */
|
||||
#define DEV_MAXBLK 8 /* max dev block */
|
||||
#define DEV_MAX 64 /* total devices */
|
||||
|
||||
struct pdp18b_dib {
|
||||
uint32 dev; /* base dev number */
|
||||
uint32 num; /* number of slots */
|
||||
int32 (*iors)(void); /* IORS responder */
|
||||
int32 (*dsp[DEV_MAXBLK])(int32 dev, int32 pulse, int32 dat);
|
||||
};
|
||||
|
||||
typedef struct pdp18b_dib DIB;
|
||||
typedef struct {
|
||||
uint32 dev; /* base dev number */
|
||||
uint32 num; /* number of slots */
|
||||
int32 (*iors)(void); /* IORS responder */
|
||||
int32 (*dsp[DEV_MAXBLK])(int32 dev, int32 pulse, int32 dat);
|
||||
} DIB;
|
||||
|
||||
/* Standard device numbers */
|
||||
|
||||
#define DEV_PTR 001 /* paper tape reader */
|
||||
#define DEV_PTP 002 /* paper tape punch */
|
||||
#define DEV_TTI 003 /* console input */
|
||||
#define DEV_TTO 004 /* console output */
|
||||
#define DEV_TTI1 041 /* extra terminals */
|
||||
#define DEV_TTO1 040
|
||||
#define DEV_DRM 060 /* drum */
|
||||
#define DEV_RP 063 /* RP15 */
|
||||
#define DEV_LPT 065 /* line printer */
|
||||
#define DEV_RF 070 /* RF09 */
|
||||
#define DEV_RB 071 /* RB09 */
|
||||
#define DEV_MT 073 /* magtape */
|
||||
#define DEV_DTA 075 /* dectape */
|
||||
|
||||
#define DEV_PTR 001 /* paper tape reader */
|
||||
#define DEV_PTP 002 /* paper tape punch */
|
||||
#define DEV_TTI 003 /* console input */
|
||||
#define DEV_TTO 004 /* console output */
|
||||
#define DEV_TTI1 041 /* extra terminals */
|
||||
#define DEV_TTO1 040
|
||||
#define DEV_DRM 060 /* drum */
|
||||
#define DEV_RP 063 /* RP15 */
|
||||
#define DEV_LPT 065 /* line printer */
|
||||
#define DEV_RF 070 /* RF09 */
|
||||
#define DEV_RB 071 /* RB09 */
|
||||
#define DEV_MT 073 /* magtape */
|
||||
#define DEV_DTA 075 /* dectape */
|
||||
|
||||
/* Interrupt system
|
||||
|
||||
The interrupt system can be modelled on either the flag driven system
|
||||
@@ -279,210 +277,210 @@ typedef struct pdp18b_dib DIB;
|
||||
If flag based, API is hard to implement; if API based, IORS requires
|
||||
extra code for implementation. I've chosen an API based model.
|
||||
|
||||
API channel Device API priority Notes
|
||||
API channel Device API priority Notes
|
||||
|
||||
00 software 4 4
|
||||
01 software 5 5
|
||||
02 software 6 6
|
||||
03 software 7 7
|
||||
04 TC02/TC15 1
|
||||
05 TC59D 1
|
||||
06 drum 1 PDP-9 only
|
||||
07 RB09 1 PDP-9 only
|
||||
10 paper tape reader 2
|
||||
11 real time clock 3
|
||||
12 power fail 0
|
||||
13 memory parity 0
|
||||
14 display 2
|
||||
15 card reader 2
|
||||
16 line printer 2
|
||||
17 A/D converter 0
|
||||
20 interprocessor buffer 3
|
||||
21 360 link 3 PDP-9 only
|
||||
22 data phone 2 PDP-15 only
|
||||
23 RF09/RF15 1
|
||||
24 RP15 1 PDP-15 only
|
||||
25 plotter 1 PDP-15 only
|
||||
26 -
|
||||
27 -
|
||||
30 -
|
||||
31 -
|
||||
32 -
|
||||
33 -
|
||||
34 LT15 TTO 3 PDP-15 only
|
||||
35 LT15 TTI 3 PDP-15 only
|
||||
36 -
|
||||
37 -
|
||||
00 software 4 4
|
||||
01 software 5 5
|
||||
02 software 6 6
|
||||
03 software 7 7
|
||||
04 TC02/TC15 1
|
||||
05 TC59D 1
|
||||
06 drum 1 PDP-9 only
|
||||
07 RB09 1 PDP-9 only
|
||||
10 paper tape reader 2
|
||||
11 real time clock 3
|
||||
12 power fail 0
|
||||
13 memory parity 0
|
||||
14 display 2
|
||||
15 card reader 2
|
||||
16 line printer 2
|
||||
17 A/D converter 0
|
||||
20 interprocessor buffer 3
|
||||
21 360 link 3 PDP-9 only
|
||||
22 data phone 2 PDP-15 only
|
||||
23 RF09/RF15 1
|
||||
24 RP15 1 PDP-15 only
|
||||
25 plotter 1 PDP-15 only
|
||||
26 -
|
||||
27 -
|
||||
30 -
|
||||
31 -
|
||||
32 -
|
||||
33 -
|
||||
34 LT15 TTO 3 PDP-15 only
|
||||
35 LT15 TTI 3 PDP-15 only
|
||||
36 -
|
||||
37 -
|
||||
|
||||
On the PDP-9, any API level active masks PI, and PI does not mask API.
|
||||
On the PDP-15, only the hardware API levels active mask PI, and PI masks
|
||||
the API software levels. */
|
||||
|
||||
#define API_ML0 0200 /* API masks: level 0 */
|
||||
#define API_ML1 0100
|
||||
#define API_ML2 0040
|
||||
#define API_ML3 0020
|
||||
#define API_ML4 0010
|
||||
#define API_ML5 0004
|
||||
#define API_ML6 0002
|
||||
#define API_ML7 0001 /* level 7 */
|
||||
#define API_ML0 0200 /* API masks: level 0 */
|
||||
#define API_ML1 0100
|
||||
#define API_ML2 0040
|
||||
#define API_ML3 0020
|
||||
#define API_ML4 0010
|
||||
#define API_ML5 0004
|
||||
#define API_ML6 0002
|
||||
#define API_ML7 0001 /* level 7 */
|
||||
|
||||
#if defined (PDP9) /* levels which mask PI */
|
||||
#define API_MASKPI (API_ML0|API_ML1|API_ML2|API_ML3|API_ML4|API_ML5|API_ML6|API_ML7)
|
||||
#if defined (PDP9) /* levels which mask PI */
|
||||
#define API_MASKPI (API_ML0|API_ML1|API_ML2|API_ML3|API_ML4|API_ML5|API_ML6|API_ML7)
|
||||
#else
|
||||
#define API_MASKPI (API_ML0|API_ML1|API_ML2|API_ML3)
|
||||
#define API_MASKPI (API_ML0|API_ML1|API_ML2|API_ML3)
|
||||
#endif
|
||||
|
||||
#define API_HLVL 4 /* hwre levels */
|
||||
#define ACH_SWRE 040 /* swre int vec */
|
||||
#define API_HLVL 4 /* hwre levels */
|
||||
#define ACH_SWRE 040 /* swre int vec */
|
||||
|
||||
/* API level 0 */
|
||||
|
||||
#define INT_V_PWRFL 0 /* powerfail */
|
||||
#define INT_V_PWRFL 0 /* powerfail */
|
||||
|
||||
#define INT_PWRFL (1 << INT_V_PWRFL)
|
||||
#define INT_PWRFL (1 << INT_V_PWRFL)
|
||||
|
||||
#define API_PWRFL 0
|
||||
#define API_PWRFL 0
|
||||
|
||||
#define ACH_PWRFL 052
|
||||
#define ACH_PWRFL 052
|
||||
|
||||
/* API level 1 */
|
||||
|
||||
#define INT_V_DTA 0 /* DECtape */
|
||||
#define INT_V_MTA 1 /* magtape */
|
||||
#define INT_V_DRM 2 /* drum */
|
||||
#define INT_V_RF 3 /* fixed head disk */
|
||||
#define INT_V_RP 4 /* disk pack */
|
||||
#define INT_V_RB 5 /* RB disk */
|
||||
#define INT_V_DTA 0 /* DECtape */
|
||||
#define INT_V_MTA 1 /* magtape */
|
||||
#define INT_V_DRM 2 /* drum */
|
||||
#define INT_V_RF 3 /* fixed head disk */
|
||||
#define INT_V_RP 4 /* disk pack */
|
||||
#define INT_V_RB 5 /* RB disk */
|
||||
|
||||
#define INT_DTA (1 << INT_V_DTA)
|
||||
#define INT_MTA (1 << INT_V_MTA)
|
||||
#define INT_DRM (1 << INT_V_DRM)
|
||||
#define INT_RF (1 << INT_V_RF)
|
||||
#define INT_RP (1 << INT_V_RP)
|
||||
#define INT_RB (1 << INT_V_RB)
|
||||
#define INT_DTA (1 << INT_V_DTA)
|
||||
#define INT_MTA (1 << INT_V_MTA)
|
||||
#define INT_DRM (1 << INT_V_DRM)
|
||||
#define INT_RF (1 << INT_V_RF)
|
||||
#define INT_RP (1 << INT_V_RP)
|
||||
#define INT_RB (1 << INT_V_RB)
|
||||
|
||||
#define API_DTA 1
|
||||
#define API_MTA 1
|
||||
#define API_DRM 1
|
||||
#define API_RF 1
|
||||
#define API_RP 1
|
||||
#define API_RB 1
|
||||
#define API_DTA 1
|
||||
#define API_MTA 1
|
||||
#define API_DRM 1
|
||||
#define API_RF 1
|
||||
#define API_RP 1
|
||||
#define API_RB 1
|
||||
|
||||
#define ACH_DTA 044
|
||||
#define ACH_MTA 045
|
||||
#define ACH_DRM 046
|
||||
#define ACH_RB 047
|
||||
#define ACH_RF 063
|
||||
#define ACH_RP 064
|
||||
#define ACH_DTA 044
|
||||
#define ACH_MTA 045
|
||||
#define ACH_DRM 046
|
||||
#define ACH_RB 047
|
||||
#define ACH_RF 063
|
||||
#define ACH_RP 064
|
||||
|
||||
/* API level 2 */
|
||||
|
||||
#define INT_V_PTR 0 /* paper tape reader */
|
||||
#define INT_V_LPT 1 /* line printer */
|
||||
#define INT_V_LPTSPC 2 /* line printer spc */
|
||||
#define INT_V_PTR 0 /* paper tape reader */
|
||||
#define INT_V_LPT 1 /* line printer */
|
||||
#define INT_V_LPTSPC 2 /* line printer spc */
|
||||
|
||||
#define INT_PTR (1 << INT_V_PTR)
|
||||
#define INT_LPT (1 << INT_V_LPT)
|
||||
#define INT_LPTSPC (1 << INT_V_LPTSPC)
|
||||
#define INT_PTR (1 << INT_V_PTR)
|
||||
#define INT_LPT (1 << INT_V_LPT)
|
||||
#define INT_LPTSPC (1 << INT_V_LPTSPC)
|
||||
|
||||
#define API_PTR 2
|
||||
#define API_LPT 2
|
||||
#define API_LPTSPC 2
|
||||
#define API_PTR 2
|
||||
#define API_LPT 2
|
||||
#define API_LPTSPC 2
|
||||
|
||||
#define ACH_PTR 050
|
||||
#define ACH_LPT 056
|
||||
#define ACH_PTR 050
|
||||
#define ACH_LPT 056
|
||||
|
||||
/* API level 3 */
|
||||
|
||||
#define INT_V_CLK 0 /* clock */
|
||||
#define INT_V_TTI1 1 /* LT15 keyboard */
|
||||
#define INT_V_TTO1 2 /* LT15 output */
|
||||
#define INT_V_CLK 0 /* clock */
|
||||
#define INT_V_TTI1 1 /* LT15 keyboard */
|
||||
#define INT_V_TTO1 2 /* LT15 output */
|
||||
|
||||
#define INT_CLK (1 << INT_V_CLK)
|
||||
#define INT_TTI1 (1 << INT_V_TTI1)
|
||||
#define INT_TTO1 (1 << INT_V_TTO1)
|
||||
#define INT_CLK (1 << INT_V_CLK)
|
||||
#define INT_TTI1 (1 << INT_V_TTI1)
|
||||
#define INT_TTO1 (1 << INT_V_TTO1)
|
||||
|
||||
#define API_CLK 3
|
||||
#define API_TTI1 3
|
||||
#define API_TTO1 3
|
||||
#define API_CLK 3
|
||||
#define API_TTI1 3
|
||||
#define API_TTO1 3
|
||||
|
||||
#define ACH_CLK 051
|
||||
#define ACH_TTI1 075
|
||||
#define ACH_TTO1 074
|
||||
#define ACH_CLK 051
|
||||
#define ACH_TTI1 075
|
||||
#define ACH_TTO1 074
|
||||
|
||||
/* PI level */
|
||||
|
||||
#define INT_V_TTI 0 /* console keyboard */
|
||||
#define INT_V_TTO 1 /* console output */
|
||||
#define INT_V_PTP 2 /* paper tape punch */
|
||||
#define INT_V_TTI 0 /* console keyboard */
|
||||
#define INT_V_TTO 1 /* console output */
|
||||
#define INT_V_PTP 2 /* paper tape punch */
|
||||
|
||||
#define INT_TTI (1 << INT_V_TTI)
|
||||
#define INT_TTO (1 << INT_V_TTO)
|
||||
#define INT_PTP (1 << INT_V_PTP)
|
||||
#define INT_TTI (1 << INT_V_TTI)
|
||||
#define INT_TTO (1 << INT_V_TTO)
|
||||
#define INT_PTP (1 << INT_V_PTP)
|
||||
|
||||
#define API_TTI 4 /* PI level */
|
||||
#define API_TTO 4
|
||||
#define API_PTP 4
|
||||
#define API_TTI 4 /* PI level */
|
||||
#define API_TTO 4
|
||||
#define API_PTP 4
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
#define SET_INT(dv) int_hwre[API_##dv] = int_hwre[API_##dv] | INT_##dv
|
||||
#define CLR_INT(dv) int_hwre[API_##dv] = int_hwre[API_##dv] & ~INT_##dv
|
||||
#define TST_INT(dv) (int_hwre[API_##dv] & INT_##dv)
|
||||
|
||||
#define SET_INT(dv) int_hwre[API_##dv] = int_hwre[API_##dv] | INT_##dv
|
||||
#define CLR_INT(dv) int_hwre[API_##dv] = int_hwre[API_##dv] & ~INT_##dv
|
||||
#define TST_INT(dv) (int_hwre[API_##dv] & INT_##dv)
|
||||
|
||||
/* I/O status flags for the IORS instruction
|
||||
|
||||
bit PDP-4 PDP-7 PDP-9 PDP-15
|
||||
bit PDP-4 PDP-7 PDP-9 PDP-15
|
||||
|
||||
0 intr on intr on intr on intr on
|
||||
1 tape rdr flag* tape rdr flag* tape rdr flag* tape rdr flag*
|
||||
2 tape pun flag* tape pun flag* tape pun flag* tape pun flag*
|
||||
3 keyboard flag* keyboard flag* keyboard flag* keyboard flag*
|
||||
4 type out flag* type out flag* type out flag* type out flag*
|
||||
5 display flag* display flag* light pen flag* light pen flag*
|
||||
6 clk ovflo flag* clk ovflo flag* clk ovflo flag* clk ovflo flag*
|
||||
7 clk enable flag clk enable flag clk enable flag clk enable flag
|
||||
8 mag tape flag* mag tape flag* tape rdr empty* tape rdr empty*
|
||||
9 card rdr col* * tape pun empty tape pun empty
|
||||
10 card rdr ~busy DECtape flag* DECtape flag*
|
||||
11 card rdr error magtape flag* magtape flag*
|
||||
12 card rdr EOF disk pack flag*
|
||||
13 card pun row* DECdisk flag* DECdisk flag*
|
||||
14 card pun error lpt flag*
|
||||
15 lpt flag* lpt flag* lpt flag*
|
||||
16 lpt space flag* lpt error flag lpt error flag
|
||||
17 drum flag* drum flag*
|
||||
0 intr on intr on intr on intr on
|
||||
1 tape rdr flag* tape rdr flag* tape rdr flag* tape rdr flag*
|
||||
2 tape pun flag* tape pun flag* tape pun flag* tape pun flag*
|
||||
3 keyboard flag* keyboard flag* keyboard flag* keyboard flag*
|
||||
4 type out flag* type out flag* type out flag* type out flag*
|
||||
5 display flag* display flag* light pen flag* light pen flag*
|
||||
6 clk ovflo flag* clk ovflo flag* clk ovflo flag* clk ovflo flag*
|
||||
7 clk enable flag clk enable flag clk enable flag clk enable flag
|
||||
8 mag tape flag* mag tape flag* tape rdr empty* tape rdr empty*
|
||||
9 card rdr col* * tape pun empty tape pun empty
|
||||
10 card rdr ~busy DECtape flag* DECtape flag*
|
||||
11 card rdr error magtape flag* magtape flag*
|
||||
12 card rdr EOF disk pack flag*
|
||||
13 card pun row* DECdisk flag* DECdisk flag*
|
||||
14 card pun error lpt flag*
|
||||
15 lpt flag* lpt flag* lpt flag*
|
||||
16 lpt space flag* lpt error flag lpt error flag
|
||||
17 drum flag* drum flag*
|
||||
*/
|
||||
|
||||
#define IOS_ION 0400000 /* interrupts on */
|
||||
#define IOS_PTR 0200000 /* tape reader */
|
||||
#define IOS_PTP 0100000 /* tape punch */
|
||||
#define IOS_TTI 0040000 /* keyboard */
|
||||
#define IOS_TTO 0020000 /* terminal */
|
||||
#define IOS_LPEN 0010000 /* light pen */
|
||||
#define IOS_CLK 0004000 /* clock */
|
||||
#define IOS_CLKON 0002000 /* clock enable */
|
||||
#define IOS_DTA 0000200 /* DECtape */
|
||||
#define IOS_RP 0000040 /* disk pack */
|
||||
#define IOS_RF 0000020 /* fixed head disk */
|
||||
#define IOS_DRM 0000001 /* drum */
|
||||
#define IOS_ION 0400000 /* interrupts on */
|
||||
#define IOS_PTR 0200000 /* tape reader */
|
||||
#define IOS_PTP 0100000 /* tape punch */
|
||||
#define IOS_TTI 0040000 /* keyboard */
|
||||
#define IOS_TTO 0020000 /* terminal */
|
||||
#define IOS_LPEN 0010000 /* light pen */
|
||||
#define IOS_CLK 0004000 /* clock */
|
||||
#define IOS_CLKON 0002000 /* clock enable */
|
||||
#define IOS_DTA 0000200 /* DECtape */
|
||||
#define IOS_RP 0000040 /* disk pack */
|
||||
#define IOS_RF 0000020 /* fixed head disk */
|
||||
#define IOS_DRM 0000001 /* drum */
|
||||
#if defined (PDP4) || defined (PDP7)
|
||||
#define IOS_MTA 0001000 /* magtape */
|
||||
#define IOS_LPT 0000004 /* line printer */
|
||||
#define IOS_LPT1 0000002 /* line printer stat */
|
||||
#define IOS_MTA 0001000 /* magtape */
|
||||
#define IOS_LPT 0000004 /* line printer */
|
||||
#define IOS_LPT1 0000002 /* line printer stat */
|
||||
#elif defined (PDP9)
|
||||
#define IOS_PTRERR 0001000 /* reader empty */
|
||||
#define IOS_PTPERR 0000400 /* punch empty */
|
||||
#define IOS_MTA 0000100 /* magtape */
|
||||
#define IOS_LPT 0000004 /* line printer */
|
||||
#define IOS_LPT1 0000002 /* line printer stat */
|
||||
#define IOS_PTRERR 0001000 /* reader empty */
|
||||
#define IOS_PTPERR 0000400 /* punch empty */
|
||||
#define IOS_MTA 0000100 /* magtape */
|
||||
#define IOS_LPT 0000004 /* line printer */
|
||||
#define IOS_LPT1 0000002 /* line printer stat */
|
||||
#elif defined (PDP15)
|
||||
#define IOS_PTRERR 0001000 /* reader empty */
|
||||
#define IOS_PTPERR 0000400 /* punch empty */
|
||||
#define IOS_MTA 0000100 /* magtape */
|
||||
#define IOS_LPT 0000010 /* line printer */
|
||||
#define IOS_LPT1 0000000 /* not used */
|
||||
#define IOS_PTRERR 0001000 /* reader empty */
|
||||
#define IOS_PTPERR 0000400 /* punch empty */
|
||||
#define IOS_MTA 0000100 /* magtape */
|
||||
#define IOS_LPT 0000010 /* line printer */
|
||||
#define IOS_LPT1 0000000 /* not used */
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
@@ -491,4 +489,3 @@ t_stat set_devno (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat show_devno (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -55,4 +55,4 @@ MAINDEC-15-D1CD-PB Extended memory test
|
||||
Read in: 200 (ignored, binary tape)
|
||||
Start: 200
|
||||
Halts after printout, set SR = 30000
|
||||
Breakpoint: 563 for one pass
|
||||
Breakpoint: 563 for one pass
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: 18b PDP Simulator Usage
|
||||
Date: 15-Nov-2004
|
||||
Date: 01-Jul-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2004, written by Robert M Supnik
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -27,8 +27,8 @@ The following copyright notice applies to both the SIMH source and binary:
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
This memorandum documents the PDP-4, PDP-7, PDP-9, and PDP-15 simulators.
|
||||
@@ -569,8 +569,7 @@ or a DETACH TTIX command.
|
||||
|
||||
The SHOW TTIX CONNECTIONS command displays the current connections to the
|
||||
extra terminals. The SHOW TTIX STATISTICS command displays statistics for
|
||||
active connections. The SET TTIX DISCONNECT=linenumber disconnects the
|
||||
specified line.
|
||||
active connections. The SET TTIXn DISCONNECT command disconnects line n.
|
||||
|
||||
The input device (TTIX) implements these registers:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp18b_drm.c: drum/fixed head disk simulator
|
||||
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,23 +19,23 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
drm (PDP-4,PDP-7) Type 24 serial drum
|
||||
drm (PDP-4,PDP-7) Type 24 serial drum
|
||||
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
05-Dec-02 RMS Updated from Type 24 documentation
|
||||
22-Nov-02 RMS Added PDP-4 support
|
||||
05-Feb-02 RMS Added DIB, device number support
|
||||
03-Feb-02 RMS Fixed bug in reset routine (found by Robert Alan Byer)
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
05-Dec-02 RMS Updated from Type 24 documentation
|
||||
22-Nov-02 RMS Added PDP-4 support
|
||||
05-Feb-02 RMS Added DIB, device number support
|
||||
03-Feb-02 RMS Fixed bug in reset routine (found by Robert Alan Byer)
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
*/
|
||||
|
||||
#include "pdp18b_defs.h"
|
||||
@@ -43,33 +43,33 @@
|
||||
|
||||
/* Constants */
|
||||
|
||||
#define DRM_NUMWDS 256 /* words/sector */
|
||||
#define DRM_NUMSC 2 /* sectors/track */
|
||||
#define DRM_NUMTR 256 /* tracks/drum */
|
||||
#define DRM_NUMDK 1 /* drum/controller */
|
||||
#define DRM_NUMWDT (DRM_NUMWDS * DRM_NUMSC) /* words/track */
|
||||
#define DRM_SIZE (DRM_NUMDK * DRM_NUMTR * DRM_NUMWDT) /* words/drum */
|
||||
#define DRM_SMASK ((DRM_NUMTR * DRM_NUMSC) - 1) /* sector mask */
|
||||
#define DRM_NUMWDS 256 /* words/sector */
|
||||
#define DRM_NUMSC 2 /* sectors/track */
|
||||
#define DRM_NUMTR 256 /* tracks/drum */
|
||||
#define DRM_NUMDK 1 /* drum/controller */
|
||||
#define DRM_NUMWDT (DRM_NUMWDS * DRM_NUMSC) /* words/track */
|
||||
#define DRM_SIZE (DRM_NUMDK * DRM_NUMTR * DRM_NUMWDT) /* words/drum */
|
||||
#define DRM_SMASK ((DRM_NUMTR * DRM_NUMSC) - 1) /* sector mask */
|
||||
|
||||
/* Parameters in the unit descriptor */
|
||||
|
||||
#define FUNC u4 /* function */
|
||||
#define DRM_READ 000 /* read */
|
||||
#define DRM_WRITE 040 /* write */
|
||||
#define FUNC u4 /* function */
|
||||
#define DRM_READ 000 /* read */
|
||||
#define DRM_WRITE 040 /* write */
|
||||
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime() / ((double) (x)), \
|
||||
((double) DRM_NUMWDT)))
|
||||
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime() / ((double) (x)), \
|
||||
((double) DRM_NUMWDT)))
|
||||
|
||||
extern int32 M[];
|
||||
extern int32 int_hwre[API_HLVL+1];
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
int32 drm_da = 0; /* track address */
|
||||
int32 drm_ma = 0; /* memory address */
|
||||
int32 drm_err = 0; /* error flag */
|
||||
int32 drm_wlk = 0; /* write lock */
|
||||
int32 drm_time = 10; /* inter-word time */
|
||||
int32 drm_stopioe = 1; /* stop on error */
|
||||
int32 drm_da = 0; /* track address */
|
||||
int32 drm_ma = 0; /* memory address */
|
||||
int32 drm_err = 0; /* error flag */
|
||||
int32 drm_wlk = 0; /* write lock */
|
||||
int32 drm_time = 10; /* inter-word time */
|
||||
int32 drm_stopioe = 1; /* stop on error */
|
||||
|
||||
DEVICE drm_dev;
|
||||
int32 drm60 (int32 dev, int32 pulse, int32 AC);
|
||||
@@ -82,47 +82,52 @@ t_stat drm_boot (int32 unitno, DEVICE *dptr);
|
||||
|
||||
/* DRM data structures
|
||||
|
||||
drm_dev DRM device descriptor
|
||||
drm_unit DRM unit descriptor
|
||||
drm_reg DRM register list
|
||||
drm_dev DRM device descriptor
|
||||
drm_unit DRM unit descriptor
|
||||
drm_reg DRM register list
|
||||
*/
|
||||
|
||||
DIB drm_dib = { DEV_DRM, 3 ,&drm_iors, { &drm60, &drm61, &drm62 } };
|
||||
|
||||
UNIT drm_unit =
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
|
||||
DRM_SIZE) };
|
||||
UNIT drm_unit = {
|
||||
UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
|
||||
DRM_SIZE)
|
||||
};
|
||||
|
||||
REG drm_reg[] = {
|
||||
{ ORDATA (DA, drm_da, 9) },
|
||||
{ ORDATA (MA, drm_ma, 16) },
|
||||
{ FLDATA (INT, int_hwre[API_DRM], INT_V_DRM) },
|
||||
{ FLDATA (DONE, int_hwre[API_DRM], INT_V_DRM) },
|
||||
{ FLDATA (ERR, drm_err, 0) },
|
||||
{ ORDATA (WLK, drm_wlk, 32) },
|
||||
{ DRDATA (TIME, drm_time, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, drm_stopioe, 0) },
|
||||
{ ORDATA (DEVNO, drm_dib.dev, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
{ ORDATA (DA, drm_da, 9) },
|
||||
{ ORDATA (MA, drm_ma, 16) },
|
||||
{ FLDATA (INT, int_hwre[API_DRM], INT_V_DRM) },
|
||||
{ FLDATA (DONE, int_hwre[API_DRM], INT_V_DRM) },
|
||||
{ FLDATA (ERR, drm_err, 0) },
|
||||
{ ORDATA (WLK, drm_wlk, 32) },
|
||||
{ DRDATA (TIME, drm_time, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, drm_stopioe, 0) },
|
||||
{ ORDATA (DEVNO, drm_dib.dev, 6), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB drm_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 } };
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE drm_dev = {
|
||||
"DRM", &drm_unit, drm_reg, drm_mod,
|
||||
1, 8, 20, 1, 8, 18,
|
||||
NULL, NULL, &drm_reset,
|
||||
&drm_boot, NULL, NULL,
|
||||
&drm_dib, DEV_DISABLE };
|
||||
|
||||
"DRM", &drm_unit, drm_reg, drm_mod,
|
||||
1, 8, 20, 1, 8, 18,
|
||||
NULL, NULL, &drm_reset,
|
||||
&drm_boot, NULL, NULL,
|
||||
&drm_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* IOT routines */
|
||||
|
||||
int32 drm60 (int32 dev, int32 pulse, int32 AC)
|
||||
{
|
||||
if ((pulse & 027) == 06) { /* DRLR, DRLW */
|
||||
drm_ma = AC & 0177777; /* load mem addr */
|
||||
drm_unit.FUNC = pulse & DRM_WRITE; } /* save function */
|
||||
if ((pulse & 027) == 06) { /* DRLR, DRLW */
|
||||
drm_ma = AC & 0177777; /* load mem addr */
|
||||
drm_unit.FUNC = pulse & DRM_WRITE; /* save function */
|
||||
}
|
||||
return AC;
|
||||
}
|
||||
|
||||
@@ -130,16 +135,19 @@ int32 drm61 (int32 dev, int32 pulse, int32 AC)
|
||||
{
|
||||
int32 t;
|
||||
|
||||
if (pulse & 001) { /* DRSF */
|
||||
if (TST_INT (DRM)) AC = AC | IOT_SKP; }
|
||||
if (pulse & 002) { /* DRCF */
|
||||
CLR_INT (DRM); /* clear done */
|
||||
drm_err = 0; } /* clear error */
|
||||
if (pulse & 004) { /* DRSS */
|
||||
drm_da = AC & DRM_SMASK; /* load sector # */
|
||||
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
||||
if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */
|
||||
sim_activate (&drm_unit, t * drm_time); } /* schedule op */
|
||||
if (pulse & 001) { /* DRSF */
|
||||
if (TST_INT (DRM)) AC = AC | IOT_SKP;
|
||||
}
|
||||
if (pulse & 002) { /* DRCF */
|
||||
CLR_INT (DRM); /* clear done */
|
||||
drm_err = 0; /* clear error */
|
||||
}
|
||||
if (pulse & 004) { /* DRSS */
|
||||
drm_da = AC & DRM_SMASK; /* load sector # */
|
||||
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
||||
if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */
|
||||
sim_activate (&drm_unit, t * drm_time); /* schedule op */
|
||||
}
|
||||
return AC;
|
||||
}
|
||||
|
||||
@@ -147,17 +155,19 @@ int32 drm62 (int32 dev, int32 pulse, int32 AC)
|
||||
{
|
||||
int32 t;
|
||||
|
||||
if (pulse & 001) { /* DRSN */
|
||||
if (drm_err == 0) AC = AC | IOT_SKP; }
|
||||
if (pulse & 004) { /* DRCS */
|
||||
CLR_INT (DRM); /* clear done */
|
||||
drm_err = 0; /* clear error */
|
||||
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
||||
if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */
|
||||
sim_activate (&drm_unit, t * drm_time); } /* schedule op */
|
||||
if (pulse & 001) { /* DRSN */
|
||||
if (drm_err == 0) AC = AC | IOT_SKP;
|
||||
}
|
||||
if (pulse & 004) { /* DRCS */
|
||||
CLR_INT (DRM); /* clear done */
|
||||
drm_err = 0; /* clear error */
|
||||
t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
|
||||
if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */
|
||||
sim_activate (&drm_unit, t * drm_time); /* schedule op */
|
||||
}
|
||||
return AC;
|
||||
}
|
||||
|
||||
|
||||
/* Unit service
|
||||
|
||||
This code assumes the entire drum is buffered.
|
||||
@@ -169,33 +179,38 @@ int32 i;
|
||||
uint32 da;
|
||||
int32 *fbuf = uptr->filebuf;
|
||||
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
drm_err = 1; /* set error */
|
||||
SET_INT (DRM); /* set done */
|
||||
return IORETURN (drm_stopioe, SCPE_UNATT); }
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
drm_err = 1; /* set error */
|
||||
SET_INT (DRM); /* set done */
|
||||
return IORETURN (drm_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
da = drm_da * DRM_NUMWDS; /* compute dev addr */
|
||||
for (i = 0; i < DRM_NUMWDS; i++, da++) { /* do transfer */
|
||||
if (uptr->FUNC == DRM_READ) { /* read? */
|
||||
if (MEM_ADDR_OK (drm_ma)) /* if !nxm */
|
||||
M[drm_ma] = fbuf[da]; } /* read word */
|
||||
else { /* write */
|
||||
if ((drm_wlk >> (drm_da >> 4)) & 1) drm_err = 1;
|
||||
else { /* not locked */
|
||||
fbuf[da] = M[drm_ma]; /* write word */
|
||||
if (da >= uptr->hwmark) uptr->hwmark = da + 1; } }
|
||||
drm_ma = (drm_ma + 1) & 0177777; } /* incr mem addr */
|
||||
drm_da = (drm_da + 1) & DRM_SMASK; /* incr dev addr */
|
||||
SET_INT (DRM); /* set done */
|
||||
da = drm_da * DRM_NUMWDS; /* compute dev addr */
|
||||
for (i = 0; i < DRM_NUMWDS; i++, da++) { /* do transfer */
|
||||
if (uptr->FUNC == DRM_READ) { /* read? */
|
||||
if (MEM_ADDR_OK (drm_ma)) /* if !nxm */
|
||||
M[drm_ma] = fbuf[da]; /* read word */
|
||||
}
|
||||
else { /* write */
|
||||
if ((drm_wlk >> (drm_da >> 4)) & 1) drm_err = 1;
|
||||
else { /* not locked */
|
||||
fbuf[da] = M[drm_ma]; /* write word */
|
||||
if (da >= uptr->hwmark) uptr->hwmark = da + 1;
|
||||
}
|
||||
}
|
||||
drm_ma = (drm_ma + 1) & 0177777; /* incr mem addr */
|
||||
}
|
||||
drm_da = (drm_da + 1) & DRM_SMASK; /* incr dev addr */
|
||||
SET_INT (DRM); /* set done */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat drm_reset (DEVICE *dptr)
|
||||
{
|
||||
drm_da = drm_ma = drm_err = 0;
|
||||
CLR_INT (DRM); /* clear done */
|
||||
CLR_INT (DRM); /* clear done */
|
||||
sim_cancel (&drm_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -213,20 +228,20 @@ return (TST_INT (DRM)? IOS_DRM: 0);
|
||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
|
||||
|
||||
static const int32 boot_rom[] = {
|
||||
0750000, /* CLA ; dev, mem addr */
|
||||
0706006, /* DRLR ; load ma */
|
||||
0706106, /* DRSS ; load da, start */
|
||||
0706101, /* DRSF ; wait for done */
|
||||
0602003, /* JMP .-1 */
|
||||
0600000 /* JMP 0 ; enter boot */
|
||||
};
|
||||
0750000, /* CLA ; dev, mem addr */
|
||||
0706006, /* DRLR ; load ma */
|
||||
0706106, /* DRSS ; load da, start */
|
||||
0706101, /* DRSF ; wait for done */
|
||||
0602003, /* JMP .-1 */
|
||||
0600000 /* JMP 0 ; enter boot */
|
||||
};
|
||||
|
||||
t_stat drm_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
int32 i;
|
||||
extern int32 PC;
|
||||
|
||||
if (drm_dib.dev != DEV_DRM) return STOP_NONSTD; /* non-std addr? */
|
||||
if (drm_dib.dev != DEV_DRM) return STOP_NONSTD; /* non-std addr? */
|
||||
for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
|
||||
PC = BOOT_START;
|
||||
return SCPE_OK;
|
||||
|
||||
1937
PDP18B/pdp18b_dt.c
1937
PDP18B/pdp18b_dt.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -19,47 +19,48 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
mt (PDP-9) TC59 magtape
|
||||
(PDP-15) TC59D magtape
|
||||
mt (PDP-9) TC59 magtape
|
||||
(PDP-15) TC59D magtape
|
||||
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
04-Mar-03 RMS Fixed bug in MTTR
|
||||
01-Mar-03 RMS Fixed bug in interrupt handling
|
||||
Revised for magtape library
|
||||
02-Feb-03 RMS Revised IOT decoding
|
||||
30-Oct-02 RMS Revised BOT handling, added error record handling
|
||||
05-Oct-02 RMS Added DIB, device number support
|
||||
Revamped error recovery
|
||||
28-Aug-02 RMS Added end of medium support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
22-Apr-02 RMS Added maximum record length test
|
||||
06-Jan-02 RMS Revised enabled/disable support
|
||||
29-Nov-01 RMS Added read only unit support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
Changed UST, POS, FLG to arrays
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
15-Feb-01 RMS Fixed 3-cycle data break sequence
|
||||
04-Oct-98 RMS V2.4 magtape format
|
||||
22-Jan-97 RMS V2.3 magtape format
|
||||
29-Jun-96 RMS Added unit enable/disable support
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
04-Mar-03 RMS Fixed bug in MTTR
|
||||
01-Mar-03 RMS Fixed bug in interrupt handling
|
||||
Revised for magtape library
|
||||
02-Feb-03 RMS Revised IOT decoding
|
||||
30-Oct-02 RMS Revised BOT handling, added error record handling
|
||||
05-Oct-02 RMS Added DIB, device number support
|
||||
Revamped error recovery
|
||||
28-Aug-02 RMS Added end of medium support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
22-Apr-02 RMS Added maximum record length test
|
||||
06-Jan-02 RMS Revised enabled/disable support
|
||||
29-Nov-01 RMS Added read only unit support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
Changed UST, POS, FLG to arrays
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
15-Feb-01 RMS Fixed 3-cycle data break sequence
|
||||
04-Oct-98 RMS V2.4 magtape format
|
||||
22-Jan-97 RMS V2.3 magtape format
|
||||
29-Jun-96 RMS Added unit enable/disable support
|
||||
|
||||
Magnetic tapes are represented as a series of variable records
|
||||
of the form:
|
||||
|
||||
32b byte count
|
||||
byte 0
|
||||
byte 1
|
||||
:
|
||||
byte n-2
|
||||
byte n-1
|
||||
32 byte count
|
||||
32b byte count
|
||||
byte 0
|
||||
byte 1
|
||||
:
|
||||
byte n-2
|
||||
byte n-1
|
||||
32 byte count
|
||||
|
||||
If the byte count is odd, the record is padded with an extra byte
|
||||
of junk. File marks are represented by a byte count of 0.
|
||||
@@ -68,69 +69,69 @@
|
||||
#include "pdp18b_defs.h"
|
||||
#include "sim_tape.h"
|
||||
|
||||
#define MT_NUMDR 8 /* #drives */
|
||||
#define USTAT u3 /* unit status */
|
||||
#define MT_MAXFR (1 << 16) /* max record length */
|
||||
#define MT_WC 032 /* word count */
|
||||
#define MT_CA 033 /* current addr */
|
||||
#define WC_SIZE (1 << 12) /* max word count */
|
||||
#define WC_MASK (WC_SIZE - 1)
|
||||
#define MT_NUMDR 8 /* #drives */
|
||||
#define USTAT u3 /* unit status */
|
||||
#define MT_MAXFR (1 << 16) /* max record length */
|
||||
#define MT_WC 032 /* word count */
|
||||
#define MT_CA 033 /* current addr */
|
||||
#define WC_SIZE (1 << 12) /* max word count */
|
||||
#define WC_MASK (WC_SIZE - 1)
|
||||
|
||||
/* Command/unit - mt_cu */
|
||||
|
||||
#define CU_V_UNIT 15 /* unit */
|
||||
#define CU_M_UNIT 07
|
||||
#define CU_PARITY 0040000 /* parity select */
|
||||
#define CU_DUMP 0020000 /* dump mode */
|
||||
#define CU_ERASE 0010000 /* ext rec gap */
|
||||
#define CU_V_CMD 9 /* command */
|
||||
#define CU_M_CMD 07
|
||||
#define FN_NOP 00
|
||||
#define FN_REWIND 01
|
||||
#define FN_READ 02
|
||||
#define FN_CMPARE 03
|
||||
#define FN_WRITE 04
|
||||
#define FN_WREOF 05
|
||||
#define FN_SPACEF 06
|
||||
#define FN_SPACER 07
|
||||
#define CU_IE 0000400 /* interrupt enable */
|
||||
#define CU_V_TYPE 6 /* drive type */
|
||||
#define CU_M_TYPE 03
|
||||
#define TY_9TK 3
|
||||
#define GET_UNIT(x) (((x) >> CU_V_UNIT) & CU_M_UNIT)
|
||||
#define GET_CMD(x) (((x) >> CU_V_CMD) & CU_M_CMD)
|
||||
#define GET_TYPE(x) (((x) >> CU_V_TYPE) & CU_M_TYPE)
|
||||
#define PACKED(x) (((x) & CU_DUMP) || (GET_TYPE (x) != TY_9TK))
|
||||
#define CU_V_UNIT 15 /* unit */
|
||||
#define CU_M_UNIT 07
|
||||
#define CU_PARITY 0040000 /* parity select */
|
||||
#define CU_DUMP 0020000 /* dump mode */
|
||||
#define CU_ERASE 0010000 /* ext rec gap */
|
||||
#define CU_V_CMD 9 /* command */
|
||||
#define CU_M_CMD 07
|
||||
#define FN_NOP 00
|
||||
#define FN_REWIND 01
|
||||
#define FN_READ 02
|
||||
#define FN_CMPARE 03
|
||||
#define FN_WRITE 04
|
||||
#define FN_WREOF 05
|
||||
#define FN_SPACEF 06
|
||||
#define FN_SPACER 07
|
||||
#define CU_IE 0000400 /* interrupt enable */
|
||||
#define CU_V_TYPE 6 /* drive type */
|
||||
#define CU_M_TYPE 03
|
||||
#define TY_9TK 3
|
||||
#define GET_UNIT(x) (((x) >> CU_V_UNIT) & CU_M_UNIT)
|
||||
#define GET_CMD(x) (((x) >> CU_V_CMD) & CU_M_CMD)
|
||||
#define GET_TYPE(x) (((x) >> CU_V_TYPE) & CU_M_TYPE)
|
||||
#define PACKED(x) (((x) & CU_DUMP) || (GET_TYPE (x) != TY_9TK))
|
||||
|
||||
/* Status - stored in mt_sta or (*) uptr->USTAT */
|
||||
|
||||
#define STA_ERR 0400000 /* error */
|
||||
#define STA_REW 0200000 /* *rewinding */
|
||||
#define STA_BOT 0100000 /* *start of tape */
|
||||
#define STA_ILL 0040000 /* illegal cmd */
|
||||
#define STA_PAR 0020000 /* parity error */
|
||||
#define STA_EOF 0010000 /* *end of file */
|
||||
#define STA_EOT 0004000 /* *end of tape */
|
||||
#define STA_CPE 0002000 /* compare error */
|
||||
#define STA_RLE 0001000 /* rec lnt error */
|
||||
#define STA_DLT 0000400 /* data late */
|
||||
#define STA_BAD 0000200 /* bad tape */
|
||||
#define STA_DON 0000100 /* done */
|
||||
#define STA_ERR 0400000 /* error */
|
||||
#define STA_REW 0200000 /* *rewinding */
|
||||
#define STA_BOT 0100000 /* *start of tape */
|
||||
#define STA_ILL 0040000 /* illegal cmd */
|
||||
#define STA_PAR 0020000 /* parity error */
|
||||
#define STA_EOF 0010000 /* *end of file */
|
||||
#define STA_EOT 0004000 /* *end of tape */
|
||||
#define STA_CPE 0002000 /* compare error */
|
||||
#define STA_RLE 0001000 /* rec lnt error */
|
||||
#define STA_DLT 0000400 /* data late */
|
||||
#define STA_BAD 0000200 /* bad tape */
|
||||
#define STA_DON 0000100 /* done */
|
||||
|
||||
#define STA_CLR 0000077 /* always clear */
|
||||
#define STA_DYN (STA_REW | STA_BOT | STA_EOF | STA_EOT)
|
||||
/* kept in USTAT */
|
||||
|
||||
#define STA_CLR 0000077 /* always clear */
|
||||
#define STA_DYN (STA_REW | STA_BOT | STA_EOF | STA_EOT)
|
||||
/* kept in USTAT */
|
||||
|
||||
extern int32 M[];
|
||||
extern int32 int_hwre[API_HLVL+1];
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
int32 mt_cu = 0; /* command/unit */
|
||||
int32 mt_sta = 0; /* status register */
|
||||
int32 mt_time = 10; /* record latency */
|
||||
int32 mt_stopioe = 1; /* stop on error */
|
||||
int32 mt_cu = 0; /* command/unit */
|
||||
int32 mt_sta = 0; /* status register */
|
||||
int32 mt_time = 10; /* record latency */
|
||||
int32 mt_stopioe = 1; /* stop on error */
|
||||
int32 mt_log = 0;
|
||||
uint8 *mtxb = NULL; /* transfer buffer */
|
||||
uint8 *mtxb = NULL; /* transfer buffer */
|
||||
|
||||
DEVICE mt_dev;
|
||||
int32 mt (int32 dev, int32 pulse, int32 dat);
|
||||
@@ -145,55 +146,59 @@ UNIT *mt_busy (void);
|
||||
|
||||
/* MT data structures
|
||||
|
||||
mt_dev MT device descriptor
|
||||
mt_unit MT unit list
|
||||
mt_reg MT register list
|
||||
mt_mod MT modifier list
|
||||
mt_dev MT device descriptor
|
||||
mt_unit MT unit list
|
||||
mt_reg MT register list
|
||||
mt_mod MT modifier list
|
||||
*/
|
||||
|
||||
DIB mt_dib = { DEV_MT, 1, &mt_iors, { &mt } };
|
||||
|
||||
UNIT mt_unit[] = {
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) } };
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }
|
||||
};
|
||||
|
||||
REG mt_reg[] = {
|
||||
{ ORDATA (STA, mt_sta, 18) },
|
||||
{ ORDATA (CMD, mt_cu, 18) },
|
||||
{ ORDATA (WC, M[MT_WC], 18) },
|
||||
{ ORDATA (CA, M[MT_CA], 18) },
|
||||
{ FLDATA (INT, int_hwre[API_MTA], INT_V_MTA) },
|
||||
{ FLDATA (STOP_IOE, mt_stopioe, 0) },
|
||||
{ DRDATA (TIME, mt_time, 24), PV_LEFT },
|
||||
{ URDATA (UST, mt_unit[0].USTAT, 8, 16, 0, MT_NUMDR, 0) },
|
||||
{ URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR, PV_LEFT | REG_RO) },
|
||||
{ FLDATA (LOG, mt_log, 0), REG_HIDDEN },
|
||||
{ ORDATA (DEVNO, mt_dib.dev, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
{ ORDATA (STA, mt_sta, 18) },
|
||||
{ ORDATA (CMD, mt_cu, 18) },
|
||||
{ ORDATA (WC, M[MT_WC], 18) },
|
||||
{ ORDATA (CA, M[MT_CA], 18) },
|
||||
{ FLDATA (INT, int_hwre[API_MTA], INT_V_MTA) },
|
||||
{ FLDATA (STOP_IOE, mt_stopioe, 0) },
|
||||
{ DRDATA (TIME, mt_time, 24), PV_LEFT },
|
||||
{ URDATA (UST, mt_unit[0].USTAT, 8, 16, 0, MT_NUMDR, 0) },
|
||||
{ URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR, PV_LEFT | REG_RO) },
|
||||
{ FLDATA (LOG, mt_log, 0), REG_HIDDEN },
|
||||
{ ORDATA (DEVNO, mt_dib.dev, 6), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB mt_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_devno, &show_devno, NULL },
|
||||
{ 0 } };
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_devno, &show_devno, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE mt_dev = {
|
||||
"MT", mt_unit, mt_reg, mt_mod,
|
||||
MT_NUMDR, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &mt_detach,
|
||||
&mt_dib, DEV_DISABLE };
|
||||
|
||||
"MT", mt_unit, mt_reg, mt_mod,
|
||||
MT_NUMDR, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &mt_detach,
|
||||
&mt_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* IOT routine */
|
||||
|
||||
int32 mt (int32 dev, int32 pulse, int32 dat)
|
||||
@@ -201,49 +206,52 @@ int32 mt (int32 dev, int32 pulse, int32 dat)
|
||||
int32 f, sb;
|
||||
UNIT *uptr;
|
||||
|
||||
uptr = mt_dev.units + GET_UNIT (mt_cu); /* get unit */
|
||||
mt_updcsta (uptr, 0); /* update status */
|
||||
sb = pulse & 060; /* subop */
|
||||
uptr = mt_dev.units + GET_UNIT (mt_cu); /* get unit */
|
||||
mt_updcsta (uptr, 0); /* update status */
|
||||
sb = pulse & 060; /* subop */
|
||||
if (pulse & 01) {
|
||||
if ((sb == 000) && (uptr->flags & UNIT_ATT) && /* MTTR */
|
||||
!sim_is_active (uptr))
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 020) && !mt_busy ()) /* MTCR */
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 040) && (mt_sta & (STA_ERR | STA_DON))) /* MTSF */
|
||||
dat = IOT_SKP | dat;
|
||||
}
|
||||
if ((sb == 000) && (uptr->flags & UNIT_ATT) && /* MTTR */
|
||||
!sim_is_active (uptr))
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 020) && !mt_busy ()) /* MTCR */
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 040) && (mt_sta & (STA_ERR | STA_DON))) /* MTSF */
|
||||
dat = IOT_SKP | dat;
|
||||
}
|
||||
if ((pulse & 06) && mt_log)
|
||||
printf ("[MT%d: IOT=%o, AC=%o, sta=%o]\n",
|
||||
GET_UNIT (mt_cu), 0707300 + pulse, dat, mt_sta);
|
||||
printf ("[MT%d: IOT=%o, AC=%o, sta=%o]\n",
|
||||
GET_UNIT (mt_cu), 0707300 + pulse, dat, mt_sta);
|
||||
if (pulse & 02) {
|
||||
if (sb == 000) dat = dat | (mt_cu & 0777700); /* MTRC */
|
||||
else if (sb == 020) { /* MTAF, MTLC */
|
||||
if (!mt_busy ()) mt_cu = mt_sta = 0; /* if not busy, clr */
|
||||
mt_sta = mt_sta & ~(STA_ERR | STA_DON); } /* clear flags */
|
||||
else if (sb == 040) dat = dat | mt_sta; /* MTRS */
|
||||
}
|
||||
if (sb == 000) dat = dat | (mt_cu & 0777700); /* MTRC */
|
||||
else if (sb == 020) { /* MTAF, MTLC */
|
||||
if (!mt_busy ()) mt_cu = mt_sta = 0; /* if not busy, clr */
|
||||
mt_sta = mt_sta & ~(STA_ERR | STA_DON); /* clear flags */
|
||||
}
|
||||
else if (sb == 040) dat = dat | mt_sta; /* MTRS */
|
||||
}
|
||||
if (pulse & 04) {
|
||||
if (sb == 000) { /* MTGO */
|
||||
f = GET_CMD (mt_cu); /* get function */
|
||||
if (mt_busy () ||
|
||||
sim_is_active (uptr) ||
|
||||
(f == FN_NOP) ||
|
||||
(((f == FN_SPACER) || (f == FN_REWIND)) && (uptr->USTAT & STA_BOT)) ||
|
||||
(((f == FN_WRITE) || (f == FN_WREOF)) && sim_tape_wrp (uptr)) ||
|
||||
((uptr->flags & UNIT_ATT) == 0))
|
||||
mt_sta = mt_sta | STA_ILL | STA_ERR; /* set illegal op */
|
||||
else {
|
||||
if (f == FN_REWIND) uptr->USTAT = STA_REW; /* rewind? */
|
||||
else mt_sta = uptr->USTAT = 0; /* no, clear status */
|
||||
sim_activate (uptr, mt_time); } } /* start io */
|
||||
if (sb == 020) /* MTCM, MTLC */
|
||||
mt_cu = (mt_cu & 0770700) | (dat & 0777700); /* load status */
|
||||
}
|
||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||
if (sb == 000) { /* MTGO */
|
||||
f = GET_CMD (mt_cu); /* get function */
|
||||
if (mt_busy () ||
|
||||
sim_is_active (uptr) ||
|
||||
(f == FN_NOP) ||
|
||||
(((f == FN_SPACER) || (f == FN_REWIND)) && (uptr->USTAT & STA_BOT)) ||
|
||||
(((f == FN_WRITE) || (f == FN_WREOF)) && sim_tape_wrp (uptr)) ||
|
||||
((uptr->flags & UNIT_ATT) == 0))
|
||||
mt_sta = mt_sta | STA_ILL | STA_ERR; /* set illegal op */
|
||||
else {
|
||||
if (f == FN_REWIND) uptr->USTAT = STA_REW; /* rewind? */
|
||||
else mt_sta = uptr->USTAT = 0; /* no, clear status */
|
||||
sim_activate (uptr, mt_time); /* start io */
|
||||
}
|
||||
}
|
||||
if (sb == 020) /* MTCM, MTLC */
|
||||
mt_cu = (mt_cu & 0770700) | (dat & 0777700); /* load status */
|
||||
}
|
||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||
return dat;
|
||||
}
|
||||
|
||||
|
||||
/* Unit service
|
||||
|
||||
If rewind done, reposition to start of tape, set status
|
||||
@@ -257,123 +265,132 @@ int32 wc, xma;
|
||||
t_mtrlnt tbc, cbc;
|
||||
t_stat st, r = SCPE_OK;
|
||||
|
||||
u = uptr - mt_dev.units; /* get unit number */
|
||||
f = GET_CMD (mt_cu); /* get command */
|
||||
wc = WC_SIZE - (M[MT_WC] & WC_MASK); /* word count is 12b */
|
||||
u = (int32) (uptr - mt_dev.units); /* get unit number */
|
||||
f = GET_CMD (mt_cu); /* get command */
|
||||
wc = WC_SIZE - (M[MT_WC] & WC_MASK); /* word count is 12b */
|
||||
|
||||
if (uptr->USTAT & STA_REW) { /* rewind? */
|
||||
sim_tape_rewind (uptr); /* rewind tape */
|
||||
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_BOT;
|
||||
else uptr->USTAT = 0;
|
||||
if (u == GET_UNIT (mt_cu)) mt_updcsta (uptr, STA_DON);
|
||||
if (mt_log) printf ("[MT%d: rewind complete, sta=%o]\n", u, mt_sta);
|
||||
return SCPE_OK; }
|
||||
if (uptr->USTAT & STA_REW) { /* rewind? */
|
||||
sim_tape_rewind (uptr); /* rewind tape */
|
||||
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_BOT;
|
||||
else uptr->USTAT = 0;
|
||||
if (u == GET_UNIT (mt_cu)) mt_updcsta (uptr, STA_DON);
|
||||
if (mt_log) printf ("[MT%d: rewind complete, sta=%o]\n", u, mt_sta);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* if not attached */
|
||||
mt_updcsta (uptr, STA_ILL); /* illegal operation */
|
||||
return IORETURN (mt_stopioe, SCPE_UNATT); }
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* if not attached */
|
||||
mt_updcsta (uptr, STA_ILL); /* illegal operation */
|
||||
return IORETURN (mt_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
switch (f) { /* case on function */
|
||||
|
||||
/* Unit service, continued */
|
||||
switch (f) { /* case on function */
|
||||
|
||||
case FN_READ: /* read */
|
||||
case FN_CMPARE: /* read/compare */
|
||||
st = sim_tape_rdrecf (uptr, mtxb, &tbc, MT_MAXFR); /* read rec */
|
||||
if (st == MTSE_RECE) mt_sta = mt_sta | STA_PAR | STA_ERR; /* rec in err? */
|
||||
else if (st != MTSE_OK) { /* other error? */
|
||||
mt_sta = mt_sta | STA_RLE | STA_ERR; /* set RLE flag */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
break; }
|
||||
cbc = PACKED (mt_cu)? wc * 3: wc * 2; /* expected bc */
|
||||
if (tbc != cbc) mt_sta = mt_sta | STA_RLE | STA_ERR; /* wrong size? */
|
||||
if (tbc < cbc) { /* record small? */
|
||||
cbc = tbc; /* use smaller */
|
||||
wc = PACKED (mt_cu)? ((tbc + 2) / 3): ((tbc + 1) / 2); }
|
||||
for (i = p = 0; i < wc; i++) { /* copy buffer */
|
||||
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC, CA */
|
||||
M[MT_CA] = (M[MT_CA] + 1) & DMASK;
|
||||
xma = M[MT_CA] & AMASK;
|
||||
if (PACKED (mt_cu)) { /* packed? */
|
||||
c1 = mtxb[p++] & 077;
|
||||
c2 = mtxb[p++] & 077;
|
||||
c3 = mtxb[p++] & 077;
|
||||
c = (c1 << 12) | (c2 << 6) | c3; }
|
||||
else {
|
||||
c1 = mtxb[p++];
|
||||
c2 = mtxb[p++];
|
||||
c = (c1 << 8) | c2; }
|
||||
if ((f == FN_READ) && MEM_ADDR_OK (xma)) M[xma] = c;
|
||||
else if ((f == FN_CMPARE) && (c != (M[xma] &
|
||||
(PACKED (mt_cu)? DMASK: 0177777)))) {
|
||||
mt_updcsta (uptr, STA_CPE);
|
||||
break; } }
|
||||
break;
|
||||
case FN_READ: /* read */
|
||||
case FN_CMPARE: /* read/compare */
|
||||
st = sim_tape_rdrecf (uptr, mtxb, &tbc, MT_MAXFR); /* read rec */
|
||||
if (st == MTSE_RECE) mt_sta = mt_sta | STA_PAR | STA_ERR; /* rec in err? */
|
||||
else if (st != MTSE_OK) { /* other error? */
|
||||
mt_sta = mt_sta | STA_RLE | STA_ERR; /* set RLE flag */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
}
|
||||
cbc = PACKED (mt_cu)? wc * 3: wc * 2; /* expected bc */
|
||||
if (tbc != cbc) mt_sta = mt_sta | STA_RLE | STA_ERR; /* wrong size? */
|
||||
if (tbc < cbc) { /* record small? */
|
||||
cbc = tbc; /* use smaller */
|
||||
wc = PACKED (mt_cu)? ((tbc + 2) / 3): ((tbc + 1) / 2);
|
||||
}
|
||||
for (i = p = 0; i < wc; i++) { /* copy buffer */
|
||||
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC, CA */
|
||||
M[MT_CA] = (M[MT_CA] + 1) & DMASK;
|
||||
xma = M[MT_CA] & AMASK;
|
||||
if (PACKED (mt_cu)) { /* packed? */
|
||||
c1 = mtxb[p++] & 077;
|
||||
c2 = mtxb[p++] & 077;
|
||||
c3 = mtxb[p++] & 077;
|
||||
c = (c1 << 12) | (c2 << 6) | c3;
|
||||
}
|
||||
else {
|
||||
c1 = mtxb[p++];
|
||||
c2 = mtxb[p++];
|
||||
c = (c1 << 8) | c2;
|
||||
}
|
||||
if ((f == FN_READ) && MEM_ADDR_OK (xma)) M[xma] = c;
|
||||
else if ((f == FN_CMPARE) && (c != (M[xma] &
|
||||
(PACKED (mt_cu)? DMASK: 0177777)))) {
|
||||
mt_updcsta (uptr, STA_CPE);
|
||||
break;
|
||||
}
|
||||
} /* end for */
|
||||
break;
|
||||
|
||||
case FN_WRITE: /* write */
|
||||
tbc = PACKED (mt_cu)? wc * 3: wc * 2;
|
||||
xma = M[MT_CA] & AMASK; /* get mem addr */
|
||||
for (i = p = 0; i < wc; i++) { /* copy buf to tape */
|
||||
xma = (xma + 1) & AMASK; /* incr mem addr */
|
||||
if (PACKED (mt_cu)) { /* packed? */
|
||||
mtxb[p++] = (M[xma] >> 12) & 077;
|
||||
mtxb[p++] = (M[xma] >> 6) & 077;
|
||||
mtxb[p++] = M[xma] & 077; }
|
||||
else {
|
||||
mtxb[p++] = (M[xma] >> 8) & 0377;
|
||||
mtxb[p++] = M[xma] & 0377; } }
|
||||
if (st = sim_tape_wrrecf (uptr, mtxb, tbc)) /* write rec, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
else {
|
||||
M[MT_CA] = (M[MT_CA] + wc) & DMASK; /* advance mem addr */
|
||||
M[MT_WC] = 0; } /* clear word cnt */
|
||||
mt_cu = mt_cu & ~CU_ERASE; /* clear erase flag */
|
||||
break;
|
||||
|
||||
/* Unit service, continued */
|
||||
case FN_WRITE: /* write */
|
||||
tbc = PACKED (mt_cu)? wc * 3: wc * 2;
|
||||
xma = M[MT_CA] & AMASK; /* get mem addr */
|
||||
for (i = p = 0; i < wc; i++) { /* copy buf to tape */
|
||||
xma = (xma + 1) & AMASK; /* incr mem addr */
|
||||
if (PACKED (mt_cu)) { /* packed? */
|
||||
mtxb[p++] = (M[xma] >> 12) & 077;
|
||||
mtxb[p++] = (M[xma] >> 6) & 077;
|
||||
mtxb[p++] = M[xma] & 077;
|
||||
}
|
||||
else {
|
||||
mtxb[p++] = (M[xma] >> 8) & 0377;
|
||||
mtxb[p++] = M[xma] & 0377;
|
||||
}
|
||||
} /* end for */
|
||||
if (st = sim_tape_wrrecf (uptr, mtxb, tbc)) /* write rec, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
else {
|
||||
M[MT_CA] = (M[MT_CA] + wc) & DMASK; /* advance mem addr */
|
||||
M[MT_WC] = 0; /* clear word cnt */
|
||||
}
|
||||
mt_cu = mt_cu & ~CU_ERASE; /* clear erase flag */
|
||||
break;
|
||||
|
||||
case FN_WREOF:
|
||||
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
else uptr->USTAT = STA_EOF;
|
||||
mt_cu = mt_cu & ~CU_ERASE; /* clear erase flag */
|
||||
break;
|
||||
case FN_WREOF:
|
||||
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
else uptr->USTAT = STA_EOF;
|
||||
mt_cu = mt_cu & ~CU_ERASE; /* clear erase flag */
|
||||
break;
|
||||
|
||||
case FN_SPACEF: /* space forward */
|
||||
do {
|
||||
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC */
|
||||
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
break; }
|
||||
}
|
||||
while (M[MT_WC] != 0);
|
||||
break;
|
||||
case FN_SPACEF: /* space forward */
|
||||
do {
|
||||
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC */
|
||||
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
}
|
||||
} while (M[MT_WC] != 0);
|
||||
break;
|
||||
|
||||
case FN_SPACER: /* space reverse */
|
||||
do {
|
||||
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC */
|
||||
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
break; }
|
||||
}
|
||||
while (M[MT_WC] != 0);
|
||||
break; } /* end case */
|
||||
case FN_SPACER: /* space reverse */
|
||||
do {
|
||||
M[MT_WC] = (M[MT_WC] + 1) & DMASK; /* inc WC */
|
||||
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
||||
r = mt_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
}
|
||||
} while (M[MT_WC] != 0);
|
||||
break;
|
||||
} /* end case */
|
||||
|
||||
mt_updcsta (uptr, STA_DON); /* set done */
|
||||
mt_updcsta (uptr, STA_DON); /* set done */
|
||||
if (mt_log) printf ("MT%d: fnc=%d done, ma=%o, wc=%o, sta=%o]\n",
|
||||
u, f, M[MT_CA], M[MT_WC], mt_sta);
|
||||
u, f, M[MT_CA], M[MT_WC], mt_sta);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* Update controller status */
|
||||
|
||||
int32 mt_updcsta (UNIT *uptr, int32 news)
|
||||
{
|
||||
mt_sta = (mt_sta & ~(STA_DYN | STA_CLR)) |
|
||||
(uptr->USTAT & STA_DYN) | news;
|
||||
(uptr->USTAT & STA_DYN) | news;
|
||||
if ((mt_sta & (STA_ERR | STA_DON)) && (mt_cu & CU_IE))
|
||||
SET_INT (MTA);
|
||||
else CLR_INT (MTA); /* int request */
|
||||
SET_INT (MTA);
|
||||
else CLR_INT (MTA); /* int request */
|
||||
return mt_sta;
|
||||
}
|
||||
|
||||
@@ -384,10 +401,11 @@ UNIT *mt_busy (void)
|
||||
int32 u;
|
||||
UNIT *uptr;
|
||||
|
||||
for (u = 0; u < MT_NUMDR; u++) { /* loop thru units */
|
||||
uptr = mt_dev.units + u;
|
||||
if (sim_is_active (uptr) && ((uptr->USTAT & STA_REW) == 0))
|
||||
return uptr; }
|
||||
for (u = 0; u < MT_NUMDR; u++) { /* loop thru units */
|
||||
uptr = mt_dev.units + u;
|
||||
if (sim_is_active (uptr) && ((uptr->USTAT & STA_REW) == 0))
|
||||
return uptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -396,38 +414,48 @@ return NULL;
|
||||
t_stat mt_map_err (UNIT *uptr, t_stat st)
|
||||
{
|
||||
switch (st) {
|
||||
case MTSE_FMT: /* illegal fmt */
|
||||
case MTSE_UNATT: /* not attached */
|
||||
mt_sta = mt_sta | STA_ILL | STA_ERR;
|
||||
case MTSE_OK: /* no error */
|
||||
return SCPE_IERR;
|
||||
case MTSE_TMK: /* end of file */
|
||||
uptr->USTAT = uptr->USTAT | STA_EOF; /* set EOF */
|
||||
mt_sta = mt_sta | STA_ERR;
|
||||
break;
|
||||
case MTSE_IOERR: /* IO error */
|
||||
mt_sta = mt_sta | STA_PAR | STA_ERR; /* set par err */
|
||||
if (mt_stopioe) return SCPE_IOERR;
|
||||
break;
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
mt_sta = mt_sta | STA_PAR | STA_ERR; /* set par err */
|
||||
return SCPE_MTRLNT;
|
||||
case MTSE_RECE: /* record in error */
|
||||
mt_sta = mt_sta | STA_PAR | STA_ERR; /* set par err */
|
||||
break;
|
||||
case MTSE_EOM: /* end of medium */
|
||||
mt_sta = mt_sta | STA_BAD | STA_ERR; /* set end tape */
|
||||
break;
|
||||
case MTSE_BOT: /* reverse into BOT */
|
||||
uptr->USTAT = uptr->USTAT | STA_BOT; /* set status */
|
||||
mt_sta = mt_sta | STA_ERR;
|
||||
break;
|
||||
case MTSE_WRP: /* write protect */
|
||||
mt_sta = mt_sta | STA_ILL | STA_ERR; /* illegal operation */
|
||||
break; }
|
||||
|
||||
case MTSE_FMT: /* illegal fmt */
|
||||
case MTSE_UNATT: /* not attached */
|
||||
mt_sta = mt_sta | STA_ILL | STA_ERR;
|
||||
case MTSE_OK: /* no error */
|
||||
return SCPE_IERR;
|
||||
|
||||
case MTSE_TMK: /* end of file */
|
||||
uptr->USTAT = uptr->USTAT | STA_EOF; /* set EOF */
|
||||
mt_sta = mt_sta | STA_ERR;
|
||||
break;
|
||||
|
||||
case MTSE_IOERR: /* IO error */
|
||||
mt_sta = mt_sta | STA_PAR | STA_ERR; /* set par err */
|
||||
if (mt_stopioe) return SCPE_IOERR;
|
||||
break;
|
||||
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
mt_sta = mt_sta | STA_PAR | STA_ERR; /* set par err */
|
||||
return SCPE_MTRLNT;
|
||||
|
||||
case MTSE_RECE: /* record in error */
|
||||
mt_sta = mt_sta | STA_PAR | STA_ERR; /* set par err */
|
||||
break;
|
||||
|
||||
case MTSE_EOM: /* end of medium */
|
||||
mt_sta = mt_sta | STA_BAD | STA_ERR; /* set end tape */
|
||||
break;
|
||||
|
||||
case MTSE_BOT: /* reverse into BOT */
|
||||
uptr->USTAT = uptr->USTAT | STA_BOT; /* set status */
|
||||
mt_sta = mt_sta | STA_ERR;
|
||||
break;
|
||||
|
||||
case MTSE_WRP: /* write protect */
|
||||
mt_sta = mt_sta | STA_ILL | STA_ERR; /* illegal operation */
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat mt_reset (DEVICE *dptr)
|
||||
@@ -436,14 +464,15 @@ int32 u;
|
||||
UNIT *uptr;
|
||||
|
||||
mt_cu = mt_sta = 0;
|
||||
for (u = 0; u < MT_NUMDR; u++) { /* loop thru units */
|
||||
uptr = mt_dev.units + u;
|
||||
sim_tape_reset (uptr); /* reset tape */
|
||||
sim_cancel (uptr); /* cancel activity */
|
||||
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_BOT;
|
||||
else uptr->USTAT = 0; }
|
||||
mt_updcsta (&mt_unit[0], 0); /* update status */
|
||||
if (mtxb == NULL) mtxb = calloc (MT_MAXFR, sizeof (uint8));
|
||||
for (u = 0; u < MT_NUMDR; u++) { /* loop thru units */
|
||||
uptr = mt_dev.units + u;
|
||||
sim_tape_reset (uptr); /* reset tape */
|
||||
sim_cancel (uptr); /* cancel activity */
|
||||
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_BOT;
|
||||
else uptr->USTAT = 0;
|
||||
}
|
||||
mt_updcsta (&mt_unit[0], 0); /* update status */
|
||||
if (mtxb == NULL) mtxb = (uint8 *) calloc (MT_MAXFR, sizeof (uint8));
|
||||
if (mtxb == NULL) return SCPE_MEM;
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -464,7 +493,7 @@ t_stat r;
|
||||
r = sim_tape_attach (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
uptr->USTAT = STA_BOT;
|
||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -472,8 +501,8 @@ return r;
|
||||
|
||||
t_stat mt_detach (UNIT* uptr)
|
||||
{
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||
if (!sim_is_active (uptr)) uptr->USTAT = 0;
|
||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||
return sim_tape_detach (uptr);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp18b_rb.c: RB09 fixed head disk simulator
|
||||
|
||||
Copyright (c) 2003-2004, Robert M Supnik
|
||||
Copyright (c) 2003-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,23 +19,23 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
rb RB09 fixed head disk
|
||||
rb RB09 fixed head disk
|
||||
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
|
||||
The RB09 is a head-per-track disk. It uses the single cycle data break
|
||||
facility. To minimize overhead, the entire RB09 is buffered in memory.
|
||||
|
||||
Two timing parameters are provided:
|
||||
|
||||
rb_time Interword timing. Must be non-zero.
|
||||
rb_burst Burst mode. If 0, DMA occurs cycle by cycle; otherwise,
|
||||
DMA occurs in a burst.
|
||||
rb_time Interword timing. Must be non-zero.
|
||||
rb_burst Burst mode. If 0, DMA occurs cycle by cycle; otherwise,
|
||||
DMA occurs in a burst.
|
||||
*/
|
||||
|
||||
#include "pdp18b_defs.h"
|
||||
@@ -43,51 +43,51 @@
|
||||
|
||||
/* Constants */
|
||||
|
||||
#define RB_NUMWD 64 /* words/sector */
|
||||
#define RB_NUMSC 80 /* sectors/track */
|
||||
#define RB_NUMTR 200 /* tracks/disk */
|
||||
#define RB_WLKTR 10 /* tracks/wlock switch */
|
||||
#define RB_SIZE (RB_NUMTR * RB_NUMSC * RB_NUMWD) /* words/drive */
|
||||
#define RB_NUMWD 64 /* words/sector */
|
||||
#define RB_NUMSC 80 /* sectors/track */
|
||||
#define RB_NUMTR 200 /* tracks/disk */
|
||||
#define RB_WLKTR 10 /* tracks/wlock switch */
|
||||
#define RB_SIZE (RB_NUMTR * RB_NUMSC * RB_NUMWD) /* words/drive */
|
||||
|
||||
/* Function/status register */
|
||||
|
||||
#define RBS_ERR 0400000 /* error */
|
||||
#define RBS_PAR 0200000 /* parity error */
|
||||
#define RBS_ILA 0100000 /* ill addr error */
|
||||
#define RBS_TIM 0040000 /* timing transfer */
|
||||
#define RBS_NRY 0020000 /* not ready error */
|
||||
#define RBS_DON 0010000 /* done */
|
||||
#define RBS_IE 0004000 /* int enable */
|
||||
#define RBS_BSY 0002000 /* busy */
|
||||
#define RBS_WR 0001000 /* read/write */
|
||||
#define RBS_XOR (RBS_IE|RBS_BSY|RBS_WR) /* set by XOR */
|
||||
#define RBS_MBZ 0000777 /* always clear */
|
||||
#define RBS_EFLGS (RBS_PAR|RBS_ILA|RBS_TIM|RBS_NRY) /* error flags */
|
||||
#define RBS_ERR 0400000 /* error */
|
||||
#define RBS_PAR 0200000 /* parity error */
|
||||
#define RBS_ILA 0100000 /* ill addr error */
|
||||
#define RBS_TIM 0040000 /* timing transfer */
|
||||
#define RBS_NRY 0020000 /* not ready error */
|
||||
#define RBS_DON 0010000 /* done */
|
||||
#define RBS_IE 0004000 /* int enable */
|
||||
#define RBS_BSY 0002000 /* busy */
|
||||
#define RBS_WR 0001000 /* read/write */
|
||||
#define RBS_XOR (RBS_IE|RBS_BSY|RBS_WR) /* set by XOR */
|
||||
#define RBS_MBZ 0000777 /* always clear */
|
||||
#define RBS_EFLGS (RBS_PAR|RBS_ILA|RBS_TIM|RBS_NRY) /* error flags */
|
||||
|
||||
/* BCD disk address */
|
||||
|
||||
#define RBA_V_TR 8
|
||||
#define RBA_M_TR 0x1FF
|
||||
#define RBA_V_SC 0
|
||||
#define RBA_M_SC 0xFF
|
||||
#define RBA_GETTR(x) (((x) >> RBA_V_TR) & RBA_M_TR)
|
||||
#define RBA_GETSC(x) (((x) >> RBA_V_SC) & RBA_M_SC)
|
||||
#define RBA_V_TR 8
|
||||
#define RBA_M_TR 0x1FF
|
||||
#define RBA_V_SC 0
|
||||
#define RBA_M_SC 0xFF
|
||||
#define RBA_GETTR(x) (((x) >> RBA_V_TR) & RBA_M_TR)
|
||||
#define RBA_GETSC(x) (((x) >> RBA_V_SC) & RBA_M_SC)
|
||||
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime () / ((double) (x)), \
|
||||
((double) (RB_NUMSC * RB_NUMWD))))
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime () / ((double) (x)), \
|
||||
((double) (RB_NUMSC * RB_NUMWD))))
|
||||
|
||||
extern int32 M[];
|
||||
extern int32 int_hwre[API_HLVL+1];
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
int32 rb_sta = 0; /* status register */
|
||||
int32 rb_da = 0; /* disk address */
|
||||
int32 rb_ma = 0; /* current addr */
|
||||
int32 rb_wc = 0; /* word count */
|
||||
int32 rb_wlk = 0; /* write lock */
|
||||
int32 rb_time = 10; /* inter-word time */
|
||||
int32 rb_burst = 1; /* burst mode flag */
|
||||
int32 rb_stopioe = 1; /* stop on error */
|
||||
int32 rb_sta = 0; /* status register */
|
||||
int32 rb_da = 0; /* disk address */
|
||||
int32 rb_ma = 0; /* current addr */
|
||||
int32 rb_wc = 0; /* word count */
|
||||
int32 rb_wlk = 0; /* write lock */
|
||||
int32 rb_time = 10; /* inter-word time */
|
||||
int32 rb_burst = 1; /* burst mode flag */
|
||||
int32 rb_stopioe = 1; /* stop on error */
|
||||
|
||||
DEVICE rb_dev;
|
||||
int32 rb71 (int32 dev, int32 pulse, int32 AC);
|
||||
@@ -98,44 +98,48 @@ int32 rb_make_da (int32 dat);
|
||||
int32 rb_make_bcd (int32 dat);
|
||||
int32 rb_set_da (int32 dat, int32 old);
|
||||
int32 rb_set_bcd (int32 dat);
|
||||
|
||||
|
||||
/* RB data structures
|
||||
|
||||
rb_dev RF device descriptor
|
||||
rb_unit RF unit descriptor
|
||||
rb_reg RF register list
|
||||
rb_dev RF device descriptor
|
||||
rb_unit RF unit descriptor
|
||||
rb_reg RF register list
|
||||
*/
|
||||
|
||||
DIB rb_dib = { DEV_RB, 1, NULL, { &rb71 } };
|
||||
|
||||
UNIT rb_unit =
|
||||
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
|
||||
RB_SIZE) };
|
||||
UNIT rb_unit = {
|
||||
UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
|
||||
RB_SIZE)
|
||||
};
|
||||
|
||||
REG rb_reg[] = {
|
||||
{ ORDATA (STA, rb_sta, 18) },
|
||||
{ ORDATA (DA, rb_da, 20) },
|
||||
{ ORDATA (WC, rb_wc, 16) },
|
||||
{ ORDATA (MA, rb_ma, ADDRSIZE) },
|
||||
{ FLDATA (INT, int_hwre[API_RB], INT_V_RB) },
|
||||
{ ORDATA (WLK, rb_wlk, RB_NUMTR / RB_WLKTR) },
|
||||
{ DRDATA (TIME, rb_time, 24), PV_LEFT + REG_NZ },
|
||||
{ FLDATA (BURST, rb_burst, 0) },
|
||||
{ FLDATA (STOP_IOE, rb_stopioe, 0) },
|
||||
{ ORDATA (DEVNO, rb_dib.dev, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
{ ORDATA (STA, rb_sta, 18) },
|
||||
{ ORDATA (DA, rb_da, 20) },
|
||||
{ ORDATA (WC, rb_wc, 16) },
|
||||
{ ORDATA (MA, rb_ma, ADDRSIZE) },
|
||||
{ FLDATA (INT, int_hwre[API_RB], INT_V_RB) },
|
||||
{ ORDATA (WLK, rb_wlk, RB_NUMTR / RB_WLKTR) },
|
||||
{ DRDATA (TIME, rb_time, 24), PV_LEFT + REG_NZ },
|
||||
{ FLDATA (BURST, rb_burst, 0) },
|
||||
{ FLDATA (STOP_IOE, rb_stopioe, 0) },
|
||||
{ ORDATA (DEVNO, rb_dib.dev, 6), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB rb_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 } };
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE rb_dev = {
|
||||
"RB", &rb_unit, rb_reg, rb_mod,
|
||||
1, 8, 21, 1, 8, 18,
|
||||
NULL, NULL, &rb_reset,
|
||||
NULL, NULL, NULL,
|
||||
&rb_dib, DEV_DIS | DEV_DISABLE };
|
||||
|
||||
"RB", &rb_unit, rb_reg, rb_mod,
|
||||
1, 8, 21, 1, 8, 18,
|
||||
NULL, NULL, &rb_reset,
|
||||
NULL, NULL, NULL,
|
||||
&rb_dib, DEV_DIS | DEV_DISABLE
|
||||
};
|
||||
|
||||
/* IOT routines */
|
||||
|
||||
int32 rb71 (int32 dev, int32 pulse, int32 AC)
|
||||
@@ -143,65 +147,70 @@ int32 rb71 (int32 dev, int32 pulse, int32 AC)
|
||||
int32 tow, t, sb = pulse & 060;
|
||||
|
||||
if (pulse & 001) {
|
||||
if (sb == 000) rb_sta = rb_sta & /* DBCF */
|
||||
~(RBS_ERR | RBS_EFLGS | RBS_DON);
|
||||
if ((sb == 020) && (rb_sta & (RBS_ERR | RBS_DON)))
|
||||
AC = AC | IOT_SKP; /* DBSF */
|
||||
if (sb == 040) rb_sta = 0; /* DBCS */
|
||||
}
|
||||
if (sb == 000) rb_sta = rb_sta & /* DBCF */
|
||||
~(RBS_ERR | RBS_EFLGS | RBS_DON);
|
||||
if ((sb == 020) && (rb_sta & (RBS_ERR | RBS_DON)))
|
||||
AC = AC | IOT_SKP; /* DBSF */
|
||||
if (sb == 040) rb_sta = 0; /* DBCS */
|
||||
}
|
||||
if (pulse & 002) {
|
||||
if (sb == 000) AC = AC | rb_make_da (rb_da); /* DBRD */
|
||||
if (sb == 020) AC = AC | rb_sta; /* DBRS */
|
||||
if (sb == 040) rb_ma = AC & AMASK; /* DBLM */
|
||||
}
|
||||
if (sb == 000) AC = AC | rb_make_da (rb_da); /* DBRD */
|
||||
if (sb == 020) AC = AC | rb_sta; /* DBRS */
|
||||
if (sb == 040) rb_ma = AC & AMASK; /* DBLM */
|
||||
}
|
||||
if (pulse & 004) {
|
||||
if (sb == 000) rb_da = rb_set_da (AC, rb_da); /* DBLD */
|
||||
if (sb == 020) rb_wc = AC & 0177777; /* DBLW */
|
||||
if (sb == 040) { /* DBLS */
|
||||
rb_sta = (rb_sta & RBS_XOR) ^ (AC & ~RBS_MBZ);
|
||||
if (rb_sta & RBS_BSY) { /* busy set? */
|
||||
if (!sim_is_active (&rb_unit)) { /* schedule */
|
||||
tow = rb_da % (RB_NUMSC * RB_NUMWD);
|
||||
t = tow - GET_POS (rb_time);
|
||||
if (t < 0) t = t + (RB_NUMSC * RB_NUMWD);
|
||||
sim_activate (&rb_unit, t * rb_time); } }
|
||||
else sim_cancel (&rb_unit); } /* no, stop */
|
||||
}
|
||||
rb_updsta (0); /* update status */
|
||||
if (sb == 000) rb_da = rb_set_da (AC, rb_da); /* DBLD */
|
||||
if (sb == 020) rb_wc = AC & 0177777; /* DBLW */
|
||||
if (sb == 040) { /* DBLS */
|
||||
rb_sta = (rb_sta & RBS_XOR) ^ (AC & ~RBS_MBZ);
|
||||
if (rb_sta & RBS_BSY) { /* busy set? */
|
||||
if (!sim_is_active (&rb_unit)) { /* schedule */
|
||||
tow = rb_da % (RB_NUMSC * RB_NUMWD);
|
||||
t = tow - GET_POS (rb_time);
|
||||
if (t < 0) t = t + (RB_NUMSC * RB_NUMWD);
|
||||
sim_activate (&rb_unit, t * rb_time);
|
||||
}
|
||||
}
|
||||
else sim_cancel (&rb_unit); /* no, stop */
|
||||
}
|
||||
}
|
||||
rb_updsta (0); /* update status */
|
||||
return AC;
|
||||
}
|
||||
|
||||
int32 rb_make_da (int32 da)
|
||||
{
|
||||
int32 t = da / (RB_NUMSC * RB_NUMWD); /* bin track */
|
||||
int32 s = (da % (RB_NUMSC * RB_NUMWD)) / RB_NUMWD; /* bin sector */
|
||||
int32 bcd_t = rb_make_bcd (t); /* bcd track */
|
||||
int32 bcd_s = rb_make_bcd (s); /* bcd sector */
|
||||
int32 t = da / (RB_NUMSC * RB_NUMWD); /* bin track */
|
||||
int32 s = (da % (RB_NUMSC * RB_NUMWD)) / RB_NUMWD; /* bin sector */
|
||||
int32 bcd_t = rb_make_bcd (t); /* bcd track */
|
||||
int32 bcd_s = rb_make_bcd (s); /* bcd sector */
|
||||
return (bcd_t << RBA_V_TR) | (bcd_s << RBA_V_SC);
|
||||
}
|
||||
|
||||
int32 rb_set_da (int32 bcda, int32 old_da)
|
||||
{
|
||||
int32 bcd_t = RBA_GETTR (bcda); /* bcd track */
|
||||
int32 bcd_s = RBA_GETSC (bcda); /* bcd sector */
|
||||
int32 t = rb_set_bcd (bcd_t); /* bin track */
|
||||
int32 s = rb_set_bcd (bcd_s); /* bin sector */
|
||||
int32 bcd_t = RBA_GETTR (bcda); /* bcd track */
|
||||
int32 bcd_s = RBA_GETSC (bcda); /* bcd sector */
|
||||
int32 t = rb_set_bcd (bcd_t); /* bin track */
|
||||
int32 s = rb_set_bcd (bcd_s); /* bin sector */
|
||||
|
||||
if ((t >= RB_NUMTR) || (t < 0) || /* invalid? */
|
||||
if ((t >= RB_NUMTR) || (t < 0) || /* invalid? */
|
||||
(s >= RB_NUMSC) || (s < 0)) {
|
||||
rb_updsta (RBS_ILA); /* error */
|
||||
return old_da; } /* don't change */
|
||||
else return (((t * RB_NUMSC) + s) * RB_NUMWD); /* new da */
|
||||
rb_updsta (RBS_ILA); /* error */
|
||||
return old_da; /* don't change */
|
||||
}
|
||||
else return (((t * RB_NUMSC) + s) * RB_NUMWD); /* new da */
|
||||
}
|
||||
|
||||
int32 rb_make_bcd (int32 bin)
|
||||
{
|
||||
int32 d, i, r;
|
||||
|
||||
for (r = i = 0; bin != 0; bin = bin / 10) { /* while nz */
|
||||
d = bin % 10; /* dec digit */
|
||||
r = r | (d << i); /* insert bcd */
|
||||
i = i + 4; }
|
||||
for (r = i = 0; bin != 0; bin = bin / 10) { /* while nz */
|
||||
d = bin % 10; /* dec digit */
|
||||
r = r | (d << i); /* insert bcd */
|
||||
i = i + 4;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -209,14 +218,15 @@ int32 rb_set_bcd (int32 bcd)
|
||||
{
|
||||
int32 d, i, r;
|
||||
|
||||
for (r = 0, i = 1; bcd != 0; bcd = bcd >> 4) { /* while nz */
|
||||
d = bcd & 0xF; /* bcd digit */
|
||||
if (d >= 10) return -1; /* invalid? */
|
||||
r = r + (d * i); /* insert bin */
|
||||
i = i * 10; }
|
||||
for (r = 0, i = 1; bcd != 0; bcd = bcd >> 4) { /* while nz */
|
||||
d = bcd & 0xF; /* bcd digit */
|
||||
if (d >= 10) return -1; /* invalid? */
|
||||
r = r + (d * i); /* insert bin */
|
||||
i = i * 10;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Unit service - disk is buffered in memory */
|
||||
|
||||
t_stat rb_svc (UNIT *uptr)
|
||||
@@ -224,31 +234,35 @@ t_stat rb_svc (UNIT *uptr)
|
||||
int32 t, sw;
|
||||
int32 *fbuf = uptr->filebuf;
|
||||
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
rb_updsta (RBS_NRY | RBS_DON); /* set nxd, done */
|
||||
return IORETURN (rb_stopioe, SCPE_UNATT); }
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
rb_updsta (RBS_NRY | RBS_DON); /* set nxd, done */
|
||||
return IORETURN (rb_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
do { if (rb_sta & RBS_WR) { /* write? */
|
||||
t = rb_da / (RB_NUMSC * RB_NUMWD); /* track */
|
||||
sw = t / RB_WLKTR; /* switch */
|
||||
if ((rb_wlk >> sw) & 1) { /* write locked? */
|
||||
rb_updsta (RBS_ILA | RBS_DON);
|
||||
break; }
|
||||
else { /* not locked */
|
||||
fbuf[rb_da] = M[rb_ma]; /* write word */
|
||||
if (((t_addr) rb_da) >= uptr->hwmark) uptr->hwmark = rb_da + 1; } }
|
||||
else if (MEM_ADDR_OK (rb_ma)) /* read, valid addr? */
|
||||
M[rb_ma] = fbuf[rb_da]; /* read word */
|
||||
rb_wc = (rb_wc + 1) & 0177777; /* incr word count */
|
||||
rb_ma = (rb_ma + 1) & AMASK; /* incr mem addr */
|
||||
rb_da = rb_da + 1; /* incr disk addr */
|
||||
if (rb_da > RB_SIZE) rb_da = 0; /* disk wraparound? */
|
||||
}
|
||||
while ((rb_wc != 0) && (rb_burst != 0)); /* brk if wc, no brst */
|
||||
do {
|
||||
if (rb_sta & RBS_WR) { /* write? */
|
||||
t = rb_da / (RB_NUMSC * RB_NUMWD); /* track */
|
||||
sw = t / RB_WLKTR; /* switch */
|
||||
if ((rb_wlk >> sw) & 1) { /* write locked? */
|
||||
rb_updsta (RBS_ILA | RBS_DON);
|
||||
break;
|
||||
}
|
||||
else { /* not locked */
|
||||
fbuf[rb_da] = M[rb_ma]; /* write word */
|
||||
if (((t_addr) rb_da) >= uptr->hwmark) uptr->hwmark = rb_da + 1;
|
||||
}
|
||||
}
|
||||
else if (MEM_ADDR_OK (rb_ma)) /* read, valid addr? */
|
||||
M[rb_ma] = fbuf[rb_da]; /* read word */
|
||||
rb_wc = (rb_wc + 1) & 0177777; /* incr word count */
|
||||
rb_ma = (rb_ma + 1) & AMASK; /* incr mem addr */
|
||||
rb_da = rb_da + 1; /* incr disk addr */
|
||||
if (rb_da > RB_SIZE) rb_da = 0; /* disk wraparound? */
|
||||
} while ((rb_wc != 0) && (rb_burst != 0)); /* brk if wc, no brst */
|
||||
|
||||
if ((rb_wc != 0) && ((rb_sta & RBS_ERR) == 0)) /* more to do? */
|
||||
sim_activate (&rb_unit, rb_time); /* sched next */
|
||||
else rb_updsta (RBS_DON); /* set done */
|
||||
if ((rb_wc != 0) && ((rb_sta & RBS_ERR) == 0)) /* more to do? */
|
||||
sim_activate (&rb_unit, rb_time); /* sched next */
|
||||
else rb_updsta (RBS_DON); /* set done */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -256,11 +270,11 @@ return SCPE_OK;
|
||||
|
||||
int32 rb_updsta (int32 new)
|
||||
{
|
||||
rb_sta = (rb_sta | new) & ~(RBS_ERR | RBS_MBZ); /* clear err, mbz */
|
||||
if (rb_sta & RBS_EFLGS) rb_sta = rb_sta | RBS_ERR; /* error? */
|
||||
if (rb_sta & RBS_DON) rb_sta = rb_sta & ~RBS_BSY; /* done? clear busy */
|
||||
rb_sta = (rb_sta | new) & ~(RBS_ERR | RBS_MBZ); /* clear err, mbz */
|
||||
if (rb_sta & RBS_EFLGS) rb_sta = rb_sta | RBS_ERR; /* error? */
|
||||
if (rb_sta & RBS_DON) rb_sta = rb_sta & ~RBS_BSY; /* done? clear busy */
|
||||
if ((rb_sta & (RBS_ERR | RBS_DON)) && (rb_sta & RBS_IE))
|
||||
SET_INT (RB); /* set or clr intr */
|
||||
SET_INT (RB); /* set or clr intr */
|
||||
else CLR_INT (RB);
|
||||
return rb_sta;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp18b_rf.c: fixed head disk simulator
|
||||
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,102 +19,102 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
rf (PDP-9) RF09/RF09
|
||||
(PDP-15) RF15/RS09
|
||||
rf (PDP-9) RF09/RF09
|
||||
(PDP-15) RF15/RS09
|
||||
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
Changed sim_fsize calling sequence
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
26-Jul-03 RMS Fixed bug in set size routine
|
||||
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
||||
03-Mar-03 RMS Fixed autosizing
|
||||
12-Feb-03 RMS Removed 8 platter sizing hack
|
||||
05-Feb-03 RMS Fixed decode bugs, added variable and autosizing
|
||||
05-Oct-02 RMS Added DIB, dev number support
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
24-Nov-01 RMS Changed WLK to array
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
15-Feb-01 RMS Fixed 3 cycle data break sequencing
|
||||
30-Nov-99 RMS Added non-zero requirement to rf_time
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
Changed sim_fsize calling sequence
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
26-Jul-03 RMS Fixed bug in set size routine
|
||||
14-Mar-03 RMS Fixed variable platter interaction with save/restore
|
||||
03-Mar-03 RMS Fixed autosizing
|
||||
12-Feb-03 RMS Removed 8 platter sizing hack
|
||||
05-Feb-03 RMS Fixed decode bugs, added variable and autosizing
|
||||
05-Oct-02 RMS Added DIB, dev number support
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
24-Nov-01 RMS Changed WLK to array
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
15-Feb-01 RMS Fixed 3 cycle data break sequencing
|
||||
30-Nov-99 RMS Added non-zero requirement to rf_time
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
|
||||
The RFxx is a head-per-track disk. It uses the multicycle data break
|
||||
facility. To minimize overhead, the entire RFxx is buffered in memory.
|
||||
|
||||
Two timing parameters are provided:
|
||||
|
||||
rf_time Interword timing. Must be non-zero.
|
||||
rf_burst Burst mode. If 0, DMA occurs cycle by cycle; otherwise,
|
||||
DMA occurs in a burst.
|
||||
rf_time Interword timing. Must be non-zero.
|
||||
rf_burst Burst mode. If 0, DMA occurs cycle by cycle; otherwise,
|
||||
DMA occurs in a burst.
|
||||
*/
|
||||
|
||||
#include "pdp18b_defs.h"
|
||||
#include <math.h>
|
||||
|
||||
#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */
|
||||
#define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */
|
||||
#define UNIT_M_PLAT 07
|
||||
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
|
||||
#define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1)
|
||||
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
||||
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
|
||||
#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */
|
||||
#define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */
|
||||
#define UNIT_M_PLAT 07
|
||||
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
|
||||
#define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1)
|
||||
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
||||
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
|
||||
|
||||
/* Constants */
|
||||
|
||||
#define RF_NUMWD 2048 /* words/track */
|
||||
#define RF_NUMTR 128 /* tracks/disk */
|
||||
#define RF_DKSIZE (RF_NUMTR * RF_NUMWD) /* words/disk */
|
||||
#define RF_NUMDK 8 /* disks/controller */
|
||||
#define RF_WMASK (RF_NUMWD - 1) /* word mask */
|
||||
#define RF_WC 036 /* word count */
|
||||
#define RF_CA 037 /* current addr */
|
||||
#define RF_NUMWD 2048 /* words/track */
|
||||
#define RF_NUMTR 128 /* tracks/disk */
|
||||
#define RF_DKSIZE (RF_NUMTR * RF_NUMWD) /* words/disk */
|
||||
#define RF_NUMDK 8 /* disks/controller */
|
||||
#define RF_WMASK (RF_NUMWD - 1) /* word mask */
|
||||
#define RF_WC 036 /* word count */
|
||||
#define RF_CA 037 /* current addr */
|
||||
|
||||
/* Function/status register */
|
||||
|
||||
#define RFS_ERR 0400000 /* error */
|
||||
#define RFS_HDW 0200000 /* hardware error */
|
||||
#define RFS_APE 0100000 /* addr parity error */
|
||||
#define RFS_MXF 0040000 /* missed transfer */
|
||||
#define RFS_WCE 0020000 /* write check error */
|
||||
#define RFS_DPE 0010000 /* data parity error */
|
||||
#define RFS_WLO 0004000 /* write lock error */
|
||||
#define RFS_NED 0002000 /* non-existent disk */
|
||||
#define RFS_DCH 0001000 /* data chan timing */
|
||||
#define RFS_PGE 0000400 /* programming error */
|
||||
#define RFS_DON 0000200 /* transfer complete */
|
||||
#define RFS_V_FNC 1 /* function */
|
||||
#define RFS_M_FNC 03
|
||||
#define RFS_FNC (RFS_M_FNC << RFS_V_FNC)
|
||||
#define FN_NOP 0
|
||||
#define FN_READ 1
|
||||
#define FN_WRITE 2
|
||||
#define FN_WCHK 3
|
||||
#define RFS_IE 0000001 /* interrupt enable */
|
||||
#define RFS_ERR 0400000 /* error */
|
||||
#define RFS_HDW 0200000 /* hardware error */
|
||||
#define RFS_APE 0100000 /* addr parity error */
|
||||
#define RFS_MXF 0040000 /* missed transfer */
|
||||
#define RFS_WCE 0020000 /* write check error */
|
||||
#define RFS_DPE 0010000 /* data parity error */
|
||||
#define RFS_WLO 0004000 /* write lock error */
|
||||
#define RFS_NED 0002000 /* non-existent disk */
|
||||
#define RFS_DCH 0001000 /* data chan timing */
|
||||
#define RFS_PGE 0000400 /* programming error */
|
||||
#define RFS_DON 0000200 /* transfer complete */
|
||||
#define RFS_V_FNC 1 /* function */
|
||||
#define RFS_M_FNC 03
|
||||
#define RFS_FNC (RFS_M_FNC << RFS_V_FNC)
|
||||
#define FN_NOP 0
|
||||
#define FN_READ 1
|
||||
#define FN_WRITE 2
|
||||
#define FN_WCHK 3
|
||||
#define RFS_IE 0000001 /* interrupt enable */
|
||||
|
||||
#define RFS_CLR 0000170 /* always clear */
|
||||
#define RFS_EFLGS (RFS_HDW | RFS_APE | RFS_MXF | RFS_WCE | \
|
||||
RFS_DPE | RFS_WLO | RFS_NED ) /* error flags */
|
||||
#define GET_FNC(x) (((x) >> RFS_V_FNC) & RFS_M_FNC)
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime () / ((double) (x)), \
|
||||
((double) RF_NUMWD)))
|
||||
#define RF_BUSY (sim_is_active (&rf_unit))
|
||||
|
||||
#define RFS_CLR 0000170 /* always clear */
|
||||
#define RFS_EFLGS (RFS_HDW | RFS_APE | RFS_MXF | RFS_WCE | \
|
||||
RFS_DPE | RFS_WLO | RFS_NED ) /* error flags */
|
||||
#define GET_FNC(x) (((x) >> RFS_V_FNC) & RFS_M_FNC)
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime () / ((double) (x)), \
|
||||
((double) RF_NUMWD)))
|
||||
#define RF_BUSY (sim_is_active (&rf_unit))
|
||||
|
||||
extern int32 M[];
|
||||
extern int32 int_hwre[API_HLVL+1];
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
int32 rf_sta = 0; /* status register */
|
||||
int32 rf_da = 0; /* disk address */
|
||||
int32 rf_dbuf = 0; /* data buffer */
|
||||
int32 rf_wlk[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* write lock */
|
||||
int32 rf_time = 10; /* inter-word time */
|
||||
int32 rf_burst = 1; /* burst mode flag */
|
||||
int32 rf_stopioe = 1; /* stop on error */
|
||||
int32 rf_sta = 0; /* status register */
|
||||
int32 rf_da = 0; /* disk address */
|
||||
int32 rf_dbuf = 0; /* data buffer */
|
||||
int32 rf_wlk[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* write lock */
|
||||
int32 rf_time = 10; /* inter-word time */
|
||||
int32 rf_burst = 1; /* burst mode flag */
|
||||
int32 rf_stopioe = 1; /* stop on error */
|
||||
|
||||
DEVICE rf_dev;
|
||||
int32 rf70 (int32 dev, int32 pulse, int32 dat);
|
||||
@@ -128,94 +128,102 @@ t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
|
||||
/* RF data structures
|
||||
|
||||
rf_dev RF device descriptor
|
||||
rf_unit RF unit descriptor
|
||||
rf_reg RF register list
|
||||
rf_dev RF device descriptor
|
||||
rf_unit RF unit descriptor
|
||||
rf_reg RF register list
|
||||
*/
|
||||
|
||||
DIB rf_dib = { DEV_RF, 3, &rf_iors, { &rf70, NULL, &rf72 } };
|
||||
|
||||
UNIT rf_unit =
|
||||
{ UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_AUTO,
|
||||
RF_DKSIZE) };
|
||||
UNIT rf_unit = {
|
||||
UDATA (&rf_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_AUTO,
|
||||
RF_DKSIZE)
|
||||
};
|
||||
|
||||
REG rf_reg[] = {
|
||||
{ ORDATA (STA, rf_sta, 18) },
|
||||
{ ORDATA (DA, rf_da, 22) },
|
||||
{ ORDATA (WC, M[RF_WC], 18) },
|
||||
{ ORDATA (CA, M[RF_CA], 18) },
|
||||
{ ORDATA (BUF, rf_dbuf, 18) },
|
||||
{ FLDATA (INT, int_hwre[API_RF], INT_V_RF) },
|
||||
{ BRDATA (WLK, rf_wlk, 8, 16, RF_NUMDK) },
|
||||
{ DRDATA (TIME, rf_time, 24), PV_LEFT + REG_NZ },
|
||||
{ FLDATA (BURST, rf_burst, 0) },
|
||||
{ FLDATA (STOP_IOE, rf_stopioe, 0) },
|
||||
{ DRDATA (CAPAC, rf_unit.capac, 31), PV_LEFT + REG_HRO },
|
||||
{ ORDATA (DEVNO, rf_dib.dev, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
{ ORDATA (STA, rf_sta, 18) },
|
||||
{ ORDATA (DA, rf_da, 22) },
|
||||
{ ORDATA (WC, M[RF_WC], 18) },
|
||||
{ ORDATA (CA, M[RF_CA], 18) },
|
||||
{ ORDATA (BUF, rf_dbuf, 18) },
|
||||
{ FLDATA (INT, int_hwre[API_RF], INT_V_RF) },
|
||||
{ BRDATA (WLK, rf_wlk, 8, 16, RF_NUMDK) },
|
||||
{ DRDATA (TIME, rf_time, 24), PV_LEFT + REG_NZ },
|
||||
{ FLDATA (BURST, rf_burst, 0) },
|
||||
{ FLDATA (STOP_IOE, rf_stopioe, 0) },
|
||||
{ DRDATA (CAPAC, rf_unit.capac, 31), PV_LEFT + REG_HRO },
|
||||
{ ORDATA (DEVNO, rf_dib.dev, 6), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB rf_mod[] = {
|
||||
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &rf_set_size },
|
||||
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &rf_set_size },
|
||||
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &rf_set_size },
|
||||
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &rf_set_size },
|
||||
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &rf_set_size },
|
||||
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &rf_set_size },
|
||||
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &rf_set_size },
|
||||
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &rf_set_size },
|
||||
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 } };
|
||||
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &rf_set_size },
|
||||
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &rf_set_size },
|
||||
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &rf_set_size },
|
||||
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &rf_set_size },
|
||||
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &rf_set_size },
|
||||
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &rf_set_size },
|
||||
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &rf_set_size },
|
||||
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &rf_set_size },
|
||||
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE rf_dev = {
|
||||
"RF", &rf_unit, rf_reg, rf_mod,
|
||||
1, 8, 21, 1, 8, 18,
|
||||
NULL, NULL, &rf_reset,
|
||||
NULL, &rf_attach, NULL,
|
||||
&rf_dib, DEV_DISABLE };
|
||||
|
||||
"RF", &rf_unit, rf_reg, rf_mod,
|
||||
1, 8, 21, 1, 8, 18,
|
||||
NULL, NULL, &rf_reset,
|
||||
NULL, &rf_attach, NULL,
|
||||
&rf_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* IOT routines */
|
||||
|
||||
int32 rf70 (int32 dev, int32 pulse, int32 dat)
|
||||
{
|
||||
int32 t, sb;
|
||||
|
||||
sb = pulse & 060; /* subopcode */
|
||||
sb = pulse & 060; /* subopcode */
|
||||
if (pulse & 01) {
|
||||
if ((sb == 000) && (rf_sta & (RFS_ERR | RFS_DON)))
|
||||
dat = IOT_SKP | dat; /* DSSF */
|
||||
else if (sb == 020) rf_reset (&rf_dev); /* DSCC */
|
||||
else if (sb == 040) { /* DSCF */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
||||
else rf_sta = rf_sta & ~(RFS_FNC | RFS_IE); } /* clear func */
|
||||
}
|
||||
if ((sb == 000) && (rf_sta & (RFS_ERR | RFS_DON)))
|
||||
dat = IOT_SKP | dat; /* DSSF */
|
||||
else if (sb == 020) rf_reset (&rf_dev); /* DSCC */
|
||||
else if (sb == 040) { /* DSCF */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
||||
else rf_sta = rf_sta & ~(RFS_FNC | RFS_IE); /* clear func */
|
||||
}
|
||||
}
|
||||
if (pulse & 02) {
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||
else if (sb == 000) dat = dat | rf_dbuf; /* DRBR */
|
||||
else if (sb == 020) /* DRAL */
|
||||
dat = dat | (rf_da & DMASK);
|
||||
else if (sb == 040) /* DSFX */
|
||||
rf_sta = rf_sta ^ (dat & (RFS_FNC | RFS_IE)); /* xor func */
|
||||
else if (sb == 060) /* DRAH */
|
||||
dat = dat | (rf_da >> 18) | ((rf_sta & RFS_NED)? 010: 0);
|
||||
}
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||
else if (sb == 000) dat = dat | rf_dbuf; /* DRBR */
|
||||
else if (sb == 020) /* DRAL */
|
||||
dat = dat | (rf_da & DMASK);
|
||||
else if (sb == 040) /* DSFX */
|
||||
rf_sta = rf_sta ^ (dat & (RFS_FNC | RFS_IE)); /* xor func */
|
||||
else if (sb == 060) /* DRAH */
|
||||
dat = dat | (rf_da >> 18) | ((rf_sta & RFS_NED)? 010: 0);
|
||||
}
|
||||
if (pulse & 04) {
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||
else if (sb == 000) rf_dbuf = dat & DMASK; /* DLBR */
|
||||
else if (sb == 020) /* DLAL */
|
||||
rf_da = (rf_da & ~DMASK) | (dat & DMASK);
|
||||
else if (sb == 040) { /* DSCN */
|
||||
rf_sta = rf_sta & ~RFS_DON; /* clear done */
|
||||
if (GET_FNC (rf_sta) != FN_NOP) {
|
||||
t = (rf_da & RF_WMASK) - GET_POS (rf_time); /* delta to new */
|
||||
if (t < 0) t = t + RF_NUMWD; /* wrap around? */
|
||||
sim_activate (&rf_unit, t * rf_time); } } /* schedule op */
|
||||
else if (sb == 060) { /* DLAH */
|
||||
rf_da = (rf_da & DMASK) | ((dat & 07) << 18);
|
||||
if ((uint32) rf_da >= rf_unit.capac) /* for sizing */
|
||||
rf_updsta (RFS_NED); }
|
||||
}
|
||||
rf_updsta (0); /* update status */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||
else if (sb == 000) rf_dbuf = dat & DMASK; /* DLBR */
|
||||
else if (sb == 020) /* DLAL */
|
||||
rf_da = (rf_da & ~DMASK) | (dat & DMASK);
|
||||
else if (sb == 040) { /* DSCN */
|
||||
rf_sta = rf_sta & ~RFS_DON; /* clear done */
|
||||
if (GET_FNC (rf_sta) != FN_NOP) {
|
||||
t = (rf_da & RF_WMASK) - GET_POS (rf_time); /* delta to new */
|
||||
if (t < 0) t = t + RF_NUMWD; /* wrap around? */
|
||||
sim_activate (&rf_unit, t * rf_time); /* schedule op */
|
||||
}
|
||||
}
|
||||
else if (sb == 060) { /* DLAH */
|
||||
rf_da = (rf_da & DMASK) | ((dat & 07) << 18);
|
||||
if ((uint32) rf_da >= rf_unit.capac) /* for sizing */
|
||||
rf_updsta (RFS_NED);
|
||||
}
|
||||
}
|
||||
rf_updsta (0); /* update status */
|
||||
return dat;
|
||||
}
|
||||
|
||||
@@ -224,19 +232,21 @@ int32 rf72 (int32 dev, int32 pulse, int32 dat)
|
||||
int32 sb = pulse & 060;
|
||||
|
||||
if (pulse & 02) {
|
||||
if (sb == 000) dat = dat | GET_POS (rf_time) | /* DLOK */
|
||||
(sim_is_active (&rf_unit)? 0400000: 0);
|
||||
else if (sb == 040) { /* DSCD */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
||||
else rf_sta = 0;
|
||||
rf_updsta (0); }
|
||||
else if (sb == 060) { /* DSRS */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||
dat = dat | rf_updsta (0); }
|
||||
}
|
||||
if (sb == 000) dat = dat | GET_POS (rf_time) | /* DLOK */
|
||||
(sim_is_active (&rf_unit)? 0400000: 0);
|
||||
else if (sb == 040) { /* DSCD */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy inhibits */
|
||||
else rf_sta = 0;
|
||||
rf_updsta (0);
|
||||
}
|
||||
else if (sb == 060) { /* DSRS */
|
||||
if (RF_BUSY) rf_sta = rf_sta | RFS_PGE; /* busy sets PGE */
|
||||
dat = dat | rf_updsta (0);
|
||||
}
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
|
||||
/* Unit service - assumes the entire disk is buffered */
|
||||
|
||||
t_stat rf_svc (UNIT *uptr)
|
||||
@@ -244,40 +254,46 @@ t_stat rf_svc (UNIT *uptr)
|
||||
int32 f, pa, d, t;
|
||||
int32 *fbuf = uptr->filebuf;
|
||||
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
rf_updsta (RFS_NED | RFS_DON); /* set nxd, done */
|
||||
return IORETURN (rf_stopioe, SCPE_UNATT); }
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
rf_updsta (RFS_NED | RFS_DON); /* set nxd, done */
|
||||
return IORETURN (rf_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
f = GET_FNC (rf_sta); /* get function */
|
||||
do { if ((uint32) rf_da >= uptr->capac) { /* disk overflow? */
|
||||
rf_updsta (RFS_NED); /* nx disk error */
|
||||
break; }
|
||||
M[RF_WC] = (M[RF_WC] + 1) & DMASK; /* incr word count */
|
||||
pa = M[RF_CA] = (M[RF_CA] + 1) & AMASK; /* incr mem addr */
|
||||
if ((f == FN_READ) && MEM_ADDR_OK (pa)) /* read? */
|
||||
M[pa] = fbuf[rf_da];
|
||||
if ((f == FN_WCHK) && (M[pa] != fbuf[rf_da])) { /* write check? */
|
||||
rf_updsta (RFS_WCE); /* flag error */
|
||||
break; }
|
||||
if (f == FN_WRITE) { /* write? */
|
||||
d = (rf_da >> 18) & 07; /* disk */
|
||||
t = (rf_da >> 14) & 017; /* track groups */
|
||||
if ((rf_wlk[d] >> t) & 1) { /* write locked? */
|
||||
rf_updsta (RFS_WLO);
|
||||
break; }
|
||||
else { /* not locked */
|
||||
fbuf[rf_da] = M[pa]; /* write word */
|
||||
if (((uint32) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1; } }
|
||||
rf_da = rf_da + 1; /* incr disk addr */
|
||||
}
|
||||
while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */
|
||||
f = GET_FNC (rf_sta); /* get function */
|
||||
do {
|
||||
if ((uint32) rf_da >= uptr->capac) { /* disk overflow? */
|
||||
rf_updsta (RFS_NED); /* nx disk error */
|
||||
break;
|
||||
}
|
||||
M[RF_WC] = (M[RF_WC] + 1) & DMASK; /* incr word count */
|
||||
pa = M[RF_CA] = (M[RF_CA] + 1) & AMASK; /* incr mem addr */
|
||||
if ((f == FN_READ) && MEM_ADDR_OK (pa)) /* read? */
|
||||
M[pa] = fbuf[rf_da];
|
||||
if ((f == FN_WCHK) && (M[pa] != fbuf[rf_da])) { /* write check? */
|
||||
rf_updsta (RFS_WCE); /* flag error */
|
||||
break;
|
||||
}
|
||||
if (f == FN_WRITE) { /* write? */
|
||||
d = (rf_da >> 18) & 07; /* disk */
|
||||
t = (rf_da >> 14) & 017; /* track groups */
|
||||
if ((rf_wlk[d] >> t) & 1) { /* write locked? */
|
||||
rf_updsta (RFS_WLO);
|
||||
break;
|
||||
}
|
||||
else { /* not locked */
|
||||
fbuf[rf_da] = M[pa]; /* write word */
|
||||
if (((uint32) rf_da) >= uptr->hwmark) uptr->hwmark = rf_da + 1;
|
||||
}
|
||||
}
|
||||
rf_da = rf_da + 1; /* incr disk addr */
|
||||
} while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */
|
||||
|
||||
if ((M[RF_WC] != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */
|
||||
sim_activate (&rf_unit, rf_time); /* sched next */
|
||||
if ((M[RF_WC] != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */
|
||||
sim_activate (&rf_unit, rf_time); /* sched next */
|
||||
else rf_updsta (RFS_DON);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Update status */
|
||||
|
||||
int32 rf_updsta (int32 new)
|
||||
@@ -285,7 +301,7 @@ int32 rf_updsta (int32 new)
|
||||
rf_sta = (rf_sta | new) & ~(RFS_ERR | RFS_CLR);
|
||||
if (rf_sta & RFS_EFLGS) rf_sta = rf_sta | RFS_ERR;
|
||||
if ((rf_sta & (RFS_ERR | RFS_DON)) && (rf_sta & RFS_IE))
|
||||
SET_INT (RF);
|
||||
SET_INT (RF);
|
||||
else CLR_INT (RF);
|
||||
return rf_sta;
|
||||
}
|
||||
@@ -318,10 +334,11 @@ t_stat r;
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (p >= RF_NUMDK) p = RF_NUMDK - 1;
|
||||
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
|
||||
(p << UNIT_V_PLAT); }
|
||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (p >= RF_NUMDK) p = RF_NUMDK - 1;
|
||||
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
|
||||
(p << UNIT_V_PLAT);
|
||||
}
|
||||
uptr->capac = UNIT_GETP (uptr->flags) * RF_DKSIZE;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp18b_rp.c: RP15/RP02 disk pack simulator
|
||||
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,130 +19,130 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
rp RP15/RP02 disk pack
|
||||
rp RP15/RP02 disk pack
|
||||
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
06-Feb-03 RMS Revised IOT decoding, fixed bug in initiation
|
||||
05-Oct-02 RMS Added DIB, device number support
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
29-Nov-01 RMS Added read only unit support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
Changed FLG to array
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
29-Jun-96 RMS Added unit enable/disable support
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
06-Feb-03 RMS Revised IOT decoding, fixed bug in initiation
|
||||
05-Oct-02 RMS Added DIB, device number support
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
29-Nov-01 RMS Added read only unit support
|
||||
25-Nov-01 RMS Revised interrupt structure
|
||||
Changed FLG to array
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
29-Jun-96 RMS Added unit enable/disable support
|
||||
*/
|
||||
|
||||
#include "pdp18b_defs.h"
|
||||
|
||||
/* Constants */
|
||||
|
||||
#define RP_NUMWD 256 /* words/sector */
|
||||
#define RP_NUMSC 10 /* sectors/surface */
|
||||
#define RP_NUMSF 20 /* surfaces/cylinder */
|
||||
#define RP_NUMCY 203 /* cylinders/drive */
|
||||
#define RP_NUMDR 8 /* drives/controller */
|
||||
#define RP_NUMWD 256 /* words/sector */
|
||||
#define RP_NUMSC 10 /* sectors/surface */
|
||||
#define RP_NUMSF 20 /* surfaces/cylinder */
|
||||
#define RP_NUMCY 203 /* cylinders/drive */
|
||||
#define RP_NUMDR 8 /* drives/controller */
|
||||
#define RP_SIZE (RP_NUMCY * RP_NUMSF * RP_NUMSC * RP_NUMWD) /* words/drive */
|
||||
|
||||
/* Unit specific flags */
|
||||
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* hwre write lock */
|
||||
#define UNIT_WLK (1u << UNIT_V_WLK)
|
||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* hwre write lock */
|
||||
#define UNIT_WLK (1u << UNIT_V_WLK)
|
||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
||||
|
||||
/* Parameters in the unit descriptor */
|
||||
|
||||
#define CYL u3 /* current cylinder */
|
||||
#define FUNC u4 /* function */
|
||||
#define CYL u3 /* current cylinder */
|
||||
#define FUNC u4 /* function */
|
||||
|
||||
/* Status register A */
|
||||
|
||||
#define STA_V_UNIT 15 /* unit select */
|
||||
#define STA_M_UNIT 07
|
||||
#define STA_V_FUNC 12 /* function */
|
||||
#define STA_M_FUNC 07
|
||||
#define FN_IDLE 0
|
||||
#define FN_READ 1
|
||||
#define FN_WRITE 2
|
||||
#define FN_RECAL 3
|
||||
#define FN_SEEK 4
|
||||
#define FN_RDALL 5
|
||||
#define FN_WRALL 6
|
||||
#define FN_WRCHK 7
|
||||
#define FN_2ND 010 /* second state flag */
|
||||
#define STA_IED 0004000 /* int enable done */
|
||||
#define STA_IEA 0002000 /* int enable attn */
|
||||
#define STA_GO 0001000 /* go */
|
||||
#define STA_WPE 0000400 /* write lock error */
|
||||
#define STA_NXC 0000200 /* nx cyl error */
|
||||
#define STA_NXF 0000100 /* nx surface error */
|
||||
#define STA_NXS 0000040 /* nx sector error */
|
||||
#define STA_HNF 0000020 /* hdr not found */
|
||||
#define STA_SUWP 0000010 /* sel unit wrt lock */
|
||||
#define STA_SUSI 0000004 /* sel unit seek inc */
|
||||
#define STA_DON 0000002 /* done */
|
||||
#define STA_ERR 0000001 /* error */
|
||||
#define STA_V_UNIT 15 /* unit select */
|
||||
#define STA_M_UNIT 07
|
||||
#define STA_V_FUNC 12 /* function */
|
||||
#define STA_M_FUNC 07
|
||||
#define FN_IDLE 0
|
||||
#define FN_READ 1
|
||||
#define FN_WRITE 2
|
||||
#define FN_RECAL 3
|
||||
#define FN_SEEK 4
|
||||
#define FN_RDALL 5
|
||||
#define FN_WRALL 6
|
||||
#define FN_WRCHK 7
|
||||
#define FN_2ND 010 /* second state flag */
|
||||
#define STA_IED 0004000 /* int enable done */
|
||||
#define STA_IEA 0002000 /* int enable attn */
|
||||
#define STA_GO 0001000 /* go */
|
||||
#define STA_WPE 0000400 /* write lock error */
|
||||
#define STA_NXC 0000200 /* nx cyl error */
|
||||
#define STA_NXF 0000100 /* nx surface error */
|
||||
#define STA_NXS 0000040 /* nx sector error */
|
||||
#define STA_HNF 0000020 /* hdr not found */
|
||||
#define STA_SUWP 0000010 /* sel unit wrt lock */
|
||||
#define STA_SUSI 0000004 /* sel unit seek inc */
|
||||
#define STA_DON 0000002 /* done */
|
||||
#define STA_ERR 0000001 /* error */
|
||||
|
||||
#define STA_RW 0777000 /* read/write */
|
||||
#define STA_EFLGS (STA_WPE | STA_NXC | STA_NXF | STA_NXS | \
|
||||
STA_HNF | STA_SUSI) /* error flags */
|
||||
#define STA_DYN (STA_SUWP | STA_SUSI) /* per unit status */
|
||||
#define GET_UNIT(x) (((x) >> STA_V_UNIT) & STA_M_UNIT)
|
||||
#define GET_FUNC(x) (((x) >> STA_V_FUNC) & STA_M_FUNC)
|
||||
#define STA_RW 0777000 /* read/write */
|
||||
#define STA_EFLGS (STA_WPE | STA_NXC | STA_NXF | STA_NXS | \
|
||||
STA_HNF | STA_SUSI) /* error flags */
|
||||
#define STA_DYN (STA_SUWP | STA_SUSI) /* per unit status */
|
||||
#define GET_UNIT(x) (((x) >> STA_V_UNIT) & STA_M_UNIT)
|
||||
#define GET_FUNC(x) (((x) >> STA_V_FUNC) & STA_M_FUNC)
|
||||
|
||||
/* Status register B */
|
||||
|
||||
#define STB_V_ATT0 17 /* unit 0 attention */
|
||||
#define STB_ATTN 0776000 /* attention flags */
|
||||
#define STB_SUFU 0001000 /* sel unit unsafe */
|
||||
#define STB_PGE 0000400 /* programming error */
|
||||
#define STB_EOP 0000200 /* end of pack */
|
||||
#define STB_TME 0000100 /* timing error */
|
||||
#define STB_FME 0000040 /* format error */
|
||||
#define STB_WCE 0000020 /* write check error */
|
||||
#define STB_WPE 0000010 /* word parity error */
|
||||
#define STB_LON 0000004 /* long parity error */
|
||||
#define STB_SUSU 0000002 /* sel unit seeking */
|
||||
#define STB_SUNR 0000001 /* sel unit not rdy */
|
||||
#define STB_V_ATT0 17 /* unit 0 attention */
|
||||
#define STB_ATTN 0776000 /* attention flags */
|
||||
#define STB_SUFU 0001000 /* sel unit unsafe */
|
||||
#define STB_PGE 0000400 /* programming error */
|
||||
#define STB_EOP 0000200 /* end of pack */
|
||||
#define STB_TME 0000100 /* timing error */
|
||||
#define STB_FME 0000040 /* format error */
|
||||
#define STB_WCE 0000020 /* write check error */
|
||||
#define STB_WPE 0000010 /* word parity error */
|
||||
#define STB_LON 0000004 /* long parity error */
|
||||
#define STB_SUSU 0000002 /* sel unit seeking */
|
||||
#define STB_SUNR 0000001 /* sel unit not rdy */
|
||||
|
||||
#define STB_EFLGS (STB_SUFU | STB_PGE | STB_EOP | STB_TME | STB_FME | \
|
||||
STB_WCE | STB_WPE | STB_LON ) /* error flags */
|
||||
#define STB_DYN (STB_SUFU | STB_SUSU | STB_SUNR) /* per unit */
|
||||
#define STB_EFLGS (STB_SUFU | STB_PGE | STB_EOP | STB_TME | STB_FME | \
|
||||
STB_WCE | STB_WPE | STB_LON ) /* error flags */
|
||||
#define STB_DYN (STB_SUFU | STB_SUSU | STB_SUNR) /* per unit */
|
||||
|
||||
/* Disk address */
|
||||
|
||||
#define DA_V_SECT 0 /* sector */
|
||||
#define DA_M_SECT 017
|
||||
#define DA_V_SURF 5
|
||||
#define DA_M_SURF 037
|
||||
#define DA_V_CYL 10 /* cylinder */
|
||||
#define DA_M_CYL 0377
|
||||
#define GET_SECT(x) (((x) >> DA_V_SECT) & DA_M_SECT)
|
||||
#define GET_SURF(x) (((x) >> DA_V_SURF) & DA_M_SURF)
|
||||
#define GET_CYL(x) (((x) >> DA_V_CYL) & DA_M_CYL)
|
||||
#define GET_DA(x) ((((GET_CYL (x) * RP_NUMSF) + GET_SURF (x)) * \
|
||||
RP_NUMSC) + GET_SECT (x))
|
||||
#define DA_V_SECT 0 /* sector */
|
||||
#define DA_M_SECT 017
|
||||
#define DA_V_SURF 5
|
||||
#define DA_M_SURF 037
|
||||
#define DA_V_CYL 10 /* cylinder */
|
||||
#define DA_M_CYL 0377
|
||||
#define GET_SECT(x) (((x) >> DA_V_SECT) & DA_M_SECT)
|
||||
#define GET_SURF(x) (((x) >> DA_V_SURF) & DA_M_SURF)
|
||||
#define GET_CYL(x) (((x) >> DA_V_CYL) & DA_M_CYL)
|
||||
#define GET_DA(x) ((((GET_CYL (x) * RP_NUMSF) + GET_SURF (x)) * \
|
||||
RP_NUMSC) + GET_SECT (x))
|
||||
|
||||
#define RP_MIN 2
|
||||
#define MAX(x,y) (((x) > (y))? (x): (y))
|
||||
|
||||
|
||||
extern int32 M[];
|
||||
extern int32 int_hwre[API_HLVL+1], nexm;
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
int32 rp_sta = 0; /* status A */
|
||||
int32 rp_stb = 0; /* status B */
|
||||
int32 rp_ma = 0; /* memory address */
|
||||
int32 rp_da = 0; /* disk address */
|
||||
int32 rp_wc = 0; /* word count */
|
||||
int32 rp_busy = 0; /* busy */
|
||||
int32 rp_stopioe = 1; /* stop on error */
|
||||
int32 rp_swait = 10; /* seek time */
|
||||
int32 rp_rwait = 10; /* rotate time */
|
||||
int32 rp_sta = 0; /* status A */
|
||||
int32 rp_stb = 0; /* status B */
|
||||
int32 rp_ma = 0; /* memory address */
|
||||
int32 rp_da = 0; /* disk address */
|
||||
int32 rp_wc = 0; /* word count */
|
||||
int32 rp_busy = 0; /* busy */
|
||||
int32 rp_stopioe = 1; /* stop on error */
|
||||
int32 rp_swait = 10; /* seek time */
|
||||
int32 rp_rwait = 10; /* rotate time */
|
||||
|
||||
DEVICE rp_dev;
|
||||
int32 rp63 (int32 dev, int32 pulse, int32 dat);
|
||||
@@ -156,93 +156,100 @@ t_stat rp_detach (UNIT *uptr);
|
||||
|
||||
/* RP15 data structures
|
||||
|
||||
rp_dev RP device descriptor
|
||||
rp_unit RP unit list
|
||||
rp_reg RP register list
|
||||
rp_mod RP modifier list
|
||||
rp_dev RP device descriptor
|
||||
rp_unit RP unit list
|
||||
rp_reg RP register list
|
||||
rp_mod RP modifier list
|
||||
*/
|
||||
|
||||
DIB rp_dib = { DEV_RP, 2, &rp_iors, { &rp63, &rp64 } };
|
||||
|
||||
UNIT rp_unit[] = {
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) } };
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) },
|
||||
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, RP_SIZE) }
|
||||
};
|
||||
|
||||
REG rp_reg[] = {
|
||||
{ ORDATA (STA, rp_sta, 18) },
|
||||
{ ORDATA (STB, rp_stb, 18) },
|
||||
{ ORDATA (DA, rp_da, 18) },
|
||||
{ ORDATA (MA, rp_ma, 18) },
|
||||
{ ORDATA (WC, rp_wc, 18) },
|
||||
{ FLDATA (INT, int_hwre[API_RP], INT_V_RP) },
|
||||
{ FLDATA (BUSY, rp_busy, 0) },
|
||||
{ FLDATA (STOP_IOE, rp_stopioe, 0) },
|
||||
{ DRDATA (STIME, rp_swait, 24), PV_LEFT },
|
||||
{ DRDATA (RTIME, rp_rwait, 24), PV_LEFT },
|
||||
{ ORDATA (DEVNO, rp_dib.dev, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
{ ORDATA (STA, rp_sta, 18) },
|
||||
{ ORDATA (STB, rp_stb, 18) },
|
||||
{ ORDATA (DA, rp_da, 18) },
|
||||
{ ORDATA (MA, rp_ma, 18) },
|
||||
{ ORDATA (WC, rp_wc, 18) },
|
||||
{ FLDATA (INT, int_hwre[API_RP], INT_V_RP) },
|
||||
{ FLDATA (BUSY, rp_busy, 0) },
|
||||
{ FLDATA (STOP_IOE, rp_stopioe, 0) },
|
||||
{ DRDATA (STIME, rp_swait, 24), PV_LEFT },
|
||||
{ DRDATA (RTIME, rp_rwait, 24), PV_LEFT },
|
||||
{ ORDATA (DEVNO, rp_dib.dev, 6), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB rp_mod[] = {
|
||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 } };
|
||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE rp_dev = {
|
||||
"RP", rp_unit, rp_reg, rp_mod,
|
||||
RP_NUMDR, 8, 24, 1, 8, 18,
|
||||
NULL, NULL, &rp_reset,
|
||||
NULL, &rp_attach, &rp_detach,
|
||||
&rp_dib, DEV_DISABLE };
|
||||
|
||||
"RP", rp_unit, rp_reg, rp_mod,
|
||||
RP_NUMDR, 8, 24, 1, 8, 18,
|
||||
NULL, NULL, &rp_reset,
|
||||
NULL, &rp_attach, &rp_detach,
|
||||
&rp_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* IOT routines */
|
||||
|
||||
int32 rp63 (int32 dev, int32 pulse, int32 dat)
|
||||
{
|
||||
int32 sb = pulse & 060; /* subopcode */
|
||||
int32 sb = pulse & 060; /* subopcode */
|
||||
|
||||
rp_updsta (0, 0);
|
||||
if (pulse & 01) {
|
||||
if ((sb == 000) && /* DPSF */
|
||||
((rp_sta & (STA_DON | STA_ERR)) || (rp_stb & STB_ATTN)))
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 020) && (rp_stb & STB_ATTN)) /* DPSA */
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 040) && (rp_sta & STA_DON)) /* DPSJ */
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 060) && (rp_sta & STA_ERR)) /* DPSE */
|
||||
dat = IOT_SKP | dat;
|
||||
}
|
||||
if ((sb == 000) && /* DPSF */
|
||||
((rp_sta & (STA_DON | STA_ERR)) || (rp_stb & STB_ATTN)))
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 020) && (rp_stb & STB_ATTN)) /* DPSA */
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 040) && (rp_sta & STA_DON)) /* DPSJ */
|
||||
dat = IOT_SKP | dat;
|
||||
else if ((sb == 060) && (rp_sta & STA_ERR)) /* DPSE */
|
||||
dat = IOT_SKP | dat;
|
||||
}
|
||||
if (pulse & 02) {
|
||||
if (sb == 000) dat = dat | rp_sta; /* DPOSA */
|
||||
else if (sb == 020) dat = dat | rp_stb; /* DPOSB */
|
||||
}
|
||||
if (sb == 000) dat = dat | rp_sta; /* DPOSA */
|
||||
else if (sb == 020) dat = dat | rp_stb; /* DPOSB */
|
||||
}
|
||||
if (pulse & 04) {
|
||||
if (rp_busy) { /* busy? */
|
||||
rp_updsta (0, STB_PGE);
|
||||
return dat; }
|
||||
else if (sb == 000) { /* DPLA */
|
||||
rp_da = dat & DMASK;
|
||||
if (GET_SECT (rp_da) >= RP_NUMSC) rp_updsta (STA_NXS, 0);
|
||||
if (GET_SURF (rp_da) >= RP_NUMSF) rp_updsta (STA_NXF, 0);
|
||||
if (GET_CYL (rp_da) >= RP_NUMCY) rp_updsta (STA_NXC, 0); }
|
||||
else if (sb == 020) { /* DPCS */
|
||||
rp_sta = rp_sta & ~(STA_HNF | STA_DON);
|
||||
rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE |
|
||||
STB_TME | STB_PGE | STB_EOP);
|
||||
rp_updsta (0, 0); }
|
||||
else if (sb == 040) rp_ma = dat & DMASK; /* DPCA */
|
||||
else if (sb == 060) rp_wc = dat & DMASK; /* DPWC */
|
||||
}
|
||||
if (rp_busy) { /* busy? */
|
||||
rp_updsta (0, STB_PGE);
|
||||
return dat;
|
||||
}
|
||||
else if (sb == 000) { /* DPLA */
|
||||
rp_da = dat & DMASK;
|
||||
if (GET_SECT (rp_da) >= RP_NUMSC) rp_updsta (STA_NXS, 0);
|
||||
if (GET_SURF (rp_da) >= RP_NUMSF) rp_updsta (STA_NXF, 0);
|
||||
if (GET_CYL (rp_da) >= RP_NUMCY) rp_updsta (STA_NXC, 0);
|
||||
}
|
||||
else if (sb == 020) { /* DPCS */
|
||||
rp_sta = rp_sta & ~(STA_HNF | STA_DON);
|
||||
rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE |
|
||||
STB_TME | STB_PGE | STB_EOP);
|
||||
rp_updsta (0, 0);
|
||||
}
|
||||
else if (sb == 040) rp_ma = dat & DMASK; /* DPCA */
|
||||
else if (sb == 060) rp_wc = dat & DMASK; /* DPWC */
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
|
||||
/* IOT 64 */
|
||||
|
||||
int32 rp64 (int32 dev, int32 pulse, int32 dat)
|
||||
@@ -252,49 +259,52 @@ UNIT *uptr;
|
||||
|
||||
sb = pulse & 060;
|
||||
if (pulse & 01) {
|
||||
if (sb == 020) dat = IOT_SKP | dat; /* DPSN */
|
||||
}
|
||||
if (sb == 020) dat = IOT_SKP | dat; /* DPSN */
|
||||
}
|
||||
if (pulse & 02) {
|
||||
if (sb == 000) dat = dat | rp_unit[GET_UNIT (rp_sta)].CYL; /* DPOU */
|
||||
else if (sb == 020) dat = dat | rp_da; /* DPOA */
|
||||
else if (sb == 040) dat = dat | rp_ma; /* DPOC */
|
||||
else if (sb == 060) dat = dat | rp_wc; /* DPOW */
|
||||
}
|
||||
if (sb == 000) dat = dat | rp_unit[GET_UNIT (rp_sta)].CYL; /* DPOU */
|
||||
else if (sb == 020) dat = dat | rp_da; /* DPOA */
|
||||
else if (sb == 040) dat = dat | rp_ma; /* DPOC */
|
||||
else if (sb == 060) dat = dat | rp_wc; /* DPOW */
|
||||
}
|
||||
if (pulse & 04) {
|
||||
if (rp_busy) { /* busy? */
|
||||
rp_updsta (0, STB_PGE);
|
||||
return dat; }
|
||||
if (sb == 000) rp_sta = rp_sta & ~STA_RW; /* DPCF */
|
||||
else if (sb == 020) rp_sta = rp_sta & (dat | ~STA_RW); /* DPLZ */
|
||||
else if (sb == 040) rp_sta = rp_sta | (dat & STA_RW); /* DPLO */
|
||||
else if (sb == 060) /* DPLF */
|
||||
rp_sta = (rp_sta & ~STA_RW) | (dat & STA_RW);
|
||||
rp_sta = rp_sta & ~STA_DON; /* clear done */
|
||||
u = GET_UNIT (rp_sta); /* get unit num */
|
||||
uptr = rp_dev.units + u; /* select unit */
|
||||
if ((rp_sta & STA_GO) && !sim_is_active (uptr)) {
|
||||
f = uptr->FUNC = GET_FUNC (rp_sta); /* get function */
|
||||
rp_busy = 1; /* set ctrl busy */
|
||||
rp_sta = rp_sta & ~(STA_HNF | STA_DON); /* clear flags */
|
||||
rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE |
|
||||
STB_TME | STB_PGE | STB_EOP | (1 << (STB_V_ATT0 - u)));
|
||||
if (((uptr->flags & UNIT_ATT) == 0) || (f == FN_IDLE) ||
|
||||
(f == FN_SEEK) || (f == FN_RECAL))
|
||||
sim_activate (uptr, RP_MIN); /* short delay */
|
||||
else {
|
||||
c = GET_CYL (rp_da);
|
||||
c = abs (c - uptr->CYL) * rp_swait; /* seek time */
|
||||
sim_activate (uptr, MAX (RP_MIN, c + rp_rwait)); } }
|
||||
}
|
||||
if (rp_busy) { /* busy? */
|
||||
rp_updsta (0, STB_PGE);
|
||||
return dat;
|
||||
}
|
||||
if (sb == 000) rp_sta = rp_sta & ~STA_RW; /* DPCF */
|
||||
else if (sb == 020) rp_sta = rp_sta & (dat | ~STA_RW); /* DPLZ */
|
||||
else if (sb == 040) rp_sta = rp_sta | (dat & STA_RW); /* DPLO */
|
||||
else if (sb == 060) /* DPLF */
|
||||
rp_sta = (rp_sta & ~STA_RW) | (dat & STA_RW);
|
||||
rp_sta = rp_sta & ~STA_DON; /* clear done */
|
||||
u = GET_UNIT (rp_sta); /* get unit num */
|
||||
uptr = rp_dev.units + u; /* select unit */
|
||||
if ((rp_sta & STA_GO) && !sim_is_active (uptr)) {
|
||||
f = uptr->FUNC = GET_FUNC (rp_sta); /* get function */
|
||||
rp_busy = 1; /* set ctrl busy */
|
||||
rp_sta = rp_sta & ~(STA_HNF | STA_DON); /* clear flags */
|
||||
rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE |
|
||||
STB_TME | STB_PGE | STB_EOP | (1 << (STB_V_ATT0 - u)));
|
||||
if (((uptr->flags & UNIT_ATT) == 0) || (f == FN_IDLE) ||
|
||||
(f == FN_SEEK) || (f == FN_RECAL))
|
||||
sim_activate (uptr, RP_MIN); /* short delay */
|
||||
else {
|
||||
c = GET_CYL (rp_da);
|
||||
c = abs (c - uptr->CYL) * rp_swait; /* seek time */
|
||||
sim_activate (uptr, MAX (RP_MIN, c + rp_rwait));
|
||||
}
|
||||
}
|
||||
}
|
||||
rp_updsta (0, 0);
|
||||
return dat;
|
||||
}
|
||||
|
||||
|
||||
/* Unit service
|
||||
|
||||
If function = idle, clear busy
|
||||
If seek or recal initial state, clear attention line, compute seek time,
|
||||
put on cylinder, set second state
|
||||
put on cylinder, set second state
|
||||
If unit not attached, give error
|
||||
If seek or recal second state, set attention line, compute errors
|
||||
Else complete data transfer command
|
||||
@@ -309,86 +319,100 @@ t_stat rp_svc (UNIT *uptr)
|
||||
int32 f, u, comp, cyl, sect, surf;
|
||||
int32 err, pa, da, wc, awc, i;
|
||||
|
||||
u = uptr - rp_dev.units; /* get drv number */
|
||||
f = uptr->FUNC; /* get function */
|
||||
if (f == FN_IDLE) { /* idle? */
|
||||
rp_busy = 0; /* clear busy */
|
||||
return SCPE_OK; }
|
||||
u = (int32) (uptr - rp_dev.units); /* get drv number */
|
||||
f = uptr->FUNC; /* get function */
|
||||
if (f == FN_IDLE) { /* idle? */
|
||||
rp_busy = 0; /* clear busy */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if ((f == FN_SEEK) || (f == FN_RECAL)) { /* seek or recal? */
|
||||
rp_busy = 0; /* not busy */
|
||||
cyl = (f == FN_SEEK)? GET_CYL (rp_da): 0; /* get cylinder */
|
||||
sim_activate (uptr, MAX (RP_MIN, abs (cyl - uptr->CYL) * rp_swait));
|
||||
uptr->CYL = cyl; /* on cylinder */
|
||||
uptr->FUNC = FN_SEEK | FN_2ND; /* set second state */
|
||||
rp_updsta (0, 0); /* update status */
|
||||
return SCPE_OK; }
|
||||
if ((f == FN_SEEK) || (f == FN_RECAL)) { /* seek or recal? */
|
||||
rp_busy = 0; /* not busy */
|
||||
cyl = (f == FN_SEEK)? GET_CYL (rp_da): 0; /* get cylinder */
|
||||
sim_activate (uptr, MAX (RP_MIN, abs (cyl - uptr->CYL) * rp_swait));
|
||||
uptr->CYL = cyl; /* on cylinder */
|
||||
uptr->FUNC = FN_SEEK | FN_2ND; /* set second state */
|
||||
rp_updsta (0, 0); /* update status */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (f == (FN_SEEK | FN_2ND)) { /* seek done? */
|
||||
rp_updsta (0, rp_stb | (1 << (STB_V_ATT0 - u))); /* set attention */
|
||||
return SCPE_OK; }
|
||||
if (f == (FN_SEEK | FN_2ND)) { /* seek done? */
|
||||
rp_updsta (0, rp_stb | (1 << (STB_V_ATT0 - u))); /* set attention */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
rp_updsta (STA_DON, STB_SUFU); /* done, unsafe */
|
||||
return IORETURN (rp_stopioe, SCPE_UNATT); }
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
rp_updsta (STA_DON, STB_SUFU); /* done, unsafe */
|
||||
return IORETURN (rp_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
if ((f == FN_WRITE) && (uptr->flags & UNIT_WPRT)) { /* write locked? */
|
||||
rp_updsta (STA_DON | STA_WPE, 0); /* error */
|
||||
return SCPE_OK; }
|
||||
if ((f == FN_WRITE) && (uptr->flags & UNIT_WPRT)) { /* write locked? */
|
||||
rp_updsta (STA_DON | STA_WPE, 0); /* error */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (GET_SECT (rp_da) >= RP_NUMSC) rp_updsta (STA_NXS, 0);
|
||||
if (GET_SURF (rp_da) >= RP_NUMSF) rp_updsta (STA_NXF, 0);
|
||||
if (GET_CYL (rp_da) >= RP_NUMCY) rp_updsta (STA_NXC, 0);
|
||||
if (rp_sta & (STA_NXS | STA_NXF | STA_NXC)) { /* or bad disk addr? */
|
||||
rp_updsta (STA_DON, STB_SUFU); /* done, unsafe */
|
||||
return SCPE_OK; }
|
||||
if (rp_sta & (STA_NXS | STA_NXF | STA_NXC)) { /* or bad disk addr? */
|
||||
rp_updsta (STA_DON, STB_SUFU); /* done, unsafe */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
pa = rp_ma & AMASK; /* get mem addr */
|
||||
da = GET_DA (rp_da) * RP_NUMWD; /* get disk addr */
|
||||
wc = 01000000 - rp_wc; /* get true wc */
|
||||
if (((uint32) (pa + wc)) > MEMSIZE) { /* memory overrun? */
|
||||
nexm = 1; /* set nexm flag */
|
||||
wc = MEMSIZE - pa; } /* limit xfer */
|
||||
if ((da + wc) > RP_SIZE) { /* disk overrun? */
|
||||
rp_updsta (0, STB_EOP); /* error */
|
||||
wc = RP_SIZE - da; } /* limit xfer */
|
||||
pa = rp_ma & AMASK; /* get mem addr */
|
||||
da = GET_DA (rp_da) * RP_NUMWD; /* get disk addr */
|
||||
wc = 01000000 - rp_wc; /* get true wc */
|
||||
if (((uint32) (pa + wc)) > MEMSIZE) { /* memory overrun? */
|
||||
nexm = 1; /* set nexm flag */
|
||||
wc = MEMSIZE - pa; /* limit xfer */
|
||||
}
|
||||
if ((da + wc) > RP_SIZE) { /* disk overrun? */
|
||||
rp_updsta (0, STB_EOP); /* error */
|
||||
wc = RP_SIZE - da; /* limit xfer */
|
||||
}
|
||||
|
||||
err = fseek (uptr->fileref, da * sizeof (int), SEEK_SET);
|
||||
|
||||
if ((f == FN_READ) && (err == 0)) { /* read? */
|
||||
awc = fxread (&M[pa], sizeof (int32), wc, uptr->fileref);
|
||||
for ( ; awc < wc; awc++) M[pa + awc] = 0;
|
||||
err = ferror (uptr->fileref); }
|
||||
if ((f == FN_READ) && (err == 0)) { /* read? */
|
||||
awc = fxread (&M[pa], sizeof (int32), wc, uptr->fileref);
|
||||
for ( ; awc < wc; awc++) M[pa + awc] = 0;
|
||||
err = ferror (uptr->fileref);
|
||||
}
|
||||
|
||||
if ((f == FN_WRITE) && (err == 0)) { /* write? */
|
||||
fxwrite (&M[pa], sizeof (int32), wc, uptr->fileref);
|
||||
err = ferror (uptr->fileref);
|
||||
if ((err == 0) && (i = (wc & (RP_NUMWD - 1)))) {
|
||||
fxwrite (fill, sizeof (int), i, uptr->fileref);
|
||||
err = ferror (uptr->fileref); } }
|
||||
if ((f == FN_WRITE) && (err == 0)) { /* write? */
|
||||
fxwrite (&M[pa], sizeof (int32), wc, uptr->fileref);
|
||||
err = ferror (uptr->fileref);
|
||||
if ((err == 0) && (i = (wc & (RP_NUMWD - 1)))) {
|
||||
fxwrite (fill, sizeof (int), i, uptr->fileref);
|
||||
err = ferror (uptr->fileref);
|
||||
}
|
||||
}
|
||||
|
||||
if ((f == FN_WRCHK) && (err == 0)) { /* write check? */
|
||||
for (i = 0; (err == 0) && (i < wc); i++) {
|
||||
awc = fxread (&comp, sizeof (int32), 1, uptr->fileref);
|
||||
if (awc == 0) comp = 0;
|
||||
if (comp != M[pa + i]) rp_updsta (0, STB_WCE); }
|
||||
err = ferror (uptr->fileref); }
|
||||
if ((f == FN_WRCHK) && (err == 0)) { /* write check? */
|
||||
for (i = 0; (err == 0) && (i < wc); i++) {
|
||||
awc = fxread (&comp, sizeof (int32), 1, uptr->fileref);
|
||||
if (awc == 0) comp = 0;
|
||||
if (comp != M[pa + i]) rp_updsta (0, STB_WCE);
|
||||
}
|
||||
err = ferror (uptr->fileref);
|
||||
}
|
||||
|
||||
rp_wc = (rp_wc + wc) & DMASK; /* final word count */
|
||||
rp_ma = (rp_ma + wc) & DMASK; /* final mem addr */
|
||||
da = (da + wc + (RP_NUMWD - 1)) / RP_NUMWD; /* final sector num */
|
||||
cyl = da / (RP_NUMSC * RP_NUMSF); /* get cyl */
|
||||
rp_wc = (rp_wc + wc) & DMASK; /* final word count */
|
||||
rp_ma = (rp_ma + wc) & DMASK; /* final mem addr */
|
||||
da = (da + wc + (RP_NUMWD - 1)) / RP_NUMWD; /* final sector num */
|
||||
cyl = da / (RP_NUMSC * RP_NUMSF); /* get cyl */
|
||||
if (cyl >= RP_NUMCY) cyl = RP_NUMCY - 1;
|
||||
surf = (da % (RP_NUMSC * RP_NUMSF)) / RP_NUMSC; /* get surface */
|
||||
sect = (da % (RP_NUMSC * RP_NUMSF)) % RP_NUMSC; /* get sector */
|
||||
surf = (da % (RP_NUMSC * RP_NUMSF)) / RP_NUMSC; /* get surface */
|
||||
sect = (da % (RP_NUMSC * RP_NUMSF)) % RP_NUMSC; /* get sector */
|
||||
rp_da = (cyl << DA_V_CYL) | (surf << DA_V_SURF) | (sect << DA_V_SECT);
|
||||
rp_busy = 0; /* clear busy */
|
||||
rp_updsta (STA_DON, 0); /* set done */
|
||||
rp_busy = 0; /* clear busy */
|
||||
rp_updsta (STA_DON, 0); /* set done */
|
||||
|
||||
if (err != 0) { /* error? */
|
||||
perror ("RP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return IORETURN (rp_stopioe, SCPE_IOERR); }
|
||||
if (err != 0) { /* error? */
|
||||
perror ("RP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return IORETURN (rp_stopioe, SCPE_IOERR);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -405,9 +429,10 @@ rp_stb = (rp_stb & ~STB_DYN) | newb;
|
||||
if (uptr->flags & UNIT_WPRT) rp_sta = rp_sta | STA_SUWP;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) rp_stb = rp_stb | STB_SUFU | STB_SUNR;
|
||||
else if (sim_is_active (uptr)) {
|
||||
f = (uptr->FUNC) & STA_M_FUNC;
|
||||
if ((f == FN_SEEK) || (f == FN_RECAL))
|
||||
rp_stb = rp_stb | STB_SUSU | STB_SUNR; }
|
||||
f = (uptr->FUNC) & STA_M_FUNC;
|
||||
if ((f == FN_SEEK) || (f == FN_RECAL))
|
||||
rp_stb = rp_stb | STB_SUSU | STB_SUNR;
|
||||
}
|
||||
else if (uptr->CYL >= RP_NUMCY) rp_sta = rp_sta | STA_SUSI;
|
||||
if ((rp_sta & STA_EFLGS) || (rp_stb & STB_EFLGS)) rp_sta = rp_sta | STA_ERR;
|
||||
if (((rp_sta & (STA_ERR | STA_DON)) && (rp_sta & STA_IED)) ||
|
||||
@@ -415,7 +440,7 @@ if (((rp_sta & (STA_ERR | STA_DON)) && (rp_sta & STA_IED)) ||
|
||||
else CLR_INT (RP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat rp_reset (DEVICE *dptr)
|
||||
@@ -426,9 +451,10 @@ UNIT *uptr;
|
||||
rp_sta = rp_stb = rp_da = rp_wc = rp_ma = rp_busy = 0;
|
||||
CLR_INT (RP);
|
||||
for (i = 0; i < RP_NUMDR; i++) {
|
||||
uptr = rp_dev.units + i;
|
||||
sim_cancel (uptr);
|
||||
uptr->CYL = uptr->FUNC = 0; }
|
||||
uptr = rp_dev.units + i;
|
||||
sim_cancel (uptr);
|
||||
uptr->CYL = uptr->FUNC = 0;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/* pdp15_ttx.c: PDP-15 additional terminals simulator
|
||||
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,13 +19,15 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
ttix,ttox LT15/LT19 terminal input/output
|
||||
ttix,ttox LT15/LT19 terminal input/output
|
||||
|
||||
14-Jan-04 RMS Cloned from pdp8_ttx.c
|
||||
29-Jun-05 RMS Added SET TTOXn DISCONNECT
|
||||
21-Jun-05 RMS Fixed bug in SHOW CONN/STATS
|
||||
14-Jan-04 RMS Cloned from pdp8_ttx.c
|
||||
|
||||
This module implements 16 individual serial interfaces similar in function
|
||||
to the console. These interfaces are mapped to Telnet based connections as
|
||||
@@ -39,25 +41,25 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined (PDP15)
|
||||
#define TTX_MAXL 16 /* max number of lines */
|
||||
#define TTX_MAXL 16 /* max number of lines */
|
||||
#elif defined (PDP9)
|
||||
#define TTX_MAXL 4
|
||||
#define TTX_MAXL 4
|
||||
#else
|
||||
#define TTX_MAXL 1
|
||||
#define TTX_MAXL 1
|
||||
#endif
|
||||
|
||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
|
||||
#define UNIT_V_KSR (UNIT_V_UF + 1) /* KSR33 */
|
||||
#define UNIT_8B (1 << UNIT_V_8B)
|
||||
#define UNIT_KSR (1 << UNIT_V_KSR)
|
||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
|
||||
#define UNIT_V_KSR (UNIT_V_UF + 1) /* KSR33 */
|
||||
#define UNIT_8B (1 << UNIT_V_8B)
|
||||
#define UNIT_KSR (1 << UNIT_V_KSR)
|
||||
|
||||
uint32 ttix_done = 0; /* input flags */
|
||||
uint32 ttox_done = 0; /* output flags */
|
||||
uint8 ttix_buf[TTX_MAXL] = { 0 }; /* input buffers */
|
||||
uint8 ttox_buf[TTX_MAXL] = { 0 }; /* output buffers */
|
||||
TMLN ttx_ldsc[TTX_MAXL] = { 0 }; /* line descriptors */
|
||||
TMXR ttx_desc = { 1, 0, 0, ttx_ldsc }; /* mux descriptor */
|
||||
#define ttx_lines ttx_desc.lines /* current number of lines */
|
||||
uint32 ttix_done = 0; /* input flags */
|
||||
uint32 ttox_done = 0; /* output flags */
|
||||
uint8 ttix_buf[TTX_MAXL] = { 0 }; /* input buffers */
|
||||
uint8 ttox_buf[TTX_MAXL] = { 0 }; /* output buffers */
|
||||
TMLN ttx_ldsc[TTX_MAXL] = { 0 }; /* line descriptors */
|
||||
TMXR ttx_desc = { 1, 0, 0, ttx_ldsc }; /* mux descriptor */
|
||||
#define ttx_lines ttx_desc.lines /* current number of lines */
|
||||
|
||||
extern int32 int_hwre[API_HLVL+1];
|
||||
extern int32 tmxr_poll;
|
||||
@@ -82,113 +84,126 @@ void ttx_reset_ln (int32 i);
|
||||
t_stat ttx_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat ttx_vlines (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
|
||||
|
||||
/* TTIx data structures
|
||||
|
||||
ttix_dev TTIx device descriptor
|
||||
ttix_unit TTIx unit descriptor
|
||||
ttix_reg TTIx register list
|
||||
ttix_mod TTIx modifiers list
|
||||
ttix_dev TTIx device descriptor
|
||||
ttix_unit TTIx unit descriptor
|
||||
ttix_reg TTIx register list
|
||||
ttix_mod TTIx modifiers list
|
||||
*/
|
||||
|
||||
DIB ttix_dib = { DEV_TTO1, 8, NULL,
|
||||
{ &ttox, &ttix, &ttox, &ttix, &ttox, &ttix, &ttox, &ttix } };
|
||||
DIB ttix_dib = {
|
||||
DEV_TTO1, 8, NULL,
|
||||
{ &ttox, &ttix, &ttox, &ttix, &ttox, &ttix, &ttox, &ttix }
|
||||
};
|
||||
|
||||
UNIT ttix_unit = { UDATA (&ttix_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG ttx_nlreg = { DRDATA (NLINES, ttx_lines, 4), PV_LEFT };
|
||||
|
||||
REG ttix_reg[] = {
|
||||
{ BRDATA (BUF, ttix_buf, 8, 8, TTX_MAXL) },
|
||||
{ ORDATA (DONE, ttix_done, TTX_MAXL) },
|
||||
{ FLDATA (INT, int_hwre[API_TTI1], INT_V_TTI1) },
|
||||
{ DRDATA (TIME, ttix_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ ORDATA (DEVNUM, ttix_dib.dev, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
{ BRDATA (BUF, ttix_buf, 8, 8, TTX_MAXL) },
|
||||
{ ORDATA (DONE, ttix_done, TTX_MAXL) },
|
||||
{ FLDATA (INT, int_hwre[API_TTI1], INT_V_TTI1) },
|
||||
{ DRDATA (TIME, ttix_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ ORDATA (DEVNUM, ttix_dib.dev, 6), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB ttix_mod[] = {
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
|
||||
&ttx_vlines, NULL, &ttx_nlreg },
|
||||
{ UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &ttx_summ },
|
||||
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
|
||||
&tmxr_dscln, NULL, &ttx_desc },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
|
||||
NULL, &ttx_show, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
|
||||
NULL, &ttx_show, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_devno, &show_devno, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
|
||||
&tmxr_set_log, &tmxr_show_log, &ttx_desc },
|
||||
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
|
||||
&tmxr_set_nolog, NULL, &ttx_desc },
|
||||
{ 0 } };
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
|
||||
&ttx_vlines, NULL, &ttx_nlreg },
|
||||
{ UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &ttx_summ },
|
||||
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
|
||||
&tmxr_dscln, NULL, &ttx_desc },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
|
||||
NULL, &ttx_show, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
|
||||
NULL, &ttx_show, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_devno, &show_devno, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE tti1_dev = {
|
||||
"TTIX", &ttix_unit, ttix_reg, ttix_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
&tmxr_ex, &tmxr_dep, &ttx_reset,
|
||||
NULL, &ttx_attach, &ttx_detach,
|
||||
&ttix_dib, DEV_NET | DEV_DISABLE };
|
||||
"TTIX", &ttix_unit, ttix_reg, ttix_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
&tmxr_ex, &tmxr_dep, &ttx_reset,
|
||||
NULL, &ttx_attach, &ttx_detach,
|
||||
&ttix_dib, DEV_NET | DEV_DISABLE
|
||||
};
|
||||
|
||||
/* TTOx data structures
|
||||
|
||||
ttox_dev TTOx device descriptor
|
||||
ttox_unit TTOx unit descriptor
|
||||
ttox_reg TTOx register list
|
||||
ttox_dev TTOx device descriptor
|
||||
ttox_unit TTOx unit descriptor
|
||||
ttox_reg TTOx register list
|
||||
*/
|
||||
|
||||
UNIT ttox_unit[] = {
|
||||
{ UDATA (&ttox_svc, UNIT_KSR, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT } };
|
||||
{ UDATA (&ttox_svc, UNIT_KSR, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
||||
{ UDATA (&ttox_svc, UNIT_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT }
|
||||
};
|
||||
|
||||
REG ttox_reg[] = {
|
||||
{ BRDATA (BUF, ttox_buf, 8, 8, TTX_MAXL) },
|
||||
{ ORDATA (DONE, ttox_done, TTX_MAXL) },
|
||||
{ FLDATA (INT, int_hwre[API_TTO1], INT_V_TTO1) },
|
||||
{ URDATA (TIME, ttox_unit[0].wait, 10, 24, 0,
|
||||
TTX_MAXL, PV_LEFT) },
|
||||
{ NULL } };
|
||||
{ BRDATA (BUF, ttox_buf, 8, 8, TTX_MAXL) },
|
||||
{ ORDATA (DONE, ttox_done, TTX_MAXL) },
|
||||
{ FLDATA (INT, int_hwre[API_TTO1], INT_V_TTO1) },
|
||||
{ URDATA (TIME, ttox_unit[0].wait, 10, 24, 0,
|
||||
TTX_MAXL, PV_LEFT) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB ttox_mod[] = {
|
||||
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", NULL },
|
||||
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , NULL },
|
||||
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , NULL },
|
||||
{ 0 } };
|
||||
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", NULL },
|
||||
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , NULL },
|
||||
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT",
|
||||
&tmxr_dscln, NULL, &ttx_desc },
|
||||
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
|
||||
&tmxr_set_log, &tmxr_show_log, &ttx_desc },
|
||||
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
|
||||
&tmxr_set_nolog, NULL, &ttx_desc },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE tto1_dev = {
|
||||
"TTOX", ttox_unit, ttox_reg, ttox_mod,
|
||||
TTX_MAXL, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &ttx_reset,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DISABLE };
|
||||
|
||||
"TTOX", ttox_unit, ttox_reg, ttox_mod,
|
||||
TTX_MAXL, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &ttx_reset,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* Terminal input: IOT routine */
|
||||
|
||||
int32 ttix (int32 dev, int32 pulse, int32 dat)
|
||||
{
|
||||
int32 ln = ttx_getln (dev, pulse); /* line # */
|
||||
int32 ln = ttx_getln (dev, pulse); /* line # */
|
||||
|
||||
if (ln > ttx_lines) return dat;
|
||||
if (pulse & 001) { /* KSF1 */
|
||||
if (ttix_test_done (ln)) dat = dat | IOT_SKP; }
|
||||
if (pulse & 002) { /* KRB1 */
|
||||
ttix_clr_done (ln); /* clear flag */
|
||||
dat = dat | ttix_buf[ln]; } /* return buffer */
|
||||
if (pulse & 001) { /* KSF1 */
|
||||
if (ttix_test_done (ln)) dat = dat | IOT_SKP;
|
||||
}
|
||||
if (pulse & 002) { /* KRB1 */
|
||||
ttix_clr_done (ln); /* clear flag */
|
||||
dat = dat | ttix_buf[ln]; /* return buffer */
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
@@ -198,22 +213,26 @@ t_stat ttix_svc (UNIT *uptr)
|
||||
{
|
||||
int32 ln, c, temp;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
|
||||
sim_activate (uptr, tmxr_poll); /* continue poll */
|
||||
ln = tmxr_poll_conn (&ttx_desc); /* look for connect */
|
||||
if (ln >= 0) ttx_ldsc[ln].rcve = 1; /* got one? rcv enab */
|
||||
tmxr_poll_rx (&ttx_desc); /* poll for input */
|
||||
for (ln = 0; ln < TTX_MAXL; ln++) { /* loop thru lines */
|
||||
if (ttx_ldsc[ln].conn) { /* connected? */
|
||||
if (temp = tmxr_getc_ln (&ttx_ldsc[ln])) { /* get char */
|
||||
if (temp & SCPE_BREAK) c = 0; /* break? */
|
||||
else if (ttox_unit[ln].flags & UNIT_KSR) { /* KSR? */
|
||||
c = temp & 0177;
|
||||
if (islower (c)) c = toupper (c);
|
||||
c = c | 0200; }
|
||||
else c = temp & ((ttox_unit[ln].flags & UNIT_8B)? 0377: 0177);
|
||||
ttix_buf[ln] = c;
|
||||
ttix_set_done (ln); } } }
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
|
||||
sim_activate (uptr, tmxr_poll); /* continue poll */
|
||||
ln = tmxr_poll_conn (&ttx_desc); /* look for connect */
|
||||
if (ln >= 0) ttx_ldsc[ln].rcve = 1; /* got one? rcv enab */
|
||||
tmxr_poll_rx (&ttx_desc); /* poll for input */
|
||||
for (ln = 0; ln < TTX_MAXL; ln++) { /* loop thru lines */
|
||||
if (ttx_ldsc[ln].conn) { /* connected? */
|
||||
if (temp = tmxr_getc_ln (&ttx_ldsc[ln])) { /* get char */
|
||||
if (temp & SCPE_BREAK) c = 0; /* break? */
|
||||
else if (ttox_unit[ln].flags & UNIT_KSR) { /* KSR? */
|
||||
c = temp & 0177;
|
||||
if (islower (c)) c = toupper (c);
|
||||
c = c | 0200;
|
||||
}
|
||||
else c = temp & ((ttox_unit[ln].flags & UNIT_8B)? 0377: 0177);
|
||||
ttix_buf[ln] = c;
|
||||
ttix_set_done (ln);
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -236,23 +255,27 @@ void ttix_clr_done (int32 ln)
|
||||
{
|
||||
ttix_done = ttix_done & ~(1 << ln);
|
||||
if (ttix_done) { SET_INT (TTI1); }
|
||||
else { CLR_INT (TTI1); }
|
||||
else {
|
||||
CLR_INT (TTI1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Terminal output: IOT routine */
|
||||
|
||||
int32 ttox (int32 dev, int32 pulse, int32 dat)
|
||||
{
|
||||
int32 ln = ttx_getln (dev, pulse); /* line # */
|
||||
int32 ln = ttx_getln (dev, pulse); /* line # */
|
||||
|
||||
if (ln > ttx_lines) return dat;
|
||||
if (pulse & 001) { /* TSF */
|
||||
if (ttox_test_done (ln)) dat = dat | IOT_SKP; }
|
||||
if (pulse & 002) ttox_clr_done (ln); /* clear flag */
|
||||
if (pulse & 004) { /* load buffer */
|
||||
sim_activate (&ttox_unit[ln], ttox_unit[ln].wait); /* activate unit */
|
||||
ttox_buf[ln] = dat & 0377; } /* load buffer */
|
||||
if (pulse & 001) { /* TSF */
|
||||
if (ttox_test_done (ln)) dat = dat | IOT_SKP;
|
||||
}
|
||||
if (pulse & 002) ttox_clr_done (ln); /* clear flag */
|
||||
if (pulse & 004) { /* load buffer */
|
||||
sim_activate (&ttox_unit[ln], ttox_unit[ln].wait); /* activate unit */
|
||||
ttox_buf[ln] = dat & 0377; /* load buffer */
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
@@ -260,23 +283,27 @@ return dat;
|
||||
|
||||
t_stat ttox_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c, ln = uptr - ttox_unit; /* line # */
|
||||
int32 c, ln = uptr - ttox_unit; /* line # */
|
||||
|
||||
if (ttx_ldsc[ln].conn) { /* connected? */
|
||||
if (ttx_ldsc[ln].xmte) { /* tx enabled? */
|
||||
TMLN *lp = &ttx_ldsc[ln]; /* get line */
|
||||
if (ttox_unit[ln].flags & UNIT_KSR) { /* KSR mode? */
|
||||
c = ttox_buf[ln] & 0177; /* get char */
|
||||
if (islower (c)) c = toupper (c);
|
||||
if ((c < 007) || (c > 0137)) c = -1; }
|
||||
else c = ttox_buf[ln] & ((ttox_unit[ln].flags & UNIT_8B)? 0377: 0177);
|
||||
if (c >= 0) tmxr_putc_ln (lp, c); /* output char */
|
||||
tmxr_poll_tx (&ttx_desc); } /* poll xmt */
|
||||
else {
|
||||
tmxr_poll_tx (&ttx_desc); /* poll xmt */
|
||||
sim_activate (uptr, ttox_unit[ln].wait); /* wait */
|
||||
return SCPE_OK; } }
|
||||
ttox_set_done (ln); /* set done */
|
||||
if (ttx_ldsc[ln].conn) { /* connected? */
|
||||
if (ttx_ldsc[ln].xmte) { /* tx enabled? */
|
||||
TMLN *lp = &ttx_ldsc[ln]; /* get line */
|
||||
if (ttox_unit[ln].flags & UNIT_KSR) { /* KSR mode? */
|
||||
c = ttox_buf[ln] & 0177; /* get char */
|
||||
if (islower (c)) c = toupper (c);
|
||||
if ((c < 007) || (c > 0137)) c = -1;
|
||||
}
|
||||
else c = ttox_buf[ln] & ((ttox_unit[ln].flags & UNIT_8B)? 0377: 0177);
|
||||
if (c >= 0) tmxr_putc_ln (lp, c); /* output char */
|
||||
tmxr_poll_tx (&ttx_desc); /* poll xmt */
|
||||
}
|
||||
else {
|
||||
tmxr_poll_tx (&ttx_desc); /* poll xmt */
|
||||
sim_activate (uptr, ttox_unit[ln].wait); /* wait */
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
ttox_set_done (ln); /* set done */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -299,10 +326,10 @@ void ttox_clr_done (int32 ln)
|
||||
{
|
||||
ttox_done = ttox_done & ~(1 << ln);
|
||||
if (ttox_done) { SET_INT (TTO1); }
|
||||
else { CLR_INT (TTO1); }
|
||||
else { CLR_INT (TTO1); }
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Compute relative line number
|
||||
|
||||
This algorithm does not assign contiguous line numbers of ascending
|
||||
@@ -313,11 +340,11 @@ int32 ttx_getln (int32 dev, int32 pulse)
|
||||
{
|
||||
int32 rdno = ((dev - ttix_dib.dev) >> 1) & 3;
|
||||
|
||||
#if defined (PDP15) /* PDP-15? */
|
||||
#if defined (PDP15) /* PDP-15? */
|
||||
int32 sub = (pulse >> 4) & 3;
|
||||
return (rdno * 4) + sub; /* use dev, subdev */
|
||||
#else /* others */
|
||||
return rdno; /* use dev only */
|
||||
return (rdno * 4) + sub; /* use dev, subdev */
|
||||
#else /* others */
|
||||
return rdno; /* use dev only */
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -327,15 +354,18 @@ t_stat ttx_reset (DEVICE *dptr)
|
||||
{
|
||||
int32 ln;
|
||||
|
||||
if (dptr->flags & DEV_DIS) { /* sync enables */
|
||||
ttix_dev.flags = ttox_dev.flags | DEV_DIS;
|
||||
ttox_dev.flags = ttox_dev.flags | DEV_DIS; }
|
||||
else { ttix_dev.flags = ttix_dev.flags & ~DEV_DIS;
|
||||
ttox_dev.flags = ttox_dev.flags & ~DEV_DIS; }
|
||||
if (ttix_unit.flags & UNIT_ATT) /* if attached, */
|
||||
sim_activate (&ttix_unit, tmxr_poll); /* activate */
|
||||
else sim_cancel (&ttix_unit); /* else stop */
|
||||
for (ln = 0; ln < TTX_MAXL; ln++) ttx_reset_ln (ln); /* for all lines */
|
||||
if (dptr->flags & DEV_DIS) { /* sync enables */
|
||||
ttix_dev.flags = ttox_dev.flags | DEV_DIS;
|
||||
ttox_dev.flags = ttox_dev.flags | DEV_DIS;
|
||||
}
|
||||
else {
|
||||
ttix_dev.flags = ttix_dev.flags & ~DEV_DIS;
|
||||
ttox_dev.flags = ttox_dev.flags & ~DEV_DIS;
|
||||
}
|
||||
if (ttix_unit.flags & UNIT_ATT) /* if attached, */
|
||||
sim_activate (&ttix_unit, tmxr_poll); /* activate */
|
||||
else sim_cancel (&ttix_unit); /* else stop */
|
||||
for (ln = 0; ln < TTX_MAXL; ln++) ttx_reset_ln (ln); /* for all lines */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -343,11 +373,11 @@ return SCPE_OK;
|
||||
|
||||
void ttx_reset_ln (int32 ln)
|
||||
{
|
||||
ttix_buf[ln] = 0; /* clear buf, */
|
||||
ttix_buf[ln] = 0; /* clear buf, */
|
||||
ttox_buf[ln] = 0;
|
||||
ttix_clr_done (ln); /* clear done */
|
||||
ttix_clr_done (ln); /* clear done */
|
||||
ttox_clr_done (ln);
|
||||
sim_cancel (&ttox_unit[ln]); /* stop poll */
|
||||
sim_cancel (&ttox_unit[ln]); /* stop poll */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -357,9 +387,9 @@ t_stat ttx_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
r = tmxr_attach (&ttx_desc, uptr, cptr); /* attach */
|
||||
if (r != SCPE_OK) return r; /* error */
|
||||
sim_activate (uptr, tmxr_poll); /* start poll */
|
||||
r = tmxr_attach (&ttx_desc, uptr, cptr); /* attach */
|
||||
if (r != SCPE_OK) return r; /* error */
|
||||
sim_activate (uptr, tmxr_poll); /* start poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -370,9 +400,9 @@ t_stat ttx_detach (UNIT *uptr)
|
||||
int32 i;
|
||||
t_stat r;
|
||||
|
||||
r = tmxr_detach (&ttx_desc, uptr); /* detach */
|
||||
sim_cancel (uptr); /* stop poll */
|
||||
for (i = 0; i < TTX_MAXL; i++) ttx_ldsc[i].rcve = 0; /* disable rcv */
|
||||
r = tmxr_detach (&ttx_desc, uptr); /* detach */
|
||||
sim_cancel (uptr); /* stop poll */
|
||||
for (i = 0; i < TTX_MAXL; i++) ttx_ldsc[i].rcve = 0; /* disable rcv */
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -392,14 +422,17 @@ return SCPE_OK;
|
||||
|
||||
t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
int32 i;
|
||||
int32 i, t;
|
||||
|
||||
for (i = 0; (i < ttx_lines) && (ttx_ldsc[i].conn == 0); i++) ;
|
||||
if (i < ttx_lines) {
|
||||
for (i = 0; i < ttx_lines; i++) {
|
||||
if (ttx_ldsc[i].conn)
|
||||
if (val) tmxr_fconns (st, &ttx_ldsc[i], i);
|
||||
else tmxr_fstats (st, &ttx_ldsc[i], i); } }
|
||||
for (i = t = 0; i < TTX_MAXL; i++) t = t + (ttx_ldsc[i].conn != 0);
|
||||
if (t) {
|
||||
for (i = 0; i < ttx_lines; i++) {
|
||||
if (ttx_ldsc[i].conn) {
|
||||
if (val) tmxr_fconns (st, &ttx_ldsc[i], i);
|
||||
else tmxr_fstats (st, &ttx_ldsc[i], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else fprintf (st, "all disconnected\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -416,20 +449,24 @@ newln = get_uint (cptr, 10, TTX_MAXL, &r);
|
||||
if ((r != SCPE_OK) || (newln == ttx_lines)) return r;
|
||||
if (newln == 0) return SCPE_ARG;
|
||||
if (newln < ttx_lines) {
|
||||
for (i = newln, t = 0; i < ttx_lines; i++) t = t | ttx_ldsc[i].conn;
|
||||
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
|
||||
return SCPE_OK;
|
||||
for (i = newln; i < ttx_lines; i++) {
|
||||
if (ttx_ldsc[i].conn) {
|
||||
tmxr_linemsg (&ttx_ldsc[i], "\r\nOperator disconnected line\r\n");
|
||||
tmxr_reset_ln (&ttx_ldsc[i]); } /* reset line */
|
||||
ttox_unit[i].flags = ttox_unit[i].flags | UNIT_DIS;
|
||||
ttx_reset_ln (i); }
|
||||
}
|
||||
else { for (i = ttx_lines; i < newln; i++) {
|
||||
ttox_unit[i].flags = ttox_unit[i].flags & ~UNIT_DIS;
|
||||
ttx_reset_ln (i); }
|
||||
}
|
||||
for (i = newln, t = 0; i < ttx_lines; i++) t = t | ttx_ldsc[i].conn;
|
||||
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
|
||||
return SCPE_OK;
|
||||
for (i = newln; i < ttx_lines; i++) {
|
||||
if (ttx_ldsc[i].conn) {
|
||||
tmxr_linemsg (&ttx_ldsc[i], "\r\nOperator disconnected line\r\n");
|
||||
tmxr_reset_ln (&ttx_ldsc[i]); /* reset line */
|
||||
}
|
||||
ttox_unit[i].flags = ttox_unit[i].flags | UNIT_DIS;
|
||||
ttx_reset_ln (i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = ttx_lines; i < newln; i++) {
|
||||
ttox_unit[i].flags = ttox_unit[i].flags & ~UNIT_DIS;
|
||||
ttx_reset_ln (i);
|
||||
}
|
||||
}
|
||||
ttx_lines = newln;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user