| /* hp_tapelib.h: HP magnetic tape controller simulator library definitions | |
| Copyright (c) 2013-2016, J. David Bryan | |
| Copyright (c) 2004-2011, 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"), to deal | |
| in the Software without restriction, including without limitation the rights | |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| copies of the Software, and to permit persons to whom the Software is | |
| furnished to do so, subject to the following conditions: | |
| The above copyright notice and this permission notice shall be included in | |
| all copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
| ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| Except as contained in this notice, the name of the authors shall not be used | |
| in advertising or otherwise to promote the sale, use or other dealings in | |
| this Software without prior written authorization from the authors. | |
| 11-Nov-15 JDB First release version | |
| 24-Mar-13 JDB Created tape controller common library from MS simulator | |
| This file defines the interface between machine-specific tape drive | |
| simulators and the common HP tape controller simulation library. It must be | |
| included by the controller-specific modules. | |
| */ | |
| #include "hp3000_defs.h" /* this must reflect the machine used */ | |
| #include "sim_tape.h" | |
| /* Program limits */ | |
| #define TL_MAXDRIVE 3 /* last valid drive number */ | |
| #define TL_AUXUNITS 1 /* number of auxiliary units required */ | |
| #define TL_CNTLR_UNIT (TL_MAXDRIVE + 1) /* controller unit number */ | |
| #define TL_MAXREC (DV_UMAX + 1) /* maximum supported tape record size in bytes */ | |
| #define TL_BUFSIZE (TL_MAXREC + 2) /* buffer size in bytes (including space for CRCC/LRCC) */ | |
| /* Debug flags */ | |
| #define TL_DEB_CMD (1 << 0) /* trace controller commands */ | |
| #define TL_DEB_INCO (1 << 1) /* trace command initiations and completions */ | |
| #define TL_DEB_STATE (1 << 2) /* trace command execution state changes */ | |
| #define TL_DEB_SERV (1 << 3) /* trace unit service scheduling calls */ | |
| #define TL_DEB_XFER (1 << 4) /* trace data reads and writes */ | |
| #define TL_DEB_IOB (1 << 5) /* trace I/O bus signals and data words */ | |
| #define TL_DEB_V_UF 6 /* first free debug flag bit */ | |
| /* Common per-unit tape drive state variables */ | |
| #define PROP u3 /* drive properties */ | |
| #define STATUS u4 /* drive status */ | |
| #define OPCODE u5 /* drive current operation */ | |
| #define PHASE u6 /* drive current operation phase */ | |
| /* Device flags and accessors */ | |
| #define DEV_REALTIME_SHIFT (DEV_V_UF + 0) /* bits 0-0: timing mode is realistic */ | |
| #define DEV_REALTIME (1 << DEV_REALTIME_SHIFT) /* realistic timing flag */ | |
| /* Unit flags and accessors. | |
| The user-defined unit flags are used to store tape unit status that may be | |
| modified by the user, as follows: | |
| +---+---+---+---+---+---+---+---+ | |
| [...] - - - | R | O | model | | |
| +---+---+---+---+---+---+---+---+ | |
| Where: | |
| R = the unit is rewinding | |
| O = the unit is offline | |
| model = the DRIVE_TYPE enumeration constant for the simulated drive | |
| Implementation notes: | |
| 1. The hardware REWIND STATUS (SRW) signal is implemented as a unit flag, | |
| although it may be inferred from unit.OPCODE = Rewind or Rewind_Offline | |
| and unit.PHASE = Traverse_Phase. This is for the convenience of testing | |
| the "unit busy" condition, which exists when a unit is offline or | |
| rewinding. | |
| */ | |
| #define UNIT_MODEL_SHIFT (MTUF_V_UF + 0) /* bits 0-2: drive model ID */ | |
| #define UNIT_OFFLINE_SHIFT (MTUF_V_UF + 3) /* bits 3-3: unit is offline */ | |
| #define UNIT_REW_SHIFT (MTUF_V_UF + 4) /* bits 4-4: unit is rewinding */ | |
| #define TL_UNIT_V_UF (MTUF_V_UF + 5) /* first free unit flag bit */ | |
| #define UNIT_MODEL_MASK 0000007 /* model ID mask */ | |
| #define UNIT_MODEL (UNIT_MODEL_MASK << UNIT_MODEL_SHIFT) | |
| #define UNIT_OFFLINE (1 << UNIT_OFFLINE_SHIFT) | |
| #define UNIT_REWINDING (1 << UNIT_REW_SHIFT) | |
| #define UNIT_7970B (HP_7970B << UNIT_MODEL_SHIFT) | |
| #define UNIT_7970E (HP_7970E << UNIT_MODEL_SHIFT) | |
| #define UNIT_7974 (HP_7974 << UNIT_MODEL_SHIFT) | |
| #define UNIT_7978 (HP_7978 << UNIT_MODEL_SHIFT) | |
| /* Controller flag and function accessors */ | |
| #define TLIFN(C) ((CNTLR_IFN_SET) ((C) & ~D16_MASK)) | |
| #define TLIBUS(C) ((CNTLR_IBUS) ((C) & D16_MASK)) | |
| #define TLNEXTIFN(S) ((CNTLR_IFN) IOPRIORITY (S)) | |
| /* Tape drive types */ | |
| typedef enum { | |
| HP_7970B, /* HP 7970B 800 bpi NRZI */ | |
| HP_7970E, /* HP 7970E 1600 bpi PE */ | |
| HP_7974, /* HP 7974A 800/1600 bpi NRZI/PE */ | |
| HP_7978 /* HP 7978A 1600/6250 bpi PE/GCR */ | |
| } DRIVE_TYPE; | |
| /* Controller types */ | |
| typedef enum { | |
| HP_13181, /* HP 1000 NRZI controller */ | |
| HP_13183, /* HP 1000 PE controller */ | |
| HP_30215, /* HP 3000 NRZI/PE controller */ | |
| HP_IB /* HP-IB controller */ | |
| } CNTLR_TYPE; | |
| #define LAST_CNTLR HP_IB | |
| #define CNTLR_COUNT (LAST_CNTLR + 1) | |
| /* Interface flags and function bus orders. | |
| The CNTLR_FLAG and CNTLR_IFN declarations simulate hardware signals that are | |
| received and asserted, respectively, by the abstract tape controller. In | |
| simulation, the interface sends a set of one or more flags that indicates the | |
| state of the interface to the controller. The controller then returns a set | |
| of one or more functions that requests the interface to perform certain | |
| actions. | |
| The function set is decoded into a set of function identifiers that are | |
| returned to, and then processed sequentially by, the interface in order of | |
| ascending numerical value. | |
| Implementation notes: | |
| 1. The enumerations describe signals. A set of signals normally would be | |
| modeled as an unsigned integer, as a set may contain more than one | |
| signal. However, we define a set as the enumeration, as the "gdb" | |
| debugger has special provisions for an enumeration of discrete bit values | |
| and will display the set in "ORed" form. | |
| 2. The null sets -- NO_FLAGS and NO_FUNCTIONS -- cannot be defined as | |
| enumeration constants, as including them would require handlers for them | |
| in "switch" statements, which is undesirable. Therefore, we define them | |
| as an explicit integer zero values compatible with the enumerations. | |
| 3. Function bus values are restricted to the upper 16 bits to allow the | |
| combined function and data value to fit in 32 bits. | |
| */ | |
| typedef enum { /* interface flags */ | |
| CMRDY = 0000001, /* Command Ready */ | |
| CMXEQ = 0000002, /* Command Execute */ | |
| DTRDY = 0000004, /* Data Ready */ | |
| EOD = 0000010, /* End of Data */ | |
| INTOK = 0000020, /* Interrupt OK */ | |
| OVRUN = 0000040, /* Data Overrun */ | |
| XFRNG = 0000100 /* Data Transfer No Good */ | |
| } CNTLR_FLAG; | |
| #define NO_FLAGS (CNTLR_FLAG) 0 /* no flags are asserted */ | |
| typedef CNTLR_FLAG CNTLR_FLAG_SET; /* a set of CNTLR_FLAGs */ | |
| typedef enum { /* interface function bus orders */ | |
| IFIN = 000000200000, /* Interface In */ | |
| IFOUT = 000000400000, /* Interface Out */ | |
| IFGTC = 000001000000, /* Interface Get Command */ | |
| SCPE = 000002000000, /* SCP Error Status */ | |
| RQSRV = 000004000000, /* Request Service */ | |
| DVEND = 000010000000, /* Device End */ | |
| STCFL = 000020000000, /* Set Control Flag */ | |
| STDFL = 000040000000, /* Set Data Flag */ | |
| STINT = 000100000000, /* Set Interrupt */ | |
| DATTN = 000200000000 /* Drive Attention */ | |
| } CNTLR_IFN; | |
| #define NO_FUNCTIONS (CNTLR_IFN) 0 /* no functions are asserted */ | |
| typedef CNTLR_IFN CNTLR_IFN_SET; /* a set of CNTLR_IFNs */ | |
| typedef uint16 CNTLR_IBUS; /* the interface data bus */ | |
| #undef NO_DATA /* remove winsock definition */ | |
| #define NO_DATA (CNTLR_IBUS) 0 /* no data asserted */ | |
| typedef uint32 CNTLR_IFN_IBUS; /* a combined interface function set and data bus value */ | |
| /* Controller opcodes. | |
| Each tape interface uses its own encoding for tape commands that must be | |
| translated to the appropriate CNTLR_OPCODEs of the common set, typically via | |
| a lookup table. | |
| Implementation notes: | |
| 1. The Select Unit 0-3 opcodes must have contiguous values, so that the | |
| value of the selected unit may be added to the Select_Unit_0 value to | |
| obtain the correct opcode. | |
| 2. The Invalid Opcode must be the last enumeration value. | |
| */ | |
| typedef enum { | |
| Select_Unit_0, | |
| Select_Unit_1, | |
| Select_Unit_2, | |
| Select_Unit_3, | |
| Clear_Controller, | |
| Read_Record, | |
| Read_Record_with_CRCC, | |
| Read_Record_Backward, | |
| Read_File_Forward, | |
| Write_Record, | |
| Write_Record_without_Parity, | |
| Write_File_Mark, | |
| Write_Gap, | |
| Write_Gap_and_File_Mark, | |
| Forward_Space_Record, | |
| Forward_Space_File, | |
| Backspace_Record, | |
| Backspace_File, | |
| Rewind, | |
| Rewind_Offline, | |
| Invalid_Opcode | |
| } CNTLR_OPCODE; | |
| /* Controller opcode classifications */ | |
| typedef enum { | |
| Class_Invalid, /* invalid classification */ | |
| Class_Read, /* read classification */ | |
| Class_Write, /* write classification */ | |
| Class_Rewind, /* rewind classification */ | |
| Class_Control /* control classification */ | |
| } CNTLR_CLASS; | |
| /* Controller execution states. | |
| The controller is in the idle state while it is awaiting a command. It is in | |
| the busy state while it is executing a command. The end and error states are | |
| busy states in which a device end or a device error, respectively, has | |
| occurred while executing the command. A device end occurs when a record | |
| shorter than the requested length is read. A device error occurs when a | |
| simulator tape support library routine returns an error (e.g., a read of a | |
| tape mark or of a record that is marked bad), or a data overrun is detected | |
| by the interface. In these cases, command execution completes normally, but | |
| notification is given that the channel order or program should be aborted. | |
| Implementation notes: | |
| 1. The error states (End_State and Error_State) must be numerically greater | |
| than the non-error states (Idle_State and Busy_State). | |
| */ | |
| typedef enum { | |
| Idle_State, /* idle */ | |
| Busy_State, /* busy */ | |
| End_State, /* device end */ | |
| Error_State /* device error */ | |
| } CNTLR_STATE; | |
| /* Tape activation delays structure. | |
| The simulation models the mechanical delays of the tape drive as timed events | |
| that are scheduled by unit command phase transitions. For example, a tape | |
| record read is modeled as a start phase, a data transfer phase, and a stop | |
| phase. These correspond to the motion of the physical tape as it starts and | |
| ramps up to speed while crossing the interrecord gap, passes the data record | |
| over the read head, and then slows the tape to a stop in the next interrecord | |
| gap. Separate structures contain the delays for realistic and optimized | |
| timing for the various tape drive types. | |
| The structure contains these fields: | |
| rewind_start -- the time from rewind initiation to controller idle | |
| rewind_rate -- the travel time per inch during rewinding | |
| rewind_stop -- the time from BOT detection to load point search completion | |
| bot_start -- the time starting from the BOT marker to the data block | |
| ir_start -- the time starting from the IR gap to the data block | |
| data_xfer -- the travel time from one data byte to the next | |
| overhead -- the controller execution time from command to first motion | |
| The bot_start and ir_start values include the drive start/stop time and the | |
| traverse time across the initial gap and one-half of the interrecord gap, | |
| respectively. The ir_start value doubles as the stop time. | |
| */ | |
| typedef struct { | |
| int32 rewind_start; /* rewind initiation time */ | |
| int32 rewind_rate; /* rewind time per inch */ | |
| int32 rewind_stop; /* rewind completion time */ | |
| int32 bot_start; /* beginning of tape gap traverse time */ | |
| int32 ir_start; /* interrecord traverse time */ | |
| int32 data_xfer; /* per-byte data transfer time */ | |
| int32 overhead; /* controller execution overhead */ | |
| } DELAY_PROPS; | |
| #define DELAY_INIT(rstart,rrate,rstop,bot,ir,dxfr,ovhd) \ | |
| (rstart), (rrate), (rstop), (bot), (ir), (dxfr), (ovhd) | |
| /* Tape controller state variable structure */ | |
| typedef struct { | |
| CNTLR_TYPE type; /* controller type */ | |
| DEVICE *device; /* controlling device pointer */ | |
| CNTLR_STATE state; /* controller state */ | |
| uint32 status; /* controller status */ | |
| uint32 unit_selected; /* unit number currently selected */ | |
| uint32 unit_attention; /* bitmap of units needing attention */ | |
| uint8 *buffer; /* data buffer pointer */ | |
| t_stat call_status; /* simulator tape support library call status */ | |
| t_mtrlnt length; /* data buffer valid length */ | |
| t_mtrlnt index; /* data buffer current index */ | |
| t_mtrlnt gaplen; /* current record erase gap length */ | |
| t_addr initial_position; /* tape motion initial position */ | |
| DELAY_PROPS *fastptr; /* pointer to the FASTTIME delays */ | |
| const DELAY_PROPS *dlyptr; /* current delay property pointer */ | |
| } CNTLR_VARS; | |
| typedef CNTLR_VARS *CVPTR; /* a pointer to a controller state variable structure */ | |
| /* Controller state variable structure initialization. | |
| The supplied parameters are: | |
| ctype - the type of the controller (CNTLR_TYPE) | |
| dev - the device on which the controller operates (DEVICE) | |
| bufptr - a pointer to the data buffer (array of uint8) | |
| fast - a pointer to the fast timing values (DELAY_PROPS) | |
| */ | |
| #define CNTLR_INIT(ctype,dev,bufptr,fast) \ | |
| (ctype), &(dev), Idle_State, 0, 0, 0, \ | |
| (bufptr), MTSE_OK, 0, 0, 0, 0, \ | |
| &(fast), &(fast) | |
| /* Tape controller device register definitions. | |
| These definitions should be included AFTER any interface-specific registers. | |
| The supplied parameters are: | |
| cntlr -- the controller state variable structure (CNTLR_VARS) | |
| units -- the unit array (array of UNIT) | |
| numunits -- the number of tape drive units | |
| buffer -- the buffer array (array of uint8) | |
| times -- the structure containing the fast delay time values (DELAY_PROPS) | |
| Implementation notes: | |
| 1. The "CNTLR" register is present to ensure that the entire CNTLR_VARS | |
| structure is saved and restored. | |
| */ | |
| #define TL_REGS(cntlr,units,numunits,buffer,times) \ | |
| /* Macro Name Location Radix Width Depth Flags */ \ | |
| /* ------ ------ ------------------------ ----- -------- --------------- ----------------- */ \ | |
| { DRDATA (CSTATE, (cntlr).state, 4), PV_LEFT | REG_RO }, \ | |
| { ORDATA (STATUS, (cntlr).status, 16), REG_RO }, \ | |
| { DRDATA (USEL, (cntlr).unit_selected, 4), PV_LEFT | REG_RO }, \ | |
| { YRDATA (UATTN, (cntlr).unit_attention, 4) }, \ | |
| { BRDATA (RECBUF, (buffer), 8, 8, TL_BUFSIZE), REG_A }, \ | |
| { DRDATA (LIBSTA, (cntlr).call_status, 16), PV_LEFT }, \ | |
| { DRDATA (LENGTH, (cntlr).length, 24), PV_LEFT }, \ | |
| { DRDATA (INDEX, (cntlr).index, 24), PV_LEFT }, \ | |
| { DRDATA (GAPLEN, (cntlr).gaplen, 32), PV_LEFT }, \ | |
| { DRDATA (INPOS, (cntlr).initial_position, T_ADDR_W), PV_LEFT }, \ | |
| { SRDATA (CNTLR, (cntlr)), REG_HRO }, \ | |
| \ | |
| /* Macro Name Location Width Flags */ \ | |
| /* ------ ------- -------------------- ----- ---------------- */ \ | |
| { DRDATA (RSTART, (times).rewind_start, 24), PV_LEFT | REG_NZ }, \ | |
| { DRDATA (RRATE, (times).rewind_rate, 24), PV_LEFT | REG_NZ }, \ | |
| { DRDATA (RSTOP, (times).rewind_stop, 24), PV_LEFT | REG_NZ }, \ | |
| { DRDATA (BTIME, (times).bot_start, 24), PV_LEFT | REG_NZ }, \ | |
| { DRDATA (ITIME, (times).ir_start, 24), PV_LEFT | REG_NZ }, \ | |
| { DRDATA (DTIME, (times).data_xfer, 24), PV_LEFT | REG_NZ }, \ | |
| { DRDATA (OTIME, (times).overhead, 24), PV_LEFT | REG_NZ }, \ | |
| \ | |
| /* Macro Name Location Radix Width Offset Depth Flags */ \ | |
| /* ------ ------- ----------------- ----- -------- ------ ---------- ------------------ */ \ | |
| { URDATA (UPROP, (units)[0].PROP, 8, 16, 0, (numunits), PV_RZRO) }, \ | |
| { URDATA (USTATUS, (units)[0].STATUS, 2, 16, 0, (numunits), PV_RZRO) }, \ | |
| { URDATA (UOPCODE, (units)[0].OPCODE, 10, 6, 0, (numunits), PV_LEFT | REG_RO) }, \ | |
| { URDATA (USTATE, (units)[0].PHASE, 10, 4, 0, (numunits), PV_LEFT | REG_RO) }, \ | |
| { URDATA (UPOS, (units)[0].pos, 10, T_ADDR_W, 0, (numunits), PV_LEFT | REG_RO) }, \ | |
| { URDATA (UWAIT, (units)[0].wait, 10, 32, 0, (numunits), PV_LEFT | REG_HRO) } | |
| /* Tape controller device modifier structure initialization. | |
| This initialization should be included BEFORE any device-specific modifiers. | |
| The supplied parameters are: | |
| cntlr -- the controller state variable structure (CNTLR_VARS) | |
| typeset -- the set of drive type flags supported by the interface | |
| densset -- the set of drive density flags supported by the interface | |
| offvalid -- the interface SET ONLINE/OFFLINE validation function | |
| Implementation notes: | |
| 1. The IFTYPE and IFDENSITY macros test their respective flag sets and | |
| enable or disable the associated modifier entries as indicated. An entry | |
| is disabled by setting the print and match strings to NULL; this ensures | |
| that the modifier is neither printed nor matched against any user input. | |
| 2. The UNIT_RO modifier displays "write ring" if the flag is not set. There | |
| is no corresponding entry for the opposite condition because "read only" | |
| is automatically printed after the attached filename. | |
| */ | |
| /* Selectable drive type flags */ | |
| #define TL_7970B (1 << HP_7970B) | |
| #define TL_7970E (1 << HP_7970E) | |
| #define TL_7974 (1 << HP_7974) | |
| #define TL_7978 (1 << HP_7978) | |
| /* Selectable drive density flags */ | |
| #define TL_FIXED 0 | |
| #define TL_800 (1 << MT_DENS_800) | |
| #define TL_1600 (1 << MT_DENS_1600) | |
| #define TL_6250 (1 << MT_DENS_6250) | |
| #define IFTYPE(t,s) (TL_##t & (s) ? #t : NULL), \ | |
| (TL_##t & (s) ? #t : NULL) | |
| #define IFDENSITY(s) ((s) ? "DENSITY" : NULL), \ | |
| ((s) ? "DENSITY" : NULL) | |
| #define TL_MODS(cntlr,typeset,densset,offvalid) \ | |
| /* Mask Value Match Value Print String Match String Validation Display Descriptor */ \ | |
| /* ----------- ----------- ------------ ------------ ------------- ------- ----------------- */ \ | |
| { UNIT_MODEL, UNIT_7970B, IFTYPE (7970B, typeset), &tl_set_model, NULL, (void *) &(cntlr) }, \ | |
| { UNIT_MODEL, UNIT_7970E, IFTYPE (7970E, typeset), &tl_set_model, NULL, (void *) &(cntlr) }, \ | |
| { UNIT_MODEL, UNIT_7974, IFTYPE (7974, typeset), &tl_set_model, NULL, (void *) &(cntlr) }, \ | |
| { UNIT_MODEL, UNIT_7978, IFTYPE (7978, typeset), &tl_set_model, NULL, (void *) &(cntlr) }, \ | |
| \ | |
| /* Entry Flags Value Print String Match String Validation Display Descriptor */ \ | |
| /* ------------------- ----- ------------ ------------ ---------------- ----------------- ----------------- */ \ | |
| { MTAB_XUN, 0, IFDENSITY (densset), &tl_set_density, &tl_show_density, (void *) &(cntlr) }, \ | |
| { MTAB_XUN, 0, "CAPACITY", "CAPACITY", &tl_set_reelsize, &tl_show_reelsize, NULL }, \ | |
| { MTAB_XUN | MTAB_NMO, 1, "REEL", "REEL", &tl_set_reelsize, &tl_show_reelsize, NULL }, \ | |
| \ | |
| /* Mask Value Match Value Print String Match String Validation Display Descriptor */ \ | |
| /* ------------ ------------ ------------ ------------ ----------- ------- ----------------- */ \ | |
| { UNIT_OFFLINE, UNIT_OFFLINE, "offline", "OFFLINE", &(offvalid), NULL, NULL }, \ | |
| { UNIT_OFFLINE, 0, "online", "ONLINE", &(offvalid), NULL, (void *) &(cntlr) }, \ | |
| \ | |
| { UNIT_RO, 0, "write ring", NULL, NULL, NULL, NULL }, \ | |
| \ | |
| /* Entry Flags Value Print String Match String Validation Display Descriptor */ \ | |
| /* ------------ ----- ------------ ------------ ----------------- ------------------ ----------------- */ \ | |
| { MTAB_XDV, 0, "TIMING", "FASTTIME", &tl_set_timing, &tl_show_timing, (void *) &(cntlr) }, \ | |
| { MTAB_XDV, 1, NULL, "REALTIME", &tl_set_timing, NULL, (void *) &(cntlr) }, \ | |
| \ | |
| { MTAB_XUN, 0, "FORMAT", "FORMAT", &sim_tape_set_fmt, &sim_tape_show_fmt, NULL } | |
| /* Tape library global controller routines */ | |
| extern CNTLR_IFN_IBUS tl_controller (CVPTR cvptr, UNIT *uptr, CNTLR_FLAG_SET flags, CNTLR_IBUS data); | |
| extern t_stat tl_onoffline (CVPTR cvptr, UNIT *uptr, t_bool online); | |
| extern uint16 tl_status (CVPTR cvptr); | |
| extern t_stat tl_reset (CVPTR cvptr); | |
| extern void tl_clear (CVPTR cvptr); | |
| /* Tape library global utility routines */ | |
| extern const char *tl_opcode_name (CNTLR_OPCODE opcode); | |
| extern const char *tl_unit_name (uint32 unit); | |
| /* Tape library global SCP support routines */ | |
| extern t_stat tl_attach (CVPTR cvptr, UNIT *uptr, char *cptr); | |
| extern t_stat tl_detach (UNIT *uptr); | |
| extern t_stat tl_set_timing (UNIT *uptr, int32 value, char *cptr, void *desc); | |
| extern t_stat tl_set_model (UNIT *uptr, int32 value, char *cptr, void *desc); | |
| extern t_stat tl_set_density (UNIT *uptr, int32 value, char *cptr, void *desc); | |
| extern t_stat tl_set_reelsize (UNIT *uptr, int32 value, char *cptr, void *desc); | |
| extern t_stat tl_show_timing (FILE *st, UNIT *uptr, int32 value, void *desc); | |
| extern t_stat tl_show_density (FILE *st, UNIT *uptr, int32 value, void *desc); | |
| extern t_stat tl_show_reelsize (FILE *st, UNIT *uptr, int32 value, void *desc); |