mirror of
https://github.com/simh/simh.git
synced 2026-01-25 19:56:25 +00:00
Notes For V2.10-0
WARNING: V2.10 has reorganized and renamed some of the definition files for the PDP-10, PDP-11, and VAX. Be sure to delete all previous source files before you unpack the Zip archive, or unpack it into a new directory structure. WARNING: V2.10 has a new, more comprehensive save file format. Restoring save files from previous releases will cause 'invalid register' errors and loss of CPU option flags, device enable/ disable flags, unit online/offline flags, and unit writelock flags. WARNING: If you are using Visual Studio .NET through the IDE, be sure to turn off the /Wp64 flag in the project settings, or dozens of spurious errors will be generated. WARNING: Compiling Ethernet support under Windows requires extra steps; see the Ethernet readme file. Ethernet support is currently available only for Windows, Linux, NetBSD, and OpenBSD. 1. New Features 1.1 SCP and Libraries - The VT emulation package has been replaced by the capability to remote the console to a Telnet session. Telnet clients typically have more complete and robust VT100 emulation. - Simulated devices may now have statically allocated buffers, in addition to dynamically allocated buffers or disk-based data stores. - The DO command now takes substitutable arguments (max 9). In command files, %n represents substitutable argument n. - The initial command line is now interpreted as the command name and substitutable arguments for a DO command. This is backward compatible to prior versions. - The initial command line parses switches. -Q is interpreted as quiet mode; informational messages are suppressed. - The HELP command now takes an optional argument. HELP <cmd> types help on the specified command. - Hooks have been added for implementing GUI-based consoles, as well as simulator-specific command extensions. A few internal data structures and definitions have changed. - Two new routines (tmxr_open_master, tmxr_close_master) have been added to sim_tmxr.c. The calling sequence for sim_accept_conn has been changed in sim_sock.c. - The calling sequence for the VM boot routine has been modified to add an additional parameter. - SAVE now saves, and GET now restores, controller and unit flags. - Library sim_ether.c has been added for Ethernet support. 1.2 VAX - Non-volatile RAM (NVR) can behave either like a memory or like a disk-based peripheral. If unattached, it behaves like memory and is saved and restored by SAVE and RESTORE, respectively. If attached, its contents are loaded from disk by ATTACH and written back to disk at DETACH and EXIT. - SHOW <device> VECTOR displays the device's interrupt vector. A few devices allow the vector to be changed with SET <device> VECTOR=nnn. - SHOW CPU IOSPACE displays the I/O space address map. - The TK50 (TMSCP tape) has been added. - The DEQNA/DELQA (Qbus Ethernet controllers) have been added. - Autoconfiguration support has been added. - The paper tape reader has been removed from vax_stddev.c and now references a common implementation file, dec_pt.h. - Examine and deposit switches now work on all devices, not just the CPU. - Device address conflicts are not detected until simulation starts. 1.3 PDP-11 - SHOW <device> VECTOR displays the device's interrupt vector. Most devices allow the vector to be changed with SET <device> VECTOR=nnn. - SHOW CPU IOSPACE displays the I/O space address map. - The TK50 (TMSCP tape), RK611/RK06/RK07 (cartridge disk), RX211 (double density floppy), and KW11P programmable clock have been added. - The DEQNA/DELQA (Qbus Ethernet controllers) have been added. - Autoconfiguration support has been added. - The paper tape reader has been removed from pdp11_stddev.c and now references a common implementation file, dec_pt.h. - Device bootstraps now use the actual CSR specified by the SET ADDRESS command, rather than just the default CSR. Note that PDP-11 operating systems may NOT support booting with non-standard addresses. - Specifying more than 256KB of memory, or changing the bus configuration, causes all peripherals that are not compatible with the current bus configuration to be disabled. - Device address conflicts are not detected until simulation starts. 1.4 PDP-10 - SHOW <device> VECTOR displays the device's interrupt vector. A few devices allow the vector to be changed with SET <device> VECTOR=nnn. - SHOW CPU IOSPACE displays the I/O space address map. - The RX211 (double density floppy) has been added; it is off by default. - The paper tape now references a common implementation file, dec_pt.h. - Device address conflicts are not detected until simulation starts. 1.5 PDP-1 - DECtape (then known as MicroTape) support has been added. - The line printer and DECtape can be disabled and enabled. 1.6 PDP-8 - The RX28 (double density floppy) has been added as an option to the existing RX8E controller. - SHOW <device> DEVNO displays the device's device number. Most devices allow the device number to be changed with SET <device> DEVNO=nnn. - Device number conflicts are not detected until simulation starts. 1.7 IBM 1620 - The IBM 1620 simulator has been released. 1.8 AltairZ80 - A hard drive has been added for increased storage. - Several bugs have been fixed. 1.9 HP 2100 - The 12845A has been added and made the default line printer (LPT). The 12653A has been renamed LPS and is off by default. It also supports the diagnostic functions needed to run the DCPC and DMS diagnostics. - The 12557A/13210A disk defaults to the 13210A (7900/7901). - The 12559A magtape is off by default. - New CPU options (EAU/NOEAU) enable/disable the extended arithmetic instructions for the 2116. These instructions are standard on the 2100 and 21MX. - New CPU options (MPR/NOMPR) enable/disable memory protect for the 2100 and 21MX. - New CPU options (DMS/NODMS) enable/disable the dynamic mapping instructions for the 21MX. - The 12539 timebase generator autocalibrates. 1.10 Simulated Magtapes - Simulated magtapes recognize end of file and the marker 0xFFFFFFFF as end of medium. Only the TMSCP tape simulator can generate an end of medium marker. - The error handling in simulated magtapes was overhauled to be consistent through all simulators. 1.11 Simulated DECtapes - Added support for RT11 image file format (256 x 16b) to DECtapes. 2. Release Notes 2.1 Bugs Fixed - TS11/TSV05 was not simulating the XS0_MOT bit, causing failures under VMS. In addition, two of the CTL options were coded interchanged. - IBM 1401 tape was not setting a word mark under group mark for load mode reads. This caused the diagnostics to crash. - SCP bugs in ssh_break and set_logon were fixed (found by Dave Hittner). - Numerous bugs in the HP 2100 extended arithmetic, floating point, 21MX, DMS, and IOP instructions were fixed. Bugs were also fixed in the memory protect and DMS functions. The moving head disks (DP, DQ) were revised to simulate the hardware more accurately. Missing functions in DQ (address skip, read address) were added. 2.2 HP 2100 Debugging - The HP 2100 CPU nows runs all of the CPU diagnostics. - The peripherals run most of the peripheral diagnostics. There is still a problem in overlapped seek operation on the disks. See the file hp2100_diag.txt for details. 3. In Progress These simulators are not finished and are available in a separate Zip archive distribution. - Interdata 16b/32b: coded, partially tested. See the file id_diag.txt for details. - SDS 940: coded, partially tested.
This commit is contained in:
committed by
Mark Pizzolato
parent
df6475181c
commit
2c2dd5ea33
@@ -316,11 +316,11 @@
|
||||
#include "nova_defs.h"
|
||||
|
||||
#define UNIT_V_MICRO (UNIT_V_UF) /* Microeclipse? */
|
||||
#define UNIT_MICRO (1 << UNIT_V_MICRO)
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF+1) /* dummy mask */
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#define UNIT_V_17B (UNIT_V_UF) /* 17 bit MAP */
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF+1) /* dummy mask */
|
||||
#define UNIT_MICRO (1 << UNIT_V_MICRO)
|
||||
#define UNIT_17B (1 << UNIT_V_17B)
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
|
||||
unsigned int16 M[MAXMEMSIZE] = { 0 }; /* memory */
|
||||
int32 AC[4] = { 0 }; /* accumulators */
|
||||
@@ -344,6 +344,8 @@ int32 XCT_mode = 0; /* 1 if XCT mode */
|
||||
int32 XCT_inst = 0; /* XCT instruction */
|
||||
int32 PPC = -1;
|
||||
|
||||
struct ndev dev_table[64]; /* dispatch table */
|
||||
|
||||
/* Instruction history buffer */
|
||||
|
||||
#define HISTMAX 4096
|
||||
@@ -418,11 +420,12 @@ FILE *Trace;
|
||||
t_stat reason;
|
||||
extern int32 sim_int_char;
|
||||
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern DEVICE *sim_devices[];
|
||||
|
||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_reset (DEVICE *dptr);
|
||||
t_stat cpu_boot (int32 unitno);
|
||||
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat Debug_Dump (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat map_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
@@ -432,59 +435,11 @@ t_stat map_svc (UNIT *uptr);
|
||||
int32 GetMap(int32 addr);
|
||||
int32 PutMap(int32 addr, int32 data);
|
||||
int32 Debug_Entry(int32 PC, int32 inst, int32 inst2, int32 AC0, int32 AC1, int32 AC2, int32 AC3, int32 flags);
|
||||
t_stat build_devtab (void);
|
||||
|
||||
extern int32 ptr (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 ptp (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tti (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tto (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tti1 (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tto1 (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 clk (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 plt (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 lpt (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 dsk (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 dkp (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 mta (int32 pulse, int32 code, int32 AC);
|
||||
int32 nulldev (int32 pulse, int32 code, int32 AC);
|
||||
extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw);
|
||||
|
||||
/* IOT dispatch table */
|
||||
|
||||
struct ndev dev_table[64] = {
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 0 - 7 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ INT_TTI, PI_TTI, &tti }, { INT_TTO, PI_TTO, &tto }, /* 10 - 17 */
|
||||
{ INT_PTR, PI_PTR, &ptr }, { INT_PTP, PI_PTP, &ptp },
|
||||
{ INT_CLK, PI_CLK, &clk }, { INT_PLT, PI_PLT, &plt },
|
||||
{ 0, 0, &nulldev }, { INT_LPT, PI_LPT, &lpt },
|
||||
{ INT_DSK, PI_DSK, &dsk }, { 0, 0, &nulldev }, /* 20 - 27 */
|
||||
{ INT_MTA, PI_MTA, &mta }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 30 - 37 */
|
||||
{ 0, 0, &nulldev }, {INT_DKP, PI_DKP, &dkp },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 40 - 47 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ INT_TTI1, PI_TTI1, &tti1 }, { INT_TTO1, PI_TTO1, &tto1 }, /* 50 - 57 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 60 - 67 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 70 - 77 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev } };
|
||||
|
||||
/* CPU data structures
|
||||
|
||||
cpu_dev CPU device descriptor
|
||||
@@ -513,7 +468,6 @@ REG cpu_reg[] = {
|
||||
{ ORDATA (DONE, dev_done, INT_V_ION+1), REG_RO },
|
||||
{ ORDATA (DISABLE, dev_disable, INT_V_ION+1), REG_RO },
|
||||
{ FLDATA (STOP_DEV, stop_dev, 0) },
|
||||
{ FLDATA (MICRO, cpu_unit.flags, UNIT_V_MICRO), REG_HRO },
|
||||
{ DRDATA (INDMAX, ind_max, 16), REG_NZ + PV_LEFT },
|
||||
{ ORDATA (DEBUG, Debug_Flags, 16) },
|
||||
{ DRDATA (MODEL, model, 16) },
|
||||
@@ -606,6 +560,7 @@ int32 pushrtn(int32 pc);
|
||||
|
||||
/* Restore register state */
|
||||
|
||||
if (build_devtab () != SCPE_OK) return SCPE_IERR; /* build dispatch */
|
||||
PC = saved_PC & AMASK; /* load local PC */
|
||||
C = C & 0200000;
|
||||
mask_out (pimask); /* reset int system */
|
||||
@@ -2762,8 +2717,7 @@ else { /* IOT */
|
||||
}
|
||||
break; }
|
||||
} /* end CPU control */
|
||||
else if ((dev_table[device].mask == 0) ||
|
||||
(dev_table[device].mask & iot_enb)) { /* normal device */
|
||||
else if (dev_table[device].routine) { /* normal device */
|
||||
iodata = dev_table[device].routine (pulse, code, AC[dstAC]);
|
||||
reason = iodata >> IOT_V_REASON;
|
||||
if (code & 1) AC[dstAC] = iodata & 0177777;
|
||||
@@ -3189,13 +3143,6 @@ int32 unimp(int32 PC)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Null device */
|
||||
|
||||
int32 nulldev (int32 pulse, int32 code, int32 AC)
|
||||
{
|
||||
return stop_dev << IOT_V_REASON;
|
||||
}
|
||||
|
||||
/* New priority mask out */
|
||||
|
||||
void mask_out (int32 newmask)
|
||||
@@ -3240,6 +3187,8 @@ M[addr] = val & 0177777;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Alter memory size */
|
||||
|
||||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
@@ -3325,7 +3274,7 @@ static const int32 boot_rom[] = {
|
||||
0 /* 0 ;padding */
|
||||
};
|
||||
|
||||
t_stat cpu_boot (int32 unitno)
|
||||
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
int32 i;
|
||||
extern int32 saved_PC;
|
||||
@@ -3411,38 +3360,23 @@ int32 Debug_Dump(UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Device enable routine */
|
||||
/* Build dispatch table */
|
||||
|
||||
t_stat set_enb (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
t_stat build_devtab (void)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
int32 i, dn;
|
||||
|
||||
if (cptr != NULL) return SCPE_ARG;
|
||||
if ((uptr == NULL) || (val == 0)) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
iot_enb = iot_enb | val;
|
||||
if (dptr -> reset) dptr -> reset (dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Device disable routine */
|
||||
|
||||
t_stat set_dsb (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 i;
|
||||
DEVICE *dptr;
|
||||
UNIT *up;
|
||||
|
||||
if (cptr != NULL) return SCPE_ARG;
|
||||
if ((uptr == NULL) || (val == 0)) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
for (i = 0; i < dptr -> numunits; i++) { /* check units */
|
||||
up = (dptr -> units) + i;
|
||||
if ((up -> flags & UNIT_ATT) || sim_is_active (up))
|
||||
return SCPE_NOFNC; }
|
||||
iot_enb = iot_enb & ~val;
|
||||
if (dptr -> reset) dptr -> reset (dptr);
|
||||
for (i = 0; i < 64; i++) { /* clr dev_table */
|
||||
dev_table[i].mask = 0;
|
||||
dev_table[i].pi = 0;
|
||||
dev_table[i].routine = NULL; }
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
||||
if (dibp = (DIB *) dptr->ctxt) { /* get DIB */
|
||||
dn = dibp->dnum; /* get dev num */
|
||||
dev_table[dn].mask = dibp->mask; /* copy entries */
|
||||
dev_table[dn].pi = dibp->pi;
|
||||
dev_table[dn].routine = dibp->routine; } }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
tti terminal input
|
||||
tto terminal output
|
||||
|
||||
03-Oct-02 RMS Added DIBs
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
28-Jan-02 RMS Cleaned up compiler warnings
|
||||
*/
|
||||
@@ -19,6 +20,8 @@
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 tti (int32 pulse, int32 code, int32 AC);
|
||||
int32 tto (int32 pulse, int32 code, int32 AC);
|
||||
t_stat tti_svc (UNIT *uptr);
|
||||
t_stat tto_svc (UNIT *uptr);
|
||||
t_stat tti_reset (DEVICE *dptr);
|
||||
@@ -36,6 +39,8 @@ int32 putseq(char *seq);
|
||||
ttx_mod TTI/TTO modifiers list
|
||||
*/
|
||||
|
||||
DIB tti_dib = { DEV_TTI, INT_TTI, PI_TTI, &tti };
|
||||
|
||||
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG tti_reg[] = {
|
||||
@@ -46,7 +51,6 @@ REG tti_reg[] = {
|
||||
{ FLDATA (INT, int_req, INT_V_TTI) },
|
||||
{ DRDATA (POS, tti_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (MODE, tti_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB ttx_mod[] = {
|
||||
@@ -58,7 +62,8 @@ DEVICE tti_dev = {
|
||||
"TTI", &tti_unit, tti_reg, ttx_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tti_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&tti_dib, 0 };
|
||||
|
||||
/* TTO data structures
|
||||
|
||||
@@ -67,6 +72,8 @@ DEVICE tti_dev = {
|
||||
tto_reg TTO register list
|
||||
*/
|
||||
|
||||
DIB tto_dib = { DEV_TTO, INT_TTO, PI_TTO, &tto };
|
||||
|
||||
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto_reg[] = {
|
||||
@@ -77,14 +84,14 @@ REG tto_reg[] = {
|
||||
{ FLDATA (INT, int_req, INT_V_TTO) },
|
||||
{ DRDATA (POS, tto_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (MODE, tto_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE tto_dev = {
|
||||
"TTO", &tto_unit, tto_reg, ttx_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tto_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&tto_dib, 0 };
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
clk real-time clock
|
||||
|
||||
03-Oct-02 RMS Added DIB
|
||||
17-Sep-01 RMS Added terminal multiplexor support
|
||||
17-Mar-01 RMS Moved function prototype
|
||||
05-Mar-01 RMS Added clock calibration
|
||||
@@ -34,11 +35,14 @@
|
||||
#include "nova_defs.h"
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 clk_sel = 0; /* selected freq */
|
||||
int32 clk_time[4] = { 16000, 100000, 10000, 1000 }; /* freq table */
|
||||
int32 clk_tps[4] = { 60, 10, 100, 1000 }; /* ticks per sec */
|
||||
int32 clk_adj[4] = { 1, -5, 2, 20 }; /* tmxr adjust */
|
||||
int32 tmxr_poll = 16000; /* tmxr poll */
|
||||
|
||||
int32 clk (int32 pulse, int32 code, int32 AC);
|
||||
t_stat clk_svc (UNIT *uptr);
|
||||
t_stat clk_reset (DEVICE *dptr);
|
||||
|
||||
@@ -49,6 +53,8 @@ t_stat clk_reset (DEVICE *dptr);
|
||||
clk_reg CLK register list
|
||||
*/
|
||||
|
||||
DIB clk_dib = { DEV_CLK, INT_CLK, PI_CLK, &clk };
|
||||
|
||||
UNIT clk_unit = { UDATA (&clk_svc, 0, 0) };
|
||||
|
||||
REG clk_reg[] = {
|
||||
@@ -67,7 +73,8 @@ DEVICE clk_dev = {
|
||||
"CLK", &clk_unit, clk_reg, NULL,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, &clk_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&clk_dib, 0 };
|
||||
|
||||
/* IOT routine */
|
||||
|
||||
|
||||
151
NOVA/nova_cpu.c
151
NOVA/nova_cpu.c
@@ -25,6 +25,7 @@
|
||||
|
||||
cpu Nova central processor
|
||||
|
||||
03-Oct-02 RMS Added DIB infrastructure
|
||||
30-Dec-01 RMS Added old PC queue
|
||||
07-Dec-01 RMS Revised to use breakpoint package
|
||||
30-Nov-01 RMS Added extended SET/SHOW support
|
||||
@@ -197,8 +198,7 @@
|
||||
4. Adding I/O devices. These modules must be modified:
|
||||
|
||||
nova_defs.h add interrupt request definition
|
||||
nova_cpu.c add IOT mask, PI mask, and routine to dev_table
|
||||
nova_sys.c add pointer to data structures to sim_devices
|
||||
nova_sys.c add sim_devices entry
|
||||
*/
|
||||
|
||||
#include "nova_defs.h"
|
||||
@@ -218,17 +218,17 @@
|
||||
M[x] = (M[x] - 1) & 0177777; \
|
||||
x = M[x] & AMASK
|
||||
|
||||
#define UNIT_V_MDV (UNIT_V_UF) /* MDV present */
|
||||
#define UNIT_V_MDV (UNIT_V_UF + 0) /* MDV present */
|
||||
#define UNIT_V_STK (UNIT_V_UF + 1) /* stack instr */
|
||||
#define UNIT_V_BYT (UNIT_V_UF + 2) /* byte instr */
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF + 3) /* dummy mask */
|
||||
#define UNIT_MDV (1 << UNIT_V_MDV)
|
||||
#define UNIT_V_STK (UNIT_V_UF+1) /* stack instr */
|
||||
#define UNIT_STK (1 << UNIT_V_STK)
|
||||
#define UNIT_V_BYT (UNIT_V_UF+2) /* byte instr */
|
||||
#define UNIT_BYT (1 << UNIT_V_BYT)
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#define UNIT_IOPT (UNIT_MDV | UNIT_STK | UNIT_BYT)
|
||||
#define UNIT_NOVA3 (UNIT_MDV | UNIT_STK)
|
||||
#define UNIT_NOVA4 (UNIT_MDV | UNIT_STK | UNIT_BYT)
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF+3) /* dummy mask */
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
|
||||
uint16 M[MAXMEMSIZE] = { 0 }; /* memory */
|
||||
int32 AC[4] = { 0 }; /* accumulators */
|
||||
@@ -240,7 +240,6 @@ int32 SR = 0; /* switch register */
|
||||
int32 dev_done = 0; /* device done flags */
|
||||
int32 dev_busy = 0; /* device busy flags */
|
||||
int32 dev_disable = 0; /* int disable flags */
|
||||
int32 iot_enb = -1; /* IOT enables */
|
||||
int32 int_req = 0; /* interrupt requests */
|
||||
int32 pimask = 0; /* priority int mask */
|
||||
int32 pwr_low = 0; /* power fail flag */
|
||||
@@ -249,64 +248,18 @@ int32 stop_dev = 0; /* stop on ill dev */
|
||||
uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
|
||||
int32 pcq_p = 0; /* PC queue ptr */
|
||||
REG *pcq_r = NULL; /* PC queue reg ptr */
|
||||
struct ndev dev_table[64]; /* dispatch table */
|
||||
|
||||
extern int32 sim_int_char;
|
||||
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern DEVICE *sim_devices[];
|
||||
|
||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_reset (DEVICE *dptr);
|
||||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat cpu_boot (int32 unitno);
|
||||
extern int32 ptr (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 ptp (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tti (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tto (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tti1 (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 tto1 (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 clk (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 plt (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 lpt (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 dsk (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 dkp (int32 pulse, int32 code, int32 AC);
|
||||
extern int32 mta (int32 pulse, int32 code, int32 AC);
|
||||
int32 nulldev (int32 pulse, int32 code, int32 AC);
|
||||
extern t_stat sim_activate (UNIT *uptr, int32 delay);
|
||||
|
||||
/* IOT dispatch table */
|
||||
|
||||
struct ndev dev_table[64] = {
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 0 - 7 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ INT_TTI, PI_TTI, &tti }, { INT_TTO, PI_TTO, &tto }, /* 10 - 17 */
|
||||
{ INT_PTR, PI_PTR, &ptr }, { INT_PTP, PI_PTP, &ptp },
|
||||
{ INT_CLK, PI_CLK, &clk }, { INT_PLT, PI_PLT, &plt },
|
||||
{ 0, 0, &nulldev }, { INT_LPT, PI_LPT, &lpt },
|
||||
{ INT_DSK, PI_DSK, &dsk }, { 0, 0, &nulldev }, /* 20 - 27 */
|
||||
{ INT_MTA, PI_MTA, &mta }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 30 - 37 */
|
||||
{ 0, 0, &nulldev }, {INT_DKP, PI_DKP, &dkp },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 40 - 47 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ INT_TTI1, PI_TTI1, &tti1 }, { INT_TTO1, PI_TTO1, &tto1 }, /* 50 - 57 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 60 - 67 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev }, /* 70 - 77 */
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev },
|
||||
{ 0, 0, &nulldev }, { 0, 0, &nulldev } };
|
||||
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat build_devtab (void);
|
||||
|
||||
/* CPU data structures
|
||||
|
||||
@@ -339,14 +292,10 @@ REG cpu_reg[] = {
|
||||
{ ORDATA (DONE, dev_done, INT_V_ION+1), REG_RO },
|
||||
{ ORDATA (DISABLE, dev_disable, INT_V_ION+1), REG_RO },
|
||||
{ FLDATA (STOP_DEV, stop_dev, 0) },
|
||||
{ FLDATA (MDV, cpu_unit.flags, UNIT_V_MDV), REG_HRO },
|
||||
{ FLDATA (ISTK, cpu_unit.flags, UNIT_V_STK), REG_HRO },
|
||||
{ FLDATA (IBYT, cpu_unit.flags, UNIT_V_BYT), REG_HRO },
|
||||
{ DRDATA (INDMAX, ind_max, 16), REG_NZ + PV_LEFT },
|
||||
{ BRDATA (PCQ, pcq, 8, 16, PCQ_SIZE), REG_RO+REG_CIRC },
|
||||
{ ORDATA (PCQP, pcq_p, 6), REG_HRO },
|
||||
{ ORDATA (WRU, sim_int_char, 8) },
|
||||
{ ORDATA (IOTENB, iot_enb, 32), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB cpu_mod[] = {
|
||||
@@ -380,6 +329,7 @@ extern int32 clk_sel, clk_time[4];
|
||||
|
||||
/* Restore register state */
|
||||
|
||||
if (build_devtab () != SCPE_OK) return SCPE_IERR; /* build dispatch */
|
||||
PC = saved_PC & AMASK; /* load local PC */
|
||||
C = C & CBIT;
|
||||
mask_out (pimask); /* reset int system */
|
||||
@@ -789,8 +739,7 @@ else { /* IOT */
|
||||
int_req = int_req & ~INT_ION;
|
||||
break; } /* end switch pulse */
|
||||
} /* end CPU control */
|
||||
else if ((dev_table[device].mask == 0) ||
|
||||
(dev_table[device].mask & iot_enb)) { /* normal device */
|
||||
else if (dev_table[device].routine) { /* normal device */
|
||||
iodata = dev_table[device].routine (pulse, code, AC[dstAC]);
|
||||
reason = iodata >> IOT_V_REASON;
|
||||
if (code & 1) AC[dstAC] = iodata & 0177777; }
|
||||
@@ -801,17 +750,10 @@ else { /* IOT */
|
||||
/* Simulation halted */
|
||||
|
||||
saved_PC = PC;
|
||||
pcq_r -> qptr = pcq_p; /* update pc q ptr */
|
||||
pcq_r->qptr = pcq_p; /* update pc q ptr */
|
||||
return reason;
|
||||
}
|
||||
|
||||
/* Null device */
|
||||
|
||||
int32 nulldev (int32 pulse, int32 code, int32 AC)
|
||||
{
|
||||
return stop_dev << IOT_V_REASON;
|
||||
}
|
||||
|
||||
/* New priority mask out */
|
||||
|
||||
void mask_out (int32 newmask)
|
||||
@@ -835,7 +777,7 @@ pimask = 0;
|
||||
dev_disable = 0;
|
||||
pwr_low = 0;
|
||||
pcq_r = find_reg ("PCQ", NULL, dptr);
|
||||
if (pcq_r) pcq_r -> qptr = 0;
|
||||
if (pcq_r) pcq_r->qptr = 0;
|
||||
else return SCPE_IERR;
|
||||
sim_brk_types = sim_brk_dflt = SWMASK ('E');
|
||||
return SCPE_OK;
|
||||
@@ -859,6 +801,8 @@ M[addr] = val & DMASK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Alter memory size */
|
||||
|
||||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
@@ -874,6 +818,27 @@ for (i = MEMSIZE; i < MAXMEMSIZE; i++) M[i] = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Build dispatch table */
|
||||
|
||||
t_stat build_devtab (void)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
int32 i, dn;
|
||||
|
||||
for (i = 0; i < 64; i++) { /* clr dev_table */
|
||||
dev_table[i].mask = 0;
|
||||
dev_table[i].pi = 0;
|
||||
dev_table[i].routine = NULL; }
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
||||
if (dibp = (DIB *) dptr->ctxt) { /* get DIB */
|
||||
dn = dibp->dnum; /* get dev num */
|
||||
dev_table[dn].mask = dibp->mask; /* copy entries */
|
||||
dev_table[dn].pi = dibp->pi;
|
||||
dev_table[dn].routine = dibp->routine; } }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Bootstrap routine for CPU */
|
||||
|
||||
#define BOOT_START 00000
|
||||
@@ -917,7 +882,7 @@ static const int32 boot_rom[] = {
|
||||
0000000 /* 0 ;padding */
|
||||
};
|
||||
|
||||
t_stat cpu_boot (int32 unitno)
|
||||
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
int32 i;
|
||||
extern int32 saved_PC;
|
||||
@@ -927,42 +892,6 @@ saved_PC = BOOT_START;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Device enable routine */
|
||||
|
||||
t_stat set_enb (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
|
||||
if (cptr != NULL) return SCPE_ARG;
|
||||
if ((uptr == NULL) || (val == 0)) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
iot_enb = iot_enb | val;
|
||||
if (dptr -> reset) dptr -> reset (dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Device disable routine */
|
||||
|
||||
t_stat set_dsb (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 i;
|
||||
DEVICE *dptr;
|
||||
UNIT *up;
|
||||
|
||||
if (cptr != NULL) return SCPE_ARG;
|
||||
if ((uptr == NULL) || (val == 0)) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
for (i = 0; i < dptr -> numunits; i++) { /* check units */
|
||||
up = (dptr -> units) + i;
|
||||
if ((up -> flags & UNIT_ATT) || sim_is_active (up))
|
||||
return SCPE_NOFNC; }
|
||||
iot_enb = iot_enb & ~val;
|
||||
if (dptr -> reset) dptr -> reset (dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* 1-to-1 map for I/O devices */
|
||||
|
||||
int32 MapAddr (int32 map, int32 addr)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
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.
|
||||
|
||||
03-Oct-02 RMS Added device information structure
|
||||
22-Dec-00 RMS Added Bruce Ray's second terminal support
|
||||
10-Dec-00 RMS Added Charles Owen's Eclipse support
|
||||
08-Dec-00 RMS Added Bruce Ray's plotter support
|
||||
@@ -156,8 +157,24 @@
|
||||
#define DEV_LOW 010 /* lowest intr dev */
|
||||
#define DEV_HIGH 051 /* highest intr dev */
|
||||
#define DEV_MDV 001 /* multiply/divide */
|
||||
#define DEV_MAP 003 /* MMPU control */
|
||||
#define DEV_ECC 002 /* ECC memory control */
|
||||
#define DEV_MAP 003 /* MMPU control */
|
||||
#define DEV_TTI 010 /* console input */
|
||||
#define DEV_TTO 011 /* console output */
|
||||
#define DEV_PTR 012 /* paper tape reader */
|
||||
#define DEV_PTP 013 /* paper tape punch */
|
||||
#define DEV_CLK 014 /* clock */
|
||||
#define DEV_PLT 015 /* plotter */
|
||||
#define DEV_CDR 016 /* card reader */
|
||||
#define DEV_LPT 017 /* line printer */
|
||||
#define DEV_DSK 020 /* fixed head disk */
|
||||
#define DEV_MTA 022 /* magtape */
|
||||
#define DEV_DCM 024 /* data comm mux */
|
||||
#define DEV_ADCV 030 /* A/D converter */
|
||||
#define DEV_DKP 033 /* disk pack */
|
||||
#define DEV_CAS 034 /* cassette */
|
||||
#define DEV_TTI1 050 /* second console input */
|
||||
#define DEV_TTO1 051 /* second console output */
|
||||
#define DEV_CPU 077 /* CPU control */
|
||||
|
||||
/* I/O structure
|
||||
@@ -168,6 +185,9 @@
|
||||
mask device mask for busy, done (simulator representation)
|
||||
pi pi disable bit (hardware representation)
|
||||
routine IOT action routine
|
||||
|
||||
dev_table is populated at run time from the device information
|
||||
blocks in each device.
|
||||
*/
|
||||
|
||||
struct ndev {
|
||||
@@ -176,6 +196,15 @@ struct ndev {
|
||||
int32 (*routine)(); /* dispatch routine */
|
||||
};
|
||||
|
||||
struct nova_dib {
|
||||
int32 dnum; /* device number */
|
||||
int32 mask; /* done/busy mask */
|
||||
int32 pi; /* assigned pi bit */
|
||||
int32 (*routine)(); /* dispatch routine */
|
||||
};
|
||||
|
||||
typedef struct nova_dib DIB;
|
||||
|
||||
/* Device flags (simulator representation)
|
||||
|
||||
Priority (for INTA) runs from low numbers to high
|
||||
|
||||
101
NOVA/nova_dkp.c
101
NOVA/nova_dkp.c
@@ -25,6 +25,7 @@
|
||||
|
||||
dkp moving head disk
|
||||
|
||||
08-Oct-02 RMS Added DIB
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
30-Nov-01 RMS Added read only unit, extended SET/SHOW support
|
||||
24-Nov-01 RMS Changed FLG, CAPAC to arrays
|
||||
@@ -47,7 +48,6 @@
|
||||
#define UNIT_V_DTYPE (UNIT_V_UF + 1) /* disk type */
|
||||
#define UNIT_M_DTYPE 017
|
||||
#define UNIT_V_AUTO (UNIT_V_UF + 5) /* autosize */
|
||||
#define UNIT_W_UF 7 /* saved flag width */
|
||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
||||
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
||||
@@ -274,16 +274,20 @@ struct drvtyp drv_tab[] = {
|
||||
|
||||
extern uint16 M[];
|
||||
extern UNIT cpu_unit;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 dkp_ma = 0; /* memory address */
|
||||
int32 dkp_ussc = 0; /* unit/sf/sc/cnt */
|
||||
int32 dkp_fccy = 0; /* flags/cylinder */
|
||||
int32 dkp_sta = 0; /* status register */
|
||||
int32 dkp_swait = 100; /* seek latency */
|
||||
int32 dkp_rwait = 100; /* rotate latency */
|
||||
|
||||
DEVICE dkp_dev;
|
||||
int32 dkp (int32 pulse, int32 code, int32 AC);
|
||||
t_stat dkp_svc (UNIT *uptr);
|
||||
t_stat dkp_reset (DEVICE *dptr);
|
||||
t_stat dkp_boot (int32 unitno);
|
||||
t_stat dkp_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat dkp_attach (UNIT *uptr, char *cptr);
|
||||
t_stat dkp_go (void);
|
||||
t_stat dkp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
@@ -296,6 +300,8 @@ t_stat dkp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
dkp_mod DKP modifier list
|
||||
*/
|
||||
|
||||
DIB dkp_dib = { DEV_DKP, INT_DKP, PI_DKP, &dkp };
|
||||
|
||||
UNIT dkp_unit[] = {
|
||||
{ UDATA (&dkp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
|
||||
UNIT_ROABLE+(TYPE_D31 << UNIT_V_DTYPE), SIZE_D31) },
|
||||
@@ -317,11 +323,8 @@ REG dkp_reg[] = {
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_DKP) },
|
||||
{ DRDATA (STIME, dkp_swait, 24), PV_LEFT },
|
||||
{ DRDATA (RTIME, dkp_rwait, 24), PV_LEFT },
|
||||
{ URDATA (FLG, dkp_unit[0].flags, 8, UNIT_W_UF, UNIT_V_UF - 1,
|
||||
DKP_NUMDR, REG_HRO) },
|
||||
{ URDATA (CAPAC, dkp_unit[0].capac, 10, 31, 0,
|
||||
DKP_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_DKP), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB dkp_mod[] = {
|
||||
@@ -419,15 +422,14 @@ MTAB dkp_mod[] = {
|
||||
NULL, "4231", &dkp_set_size },
|
||||
{ (UNIT_AUTO+UNIT_DTYPE), (TYPE_4231 << UNIT_V_DTYPE),
|
||||
NULL, "3330", &dkp_set_size },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_DKP, NULL, "ENABLED", &set_enb },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_DKP, NULL, "DISABLED", &set_dsb },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE dkp_dev = {
|
||||
"DP", dkp_unit, dkp_reg, dkp_mod,
|
||||
DKP_NUMDR, 8, 30, 1, 8, 16,
|
||||
NULL, NULL, &dkp_reset,
|
||||
&dkp_boot, &dkp_attach, NULL };
|
||||
&dkp_boot, &dkp_attach, NULL,
|
||||
&dkp_dib, DEV_DISABLE };
|
||||
|
||||
/* IOT routine */
|
||||
|
||||
@@ -437,13 +439,13 @@ UNIT *uptr;
|
||||
int32 u, rval, dtype;
|
||||
|
||||
rval = 0;
|
||||
uptr = dkp_dev.units + GET_UNIT (dkp_ussc); /* select unit */
|
||||
dtype = GET_DTYPE (uptr -> flags); /* get drive type */
|
||||
uptr = dkp_dev.units + GET_UNIT (dkp_ussc); /* select unit */
|
||||
dtype = GET_DTYPE (uptr->flags); /* get drive type */
|
||||
switch (code) { /* decode IR<5:7> */
|
||||
case ioDIA: /* DIA */
|
||||
dkp_sta = dkp_sta & ~STA_DYN; /* clear dynamic */
|
||||
if (uptr -> flags & UNIT_ATT) dkp_sta = dkp_sta | STA_DRDY;
|
||||
if (uptr -> CYL >= drv_tab[dtype].cyl)
|
||||
if (uptr->flags & UNIT_ATT) dkp_sta = dkp_sta | STA_DRDY;
|
||||
if (uptr->CYL >= drv_tab[dtype].cyl)
|
||||
dkp_sta = dkp_sta | STA_CYL; /* bad cylinder? */
|
||||
if (dkp_sta & STA_EFLGS) dkp_sta = dkp_sta | STA_ERR;
|
||||
rval = dkp_sta;
|
||||
@@ -454,7 +456,7 @@ case ioDOA: /* DOA */
|
||||
dkp_sta = dkp_sta & ~(AC & FCCY_FLAGS); }
|
||||
break;
|
||||
case ioDIB: /* DIB */
|
||||
rval = dkp_ma; /* return buf addr */
|
||||
rval = dkp_ma; /* return buf addr */
|
||||
break;
|
||||
case ioDOB: /* DOB */
|
||||
if ((dev_busy & INT_DKP) == 0) dkp_ma =
|
||||
@@ -510,10 +512,10 @@ int32 newcyl, func, u, dtype;
|
||||
dkp_sta = dkp_sta & ~STA_EFLGS; /* clear errors */
|
||||
u = GET_UNIT (dkp_ussc); /* get unit number */
|
||||
uptr = dkp_dev.units + u; /* get unit */
|
||||
if (((uptr -> flags & UNIT_ATT) == 0) || sim_is_active (uptr)) {
|
||||
if (((uptr->flags & UNIT_ATT) == 0) || sim_is_active (uptr)) {
|
||||
dkp_sta = dkp_sta | STA_ERR; /* attached or busy? */
|
||||
return FALSE; }
|
||||
dtype = GET_DTYPE (uptr -> flags); /* get drive type */
|
||||
dtype = GET_DTYPE (uptr->flags); /* get drive type */
|
||||
func = GET_CMD (dkp_fccy, dtype); /* get function */
|
||||
newcyl = GET_CYL (dkp_fccy, dtype); /* get cylinder */
|
||||
switch (func) { /* decode command */
|
||||
@@ -524,11 +526,11 @@ case FCCY_RECAL: /* recalibrate */
|
||||
newcyl = 0;
|
||||
func = FCCY_SEEK;
|
||||
case FCCY_SEEK: /* seek */
|
||||
sim_activate (uptr, dkp_swait * abs (newcyl - uptr -> CYL));
|
||||
sim_activate (uptr, dkp_swait * abs (newcyl - uptr->CYL));
|
||||
dkp_sta = dkp_sta | (STA_SEEK0 >> u); /* set seeking */
|
||||
uptr -> CYL = newcyl; /* on cylinder */
|
||||
uptr->CYL = newcyl; /* on cylinder */
|
||||
break; } /* end case command */
|
||||
uptr -> FUNC = func; /* save command */
|
||||
uptr->FUNC = func; /* save command */
|
||||
return TRUE; /* no error */
|
||||
}
|
||||
|
||||
@@ -546,16 +548,17 @@ return TRUE; /* no error */
|
||||
|
||||
t_stat dkp_svc (UNIT *uptr)
|
||||
{
|
||||
int32 sc, sa, xcsa, awc, bda;
|
||||
int32 sx, dx, pa;
|
||||
int32 dtype, u, err, newsect, newsurf;
|
||||
int32 sc, sa, xcsa, bda;
|
||||
int32 sx, dx, pa, u;
|
||||
int32 dtype, err, newsect, newsurf;
|
||||
uint32 awc;
|
||||
t_stat rval;
|
||||
static uint16 tbuf[DKP_NUMWD]; /* transfer buffer */
|
||||
|
||||
rval = SCPE_OK;
|
||||
dtype = GET_DTYPE (uptr -> flags); /* get drive type */
|
||||
if (uptr -> FUNC == FCCY_SEEK) { /* seek? */
|
||||
if (uptr -> CYL >= drv_tab[dtype].cyl) /* bad cylinder? */
|
||||
dtype = GET_DTYPE (uptr->flags); /* get drive type */
|
||||
if (uptr->FUNC == FCCY_SEEK) { /* seek? */
|
||||
if (uptr->CYL >= drv_tab[dtype].cyl) /* bad cylinder? */
|
||||
dkp_sta = dkp_sta | STA_ERR | STA_CYL;
|
||||
dev_done = dev_done | INT_DKP; /* set done */
|
||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||
@@ -564,52 +567,52 @@ if (uptr -> FUNC == FCCY_SEEK) { /* seek? */
|
||||
& ~(STA_SEEK0 >> u); /* clear seeking */
|
||||
return SCPE_OK; }
|
||||
|
||||
if (((uptr -> flags & UNIT_ATT) == 0) || /* not attached? */
|
||||
((uptr -> flags & UNIT_WPRT) && (uptr -> FUNC == FCCY_WRITE)))
|
||||
if (((uptr->flags & UNIT_ATT) == 0) || /* not attached? */
|
||||
((uptr->flags & UNIT_WPRT) && (uptr->FUNC == FCCY_WRITE)))
|
||||
dkp_sta = dkp_sta | STA_DONE | STA_ERR; /* error */
|
||||
|
||||
else if ((uptr -> CYL >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||
else if ((uptr->CYL >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||
(GET_SURF (dkp_ussc, dtype) >= drv_tab[dtype].surf) || /* bad surface */
|
||||
(GET_SECT (dkp_ussc, dtype) >= drv_tab[dtype].sect)) /* or bad sector? */
|
||||
dkp_sta = dkp_sta | STA_DONE | STA_ERR | STA_UNS;
|
||||
|
||||
else if (GET_CYL (dkp_fccy, dtype) != uptr -> CYL) /* address error? */
|
||||
else if (GET_CYL (dkp_fccy, dtype) != uptr->CYL) /* address error? */
|
||||
dkp_sta = dkp_sta | STA_DONE | STA_ERR | STA_UNS;
|
||||
|
||||
else { sc = 16 - GET_COUNT (dkp_ussc); /* get sector count */
|
||||
sa = GET_SA (uptr -> CYL, GET_SURF (dkp_ussc, dtype),
|
||||
sa = GET_SA (uptr->CYL, GET_SURF (dkp_ussc, dtype),
|
||||
GET_SECT (dkp_ussc, dtype), dtype); /* get disk block */
|
||||
xcsa = GET_SA (uptr -> CYL + 1, 0, 0, dtype); /* get next cyl addr */
|
||||
xcsa = GET_SA (uptr->CYL + 1, 0, 0, dtype); /* get next cyl addr */
|
||||
if ((sa + sc) > xcsa ) { /* across cylinder? */
|
||||
sc = xcsa - sa; /* limit transfer */
|
||||
dkp_sta = dkp_sta | STA_XCY; } /* xcyl error */
|
||||
bda = sa * DKP_NUMWD * sizeof (short); /* to words, bytes */
|
||||
|
||||
err = fseek (uptr -> fileref, bda, SEEK_SET); /* position drive */
|
||||
err = fseek (uptr->fileref, bda, SEEK_SET); /* position drive */
|
||||
|
||||
if (uptr -> FUNC == FCCY_READ) { /* read? */
|
||||
if (uptr->FUNC == FCCY_READ) { /* read? */
|
||||
for (sx = 0; sx < sc; sx++) { /* loop thru sectors */
|
||||
awc = fxread (tbuf, sizeof(uint16), DKP_NUMWD, uptr -> fileref);
|
||||
awc = fxread (tbuf, sizeof(uint16), DKP_NUMWD, uptr->fileref);
|
||||
for ( ; awc < DKP_NUMWD; awc++) tbuf[awc] = 0;
|
||||
if (err = ferror (uptr -> fileref)) break;
|
||||
if (err = ferror (uptr->fileref)) break;
|
||||
for (dx = 0; dx < DKP_NUMWD; dx++) { /* loop thru buffer */
|
||||
pa = MapAddr (0, dkp_ma);
|
||||
if (MEM_ADDR_OK (pa)) M[pa] = tbuf[dx];
|
||||
dkp_ma = (dkp_ma + 1) & AMASK; } } }
|
||||
|
||||
if (uptr -> FUNC == FCCY_WRITE) { /* write? */
|
||||
if (uptr->FUNC == FCCY_WRITE) { /* write? */
|
||||
for (sx = 0; sx < sc; sx++) { /* loop thru sectors */
|
||||
for (dx = 0; dx < DKP_NUMWD; dx++) { /* loop into buffer */
|
||||
pa = MapAddr (0, dkp_ma);
|
||||
tbuf[dx] = M[pa];
|
||||
dkp_ma = (dkp_ma + 1) & AMASK; }
|
||||
fxwrite (tbuf, sizeof(int16), DKP_NUMWD, uptr -> fileref);
|
||||
if (err = ferror (uptr -> fileref)) break; } }
|
||||
fxwrite (tbuf, sizeof(int16), DKP_NUMWD, uptr->fileref);
|
||||
if (err = ferror (uptr->fileref)) break; } }
|
||||
|
||||
if (err != 0) {
|
||||
perror ("DKP I/O error");
|
||||
rval = SCPE_IOERR; }
|
||||
clearerr (uptr -> fileref);
|
||||
clearerr (uptr->fileref);
|
||||
|
||||
sa = sa + sc; /* update sector addr */
|
||||
newsect = sa % drv_tab[dtype].sect;
|
||||
@@ -640,7 +643,7 @@ dkp_fccy = dkp_ussc = dkp_ma = dkp_sta = 0; /* clear registers */
|
||||
for (u = 0; u < DKP_NUMDR; u++) { /* loop thru units */
|
||||
uptr = dkp_dev.units + u;
|
||||
sim_cancel (uptr); /* cancel activity */
|
||||
uptr -> CYL = uptr -> FUNC = 0; }
|
||||
uptr->CYL = uptr->FUNC = 0; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -651,15 +654,15 @@ t_stat dkp_attach (UNIT *uptr, char *cptr)
|
||||
int32 i, p;
|
||||
t_stat r;
|
||||
|
||||
uptr -> capac = drv_tab[GET_DTYPE (uptr -> flags)].size;
|
||||
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||
r = attach_unit (uptr, cptr);
|
||||
if ((r != SCPE_OK) || ((uptr -> flags & UNIT_AUTO) == 0)) return r;
|
||||
if (fseek (uptr -> fileref, 0, SEEK_END)) return SCPE_OK;
|
||||
if ((p = ftell (uptr -> fileref)) == 0) return SCPE_OK;
|
||||
if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r;
|
||||
if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK;
|
||||
if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK;
|
||||
for (i = 0; drv_tab[i].sect != 0; i++) {
|
||||
if (p <= (drv_tab[i].size * (int) sizeof (short))) {
|
||||
uptr -> flags = (uptr -> flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE);
|
||||
uptr -> capac = drv_tab[i].size;
|
||||
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE);
|
||||
uptr->capac = drv_tab[i].size;
|
||||
return SCPE_OK; } }
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -668,8 +671,8 @@ return SCPE_OK;
|
||||
|
||||
t_stat dkp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
if (uptr -> flags & UNIT_ATT) return SCPE_ALATT;
|
||||
uptr -> capac = drv_tab[GET_DTYPE (val)].size;
|
||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||
uptr->capac = drv_tab[GET_DTYPE (val)].size;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -704,7 +707,7 @@ static const int32 boot_rom[] = {
|
||||
0174000 /* REDCMD: 174000 */
|
||||
};
|
||||
|
||||
t_stat dkp_boot (int32 unitno)
|
||||
t_stat dkp_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
int32 i, dtype;
|
||||
extern int32 saved_PC;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: Nova Simulator Usage
|
||||
Date: 15-Jun-2002
|
||||
Date: 15-Nov-2002
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
@@ -37,11 +37,11 @@ This memorandum documents the Nova simulator.
|
||||
1. Simulator Files
|
||||
|
||||
sim/ sim_defs.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
scp_tty.c
|
||||
sim_rev.c
|
||||
sim_sock.c
|
||||
sim_tmxr.c
|
||||
|
||||
@@ -76,8 +76,6 @@ DK head-per-track disk controller
|
||||
DP moving head disk controller with four drives
|
||||
MT magnetic tape controller with eight drives
|
||||
|
||||
The TTI1/TTO1, PLT, DK, DP, and MT devices can be set DISABLED.
|
||||
|
||||
The Nova simulator implements these unique stop conditions:
|
||||
|
||||
- reference to undefined I/O device, and STOP_DEV is set
|
||||
@@ -89,14 +87,21 @@ The Nova simulator implements these unique stop conditions:
|
||||
The Nova loader supports standard binary format tapes. The DUMP command
|
||||
is not implemented.
|
||||
|
||||
Most devices can be disabled or enabled, by the commands:
|
||||
|
||||
SET <dev> DISABLED
|
||||
SET <dev> ENABLED
|
||||
|
||||
All devices are enabled by default.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The only CPU options are the presence of the optional instructions
|
||||
and the size of main memory.
|
||||
|
||||
SET CPU NOVA4 enable Nova4 instructions
|
||||
SET CPU NOVA3 enable Nova3 instructions
|
||||
SET CPU MDV enable multiply/divide
|
||||
SET CPU NOVA3 enable Nova3 instructions
|
||||
SET CPU NOVA4 enable Nova4 instructions
|
||||
SET CPU NONE disable all optional instructions
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
@@ -505,8 +510,7 @@ Error handling is as follows:
|
||||
|
||||
not attached tape not ready
|
||||
|
||||
end of file (read or space) end of physical tape
|
||||
(write) ignored
|
||||
end of file bad tape
|
||||
|
||||
OS I/O error report error and stop
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
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.
|
||||
|
||||
dsk fixed head disk
|
||||
dsk fixed head disk
|
||||
|
||||
03-Oct-02 RMS Added DIB
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
23-Aug-01 RMS Fixed bug in write watermarking
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
@@ -79,16 +80,20 @@ static const int32 sector_map[] = {
|
||||
|
||||
extern uint16 M[];
|
||||
extern UNIT cpu_unit;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 dsk_stat = 0; /* status register */
|
||||
int32 dsk_da = 0; /* disk address */
|
||||
int32 dsk_ma = 0; /* memory address */
|
||||
int32 dsk_wlk = 0; /* wrt lock switches */
|
||||
int32 dsk_stopioe = 1; /* stop on error */
|
||||
int32 dsk_time = 100; /* time per sector */
|
||||
|
||||
DEVICE dsk_dev;
|
||||
int32 dsk (int32 pulse, int32 code, int32 AC);
|
||||
t_stat dsk_svc (UNIT *uptr);
|
||||
t_stat dsk_reset (DEVICE *dptr);
|
||||
t_stat dsk_boot (int32 unitno);
|
||||
t_stat dsk_boot (int32 unitno, DEVICE *dptr);
|
||||
|
||||
/* DSK data structures
|
||||
|
||||
@@ -97,6 +102,8 @@ t_stat dsk_boot (int32 unitno);
|
||||
dsk_reg register list
|
||||
*/
|
||||
|
||||
DIB dsk_dib = { DEV_DSK, INT_DSK, PI_DSK, &dsk };
|
||||
|
||||
UNIT dsk_unit =
|
||||
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
|
||||
DSK_SIZE) };
|
||||
@@ -112,19 +119,14 @@ REG dsk_reg[] = {
|
||||
{ ORDATA (WLK, dsk_wlk, 8) },
|
||||
{ DRDATA (TIME, dsk_time, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, dsk_stopioe, 0) },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_DSK), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB dsk_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, INT_DSK, NULL, "ENABLED", &set_enb },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_DSK, NULL, "DISABLED", &set_dsb },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE dsk_dev = {
|
||||
"DK", &dsk_unit, dsk_reg, dsk_mod,
|
||||
"DK", &dsk_unit, dsk_reg, NULL,
|
||||
1, 8, 21, 1, 8, 16,
|
||||
NULL, NULL, &dsk_reset,
|
||||
&dsk_boot, NULL, NULL };
|
||||
&dsk_boot, NULL, NULL,
|
||||
&dsk_dib, DEV_DISABLE };
|
||||
|
||||
/* IOT routine */
|
||||
|
||||
@@ -184,23 +186,23 @@ dev_busy = dev_busy & ~INT_DSK; /* clear busy */
|
||||
dev_done = dev_done | INT_DSK; /* set done */
|
||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||
|
||||
if ((uptr -> flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
dsk_stat = DSKS_ERR + DSKS_NSD; /* set status */
|
||||
return IORETURN (dsk_stopioe, SCPE_UNATT); }
|
||||
|
||||
da = dsk_da * DSK_NUMWD; /* calc disk addr */
|
||||
if (uptr -> FUNC == iopS) { /* read? */
|
||||
if (uptr->FUNC == iopS) { /* read? */
|
||||
for (i = 0; i < DSK_NUMWD; i++) { /* copy sector */
|
||||
pa = MapAddr (0, (dsk_ma + i) & AMASK); /* map address */
|
||||
if (MEM_ADDR_OK (pa)) M[pa] =
|
||||
*(((int16 *) uptr -> filebuf) + da + i); }
|
||||
*(((int16 *) uptr->filebuf) + da + i); }
|
||||
dsk_ma = (dsk_ma + DSK_NUMWD) & AMASK; }
|
||||
if (uptr -> FUNC == iopP) { /* write? */
|
||||
if (uptr->FUNC == iopP) { /* write? */
|
||||
for (i = 0; i < DSK_NUMWD; i++) { /* copy sector */
|
||||
pa = MapAddr (0, (dsk_ma + i) & AMASK); /* map address */
|
||||
*(((int16 *) uptr -> filebuf) + da + i) = M[pa]; }
|
||||
if (((t_addr) (da + i)) >= uptr -> hwmark) /* past end? */
|
||||
uptr -> hwmark = da + i + 1; /* upd hwmark */
|
||||
*(((int16 *) uptr->filebuf) + da + i) = M[pa]; }
|
||||
if (((t_addr) (da + i)) >= uptr->hwmark) /* past end? */
|
||||
uptr->hwmark = da + i + 1; /* upd hwmark */
|
||||
dsk_ma = (dsk_ma + DSK_NUMWD + 3) & AMASK; }
|
||||
|
||||
dsk_stat = 0; /* set status */
|
||||
@@ -234,7 +236,7 @@ static const int32 boot_rom[] = {
|
||||
000377, /* JMP 377 */
|
||||
};
|
||||
|
||||
t_stat dsk_boot (int32 unitno)
|
||||
t_stat dsk_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
int32 i;
|
||||
extern int32 saved_PC;
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
#include "nova_defs.h"
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 lpt_stopioe = 0; /* stop on error */
|
||||
|
||||
int32 lpt (int32 pulse, int32 code, int32 AC);
|
||||
t_stat lpt_svc (UNIT *uptr);
|
||||
t_stat lpt_reset (DEVICE *dptr);
|
||||
|
||||
@@ -42,6 +45,8 @@ t_stat lpt_reset (DEVICE *dptr);
|
||||
lpt_reg LPT register list
|
||||
*/
|
||||
|
||||
DIB lpt_dib = { DEV_LPT, INT_LPT, PI_LPT, &lpt };
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
@@ -60,7 +65,8 @@ DEVICE lpt_dev = {
|
||||
"LPT", &lpt_unit, lpt_reg, NULL,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &lpt_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&lpt_dib, DEV_DISABLE };
|
||||
|
||||
/* IOT routine */
|
||||
|
||||
|
||||
286
NOVA/nova_mta.c
286
NOVA/nova_mta.c
@@ -25,6 +25,10 @@
|
||||
|
||||
mta magnetic tape
|
||||
|
||||
30-Oct-02 RMS Fixed BOT handling, added error record handling
|
||||
08-Oct-02 RMS Added DIB
|
||||
30-Sep-02 RMS Revamped error handling
|
||||
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 enable/disable support
|
||||
@@ -59,10 +63,10 @@
|
||||
|
||||
#define MTA_NUMDR 8 /* #drives */
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_V_PNU (UNIT_V_UF + 1) /* pos not updated */
|
||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||
#define UNIT_W_UF 2 /* saved flags width */
|
||||
#define UNIT_PNU (1 << UNIT_V_PNU)
|
||||
#define USTAT u3 /* unit status */
|
||||
#define UNUM u4 /* unit number */
|
||||
#define MTA_MAXFR (1 << 16) /* max record lnt */
|
||||
#define DTSIZE (1 << 14) /* max data xfer */
|
||||
#define DTMASK (DTSIZE - 1)
|
||||
@@ -93,7 +97,7 @@
|
||||
#define GET_CMD(x) (((x) >> CU_V_CMD) & CU_M_CMD)
|
||||
#define GET_UNIT(x) (((x) >> CU_V_UNIT) & CU_M_UNIT)
|
||||
|
||||
/* Status 1 - stored in mta_sta<31:16> or (*) uptr -> USTAT<31:16> */
|
||||
/* Status 1 - stored in mta_sta<31:16> or (*) uptr->USTAT<31:16> */
|
||||
|
||||
#define STA_ERR1 (0100000u << 16) /* error */
|
||||
#define STA_DLT (0040000 << 16) /* data late */
|
||||
@@ -111,7 +115,7 @@
|
||||
#define STA_ODD (0000002 << 16) /* odd character */
|
||||
#define STA_RDY (0000001 << 16) /* *drive ready */
|
||||
|
||||
/* Status 2 - stored in mta_sta<15:0> or (*) uptr -> USTAT<15:0> */
|
||||
/* Status 2 - stored in mta_sta<15:0> or (*) uptr->USTAT<15:0> */
|
||||
|
||||
#define STA_ERR2 0100000 /* error */
|
||||
#define STA_RWY 0040000 /* runaway tape */
|
||||
@@ -141,7 +145,8 @@
|
||||
|
||||
extern uint16 M[];
|
||||
extern UNIT cpu_unit;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 mta_ma = 0; /* memory address */
|
||||
int32 mta_wc = 0; /* word count */
|
||||
int32 mta_cu = 0; /* command/unit */
|
||||
@@ -149,14 +154,19 @@ int32 mta_sta = 0; /* status register */
|
||||
int32 mta_ep = 0; /* enable polling */
|
||||
int32 mta_cwait = 100; /* command latency */
|
||||
int32 mta_rwait = 100; /* record latency */
|
||||
|
||||
DEVICE mta_dev;
|
||||
int32 mta (int32 pulse, int32 code, int32 AC);
|
||||
t_stat mta_svc (UNIT *uptr);
|
||||
t_stat mta_reset (DEVICE *dptr);
|
||||
t_stat mta_boot (int32 unitno);
|
||||
t_stat mta_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat mta_attach (UNIT *uptr, char *cptr);
|
||||
t_stat mta_detach (UNIT *uptr);
|
||||
int32 mta_updcsta (UNIT *uptr);
|
||||
void mta_upddsta (UNIT *uptr, int32 newsta);
|
||||
t_stat mta_vlock (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_bool mta_rdlntf (UNIT *uptr, t_mtrlnt *tbc, int32 *err);
|
||||
t_bool mta_rdlntr (UNIT *uptr, t_mtrlnt *tbc, int32 *err);
|
||||
|
||||
static const int ctype[32] = { /* c vs r timing */
|
||||
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
|
||||
@@ -170,6 +180,8 @@ static const int ctype[32] = { /* c vs r timing */
|
||||
mta_mod MTA modifier list
|
||||
*/
|
||||
|
||||
DIB mta_dib = { DEV_MTA, INT_MTA, PI_MTA, &mta };
|
||||
|
||||
UNIT mta_unit[] = {
|
||||
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
|
||||
@@ -196,23 +208,19 @@ REG mta_reg[] = {
|
||||
{ URDATA (UST, mta_unit[0].USTAT, 8, 32, 0, MTA_NUMDR, 0) },
|
||||
{ URDATA (POS, mta_unit[0].pos, 8, 32, 0,
|
||||
MTA_NUMDR, REG_RO | PV_LEFT) },
|
||||
{ URDATA (FLG, mta_unit[0].flags, 8, UNIT_W_UF, UNIT_V_UF - 1,
|
||||
MTA_NUMDR, REG_HRO) },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_MTA), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB mta_mod[] = {
|
||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", &mta_vlock },
|
||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", &mta_vlock },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_MTA, NULL, "ENABLED", &set_enb },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_MTA, NULL, "DISABLED", &set_dsb },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE mta_dev = {
|
||||
"MT", mta_unit, mta_reg, mta_mod,
|
||||
MTA_NUMDR, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mta_reset,
|
||||
&mta_boot, &mta_attach, &mta_detach };
|
||||
&mta_boot, &mta_attach, &mta_detach,
|
||||
&mta_dib, DEV_DISABLE };
|
||||
|
||||
/* IOT routine */
|
||||
|
||||
@@ -252,13 +260,13 @@ switch (pulse) { /* decode IR<8:9> */
|
||||
case iopS: /* start */
|
||||
c = GET_CMD (mta_cu); /* get command */
|
||||
if (dev_busy & INT_MTA) break; /* ignore if busy */
|
||||
if ((uptr -> USTAT & STA_RDY) == 0) { /* drive not ready? */
|
||||
if ((uptr->USTAT & STA_RDY) == 0) { /* drive not ready? */
|
||||
mta_sta = mta_sta | STA_ILL; /* illegal op */
|
||||
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
|
||||
dev_done = dev_done | INT_MTA; /* set done */
|
||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable); }
|
||||
else if ((c == CU_REWIND) || (c == CU_UNLOAD)) { /* rewind, unload? */
|
||||
mta_upddsta (uptr, (uptr -> USTAT & /* update status */
|
||||
mta_upddsta (uptr, (uptr->USTAT & /* update status */
|
||||
~(STA_BOT | STA_EOF | STA_EOT | STA_RDY)) | STA_REW);
|
||||
sim_activate (uptr, mta_rwait); /* start IO */
|
||||
if (c == CU_UNLOAD) detach_unit (uptr); }
|
||||
@@ -267,7 +275,7 @@ case iopS: /* start */
|
||||
dev_done = dev_done & ~INT_MTA; /* clear done */
|
||||
int_req = int_req & ~INT_MTA; /* clear int */
|
||||
if (ctype[c]) sim_activate (uptr, mta_cwait);
|
||||
else { mta_upddsta (uptr, uptr -> USTAT &
|
||||
else { mta_upddsta (uptr, uptr->USTAT &
|
||||
~(STA_BOT | STA_EOF | STA_EOT | STA_RDY));
|
||||
sim_activate (uptr, mta_rwait); } }
|
||||
mta_updcsta (uptr); /* update status */
|
||||
@@ -275,8 +283,8 @@ case iopS: /* start */
|
||||
case iopC: /* clear */
|
||||
for (u = 0; u < MTA_NUMDR; u++) { /* loop thru units */
|
||||
uptr = mta_dev.units + u; /* cancel IO */
|
||||
if (sim_is_active (uptr) && !(uptr -> USTAT & STA_REW)) {
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY);
|
||||
if (sim_is_active (uptr) && !(uptr->USTAT & STA_REW)) {
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
|
||||
sim_cancel (uptr); } }
|
||||
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
|
||||
dev_done = dev_done & ~INT_MTA; /* clear done */
|
||||
@@ -295,32 +303,32 @@ return rval;
|
||||
|
||||
t_stat mta_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c, i, p, u, pa, err;
|
||||
t_stat rval;
|
||||
t_mtrlnt cbc, tbc, wc;
|
||||
int32 c, p, pa, err, pnu, u;
|
||||
t_mtrlnt i, cbc, tbc, wc;
|
||||
uint16 c1, c2;
|
||||
static uint8 dbuf[2 * DTSIZE];
|
||||
static t_mtrlnt bceof = { 0 };
|
||||
|
||||
rval = SCPE_OK;
|
||||
u = uptr -> UNUM; /* get unit number */
|
||||
if (uptr -> USTAT & STA_REW) { /* rewind? */
|
||||
uptr -> pos = 0; /* update position */
|
||||
mta_upddsta (uptr, (uptr -> USTAT & ~STA_REW) | STA_BOT | STA_RDY);
|
||||
if (u == GET_UNIT (mta_cu)) mta_updcsta (uptr);
|
||||
return rval; }
|
||||
static t_mtrlnt bceof = { MTR_TMK };
|
||||
|
||||
err = 0;
|
||||
u = uptr - mta_dev.units; /* get unit number */
|
||||
pnu = MT_TST_PNU (uptr); /* get pos not upd */
|
||||
MT_CLR_PNU (uptr); /* and clear */
|
||||
if (uptr->USTAT & STA_REW) { /* rewind? */
|
||||
uptr->pos = 0; /* update position */
|
||||
mta_upddsta (uptr, (uptr->USTAT & ~STA_REW) | STA_BOT | STA_RDY);
|
||||
if (u == GET_UNIT (mta_cu)) mta_updcsta (uptr);
|
||||
return SCPE_OK; }
|
||||
|
||||
c = GET_CMD (mta_cu); /* command */
|
||||
wc = DTSIZE - (mta_wc & DTMASK); /* io wc */
|
||||
|
||||
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
mta_upddsta (uptr, 0); /* unit off line */
|
||||
mta_sta = mta_sta | STA_ILL; } /* illegal operation */
|
||||
|
||||
else if ((uptr -> flags & UNIT_WPRT) && /* write locked? */
|
||||
else if ((uptr->flags & UNIT_WPRT) && /* write locked? */
|
||||
((c == CU_WRITE) || (c == CU_WREOF) || (c == CU_ERASE))) {
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_WLK | STA_RDY);
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_WLK | STA_RDY);
|
||||
mta_sta = mta_sta | STA_ILL; } /* illegal operation */
|
||||
|
||||
else switch (c) { /* case on command */
|
||||
@@ -328,35 +336,28 @@ case CU_CMODE: /* controller mode */
|
||||
mta_ep = mta_cu & CU_EP;
|
||||
break;
|
||||
case CU_DMODE: /* drive mode */
|
||||
if (uptr -> pos) mta_sta = mta_sta | STA_ILL; /* must be BOT */
|
||||
if (uptr->pos) mta_sta = mta_sta | STA_ILL; /* must be BOT */
|
||||
else mta_upddsta (uptr, (mta_cu & CU_PE)? /* update drv status */
|
||||
uptr -> USTAT | STA_PEM: uptr -> USTAT & ~ STA_PEM);
|
||||
uptr->USTAT | STA_PEM: uptr->USTAT & ~ STA_PEM);
|
||||
break;
|
||||
|
||||
/* Unit service, continued */
|
||||
|
||||
case CU_READ: /* read */
|
||||
case CU_READNS: /* read non-stop */
|
||||
fseek (uptr -> fileref, uptr -> pos, SEEK_SET);
|
||||
fxread (&tbc, sizeof (t_mtrlnt), 1, uptr -> fileref); /* read byte count */
|
||||
if ((err = ferror (uptr -> fileref)) || /* error or eof? */
|
||||
(feof (uptr -> fileref))) {
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_EOT);
|
||||
break; }
|
||||
if (tbc == 0) { /* tape mark? */
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_EOF);
|
||||
uptr -> pos = uptr -> pos + sizeof (t_mtrlnt);
|
||||
break; }
|
||||
tbc = MTRL (tbc); /* ignore error flag */
|
||||
if (mta_rdlntf (uptr, &tbc, & err)) break; /* read rec lnt, err? */
|
||||
if (tbc > MTA_MAXFR) return SCPE_MTRLNT; /* record too long? */
|
||||
cbc = wc * 2; /* expected bc */
|
||||
if (tbc & 1) mta_sta = mta_sta | STA_ODD; /* odd byte count? */
|
||||
if (tbc > cbc) mta_sta = mta_sta | STA_WCO; /* too big? */
|
||||
else { cbc = tbc; /* no, use it */
|
||||
wc = (cbc + 1) / 2; } /* adjust wc */
|
||||
i = fxread (dbuf, sizeof (int8), cbc, uptr -> fileref);
|
||||
i = fxread (dbuf, sizeof (int8), cbc, uptr->fileref);
|
||||
for ( ; i < cbc; i++) dbuf[i] = 0;
|
||||
err = ferror (uptr -> fileref);
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
|
||||
if (err = ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
break; }
|
||||
for (i = p = 0; i < wc; i++) { /* copy buf to mem */
|
||||
c1 = dbuf[p++];
|
||||
c2 = dbuf[p++];
|
||||
@@ -364,105 +365,82 @@ case CU_READNS: /* read non-stop */
|
||||
if (MEM_ADDR_OK (pa)) M[pa] = (c1 << 8) | c2;
|
||||
mta_ma = (mta_ma + 1) & AMASK; }
|
||||
mta_wc = (mta_wc + wc) & DMASK;
|
||||
uptr -> pos = uptr -> pos + ((tbc + 1) & ~1) +
|
||||
uptr->pos = uptr->pos + ((tbc + 1) & ~1) +
|
||||
(2 * sizeof (t_mtrlnt));
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY);
|
||||
break;
|
||||
|
||||
case CU_WRITE: /* write */
|
||||
fseek (uptr -> fileref, uptr -> pos, SEEK_SET);
|
||||
fseek (uptr->fileref, uptr->pos, SEEK_SET);
|
||||
tbc = wc * 2; /* io byte count */
|
||||
fxwrite (&tbc, sizeof (t_mtrlnt), 1, uptr -> fileref);
|
||||
fxwrite (&tbc, sizeof (t_mtrlnt), 1, uptr->fileref);
|
||||
for (i = p = 0; i < wc; i++) { /* copy to buffer */
|
||||
pa = MapAddr (0, mta_ma); /* map address */
|
||||
dbuf[p++] = (M[pa] >> 8) & 0377;
|
||||
dbuf[p++] = M[pa] & 0377;
|
||||
mta_ma = (mta_ma + 1) & AMASK; }
|
||||
fxwrite (dbuf, sizeof (int8), tbc, uptr -> fileref);
|
||||
fxwrite (&tbc, sizeof (t_mtrlnt), 1, uptr -> fileref);
|
||||
err = ferror (uptr -> fileref);
|
||||
mta_wc = 0;
|
||||
uptr -> pos = uptr -> pos + tbc + (2 * sizeof (t_mtrlnt));
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY);
|
||||
break;
|
||||
case CU_WREOF: /* write eof */
|
||||
fseek (uptr -> fileref, uptr -> pos, SEEK_SET);
|
||||
fxwrite (&bceof, sizeof (t_mtrlnt), 1, uptr -> fileref);
|
||||
err = ferror (uptr -> fileref);
|
||||
uptr -> pos = uptr -> pos + sizeof (t_mtrlnt);
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_EOF | STA_RDY);
|
||||
break;
|
||||
case CU_ERASE: /* erase */
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY);
|
||||
fxwrite (dbuf, sizeof (int8), tbc, uptr->fileref);
|
||||
fxwrite (&tbc, sizeof (t_mtrlnt), 1, uptr->fileref);
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
|
||||
if (err = ferror (uptr->fileref)) MT_SET_PNU (uptr); /* error? */
|
||||
else { mta_wc = 0;
|
||||
uptr->pos = uptr->pos + tbc + (2 * sizeof (t_mtrlnt)); }
|
||||
break;
|
||||
|
||||
/* Unit service, continued */
|
||||
|
||||
case CU_WREOF: /* write eof */
|
||||
fseek (uptr->fileref, uptr->pos, SEEK_SET);
|
||||
fxwrite (&bceof, sizeof (t_mtrlnt), 1, uptr->fileref);
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_EOF | STA_RDY);
|
||||
if (err = ferror (uptr->fileref)) MT_SET_PNU (uptr); /* error? */
|
||||
else uptr->pos = uptr->pos + sizeof (t_mtrlnt);
|
||||
break;
|
||||
|
||||
case CU_ERASE: /* erase */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
|
||||
break;
|
||||
|
||||
case CU_SPACEF: /* space forward */
|
||||
do { mta_wc = (mta_wc + 1) & DMASK; /* incr wc */
|
||||
fseek (uptr -> fileref, uptr -> pos, SEEK_SET);
|
||||
fxread (&tbc, sizeof (t_mtrlnt), 1, uptr -> fileref);
|
||||
if ((err = ferror (uptr -> fileref)) || /* error or eof? */
|
||||
(feof (uptr -> fileref))) {
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_EOT);
|
||||
break; }
|
||||
if (tbc == 0) { /* zero bc? */
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_EOF);
|
||||
uptr -> pos = uptr -> pos + sizeof (t_mtrlnt);
|
||||
break; }
|
||||
uptr -> pos = uptr -> pos + ((MTRL (tbc) + 1) & ~1) +
|
||||
if (mta_rdlntf (uptr, &tbc, &err)) break; /* read rec lnt, err? */
|
||||
uptr->pos = uptr->pos + ((tbc + 1) & ~1) +
|
||||
(2 * sizeof (t_mtrlnt)); }
|
||||
while (mta_wc != 0);
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY);
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
|
||||
break;
|
||||
|
||||
case CU_SPACER: /* space reverse */
|
||||
if (uptr -> pos == 0) { /* at BOT? */
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_BOT);
|
||||
break; }
|
||||
do { mta_wc = (mta_wc + 1) & DMASK; /* incr wc */
|
||||
fseek (uptr -> fileref, uptr -> pos - sizeof (t_mtrlnt),
|
||||
SEEK_SET); /* bs to reclnt */
|
||||
fxread (&tbc, sizeof (t_mtrlnt), 1, uptr -> fileref);
|
||||
if ((err = ferror (uptr -> fileref)) || /* error or eof? */
|
||||
(feof (uptr -> fileref))) {
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_BOT);
|
||||
uptr -> pos = 0;
|
||||
break; }
|
||||
if (tbc == 0) { /* zero bc? */
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_EOF);
|
||||
uptr -> pos = uptr -> pos - sizeof (t_mtrlnt);
|
||||
break; }
|
||||
uptr -> pos = uptr -> pos - ((MTRL (tbc) + 1) & ~1) -
|
||||
(2 * sizeof (t_mtrlnt));
|
||||
if (uptr -> pos == 0) { /* start of tape? */
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY | STA_BOT);
|
||||
break; } }
|
||||
if (pnu) pnu = 0; /* pos not upd? */
|
||||
else { if (mta_rdlntr (uptr, &tbc, &err)) break;
|
||||
uptr->pos = uptr->pos - ((tbc + 1) & ~1) -
|
||||
(2 * sizeof (t_mtrlnt)); } }
|
||||
while (mta_wc != 0);
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_RDY);
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
|
||||
break;
|
||||
|
||||
default: /* reserved */
|
||||
mta_sta = mta_sta | STA_ILL;
|
||||
break; } /* end case */
|
||||
|
||||
/* Unit service, continued */
|
||||
|
||||
if (err != 0) { /* I/O error */
|
||||
mta_sta = mta_sta | STA_DAE; /* flag error */
|
||||
perror ("MTA I/O error");
|
||||
rval = SCPE_IOERR;
|
||||
clearerr (uptr -> fileref); }
|
||||
if (err != 0) mta_sta = mta_sta | STA_DAE; /* I/O error */
|
||||
mta_updcsta (uptr); /* update status */
|
||||
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
|
||||
dev_done = dev_done | INT_MTA; /* set done */
|
||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||
return rval;
|
||||
if (err != 0) {
|
||||
perror ("MTA I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Update controller status */
|
||||
|
||||
int32 mta_updcsta (UNIT *uptr) /* update ctrl */
|
||||
{
|
||||
mta_sta = (mta_sta & ~(STA_DYN | STA_CLR | STA_ERR1 | STA_ERR2)) |
|
||||
(uptr -> USTAT & STA_DYN) | STA_SET;
|
||||
(uptr->USTAT & STA_DYN) | STA_SET;
|
||||
if (mta_sta & STA_EFLGS1) mta_sta = mta_sta | STA_ERR1;
|
||||
if (mta_sta & STA_EFLGS2) mta_sta = mta_sta | STA_ERR2;
|
||||
return mta_sta;
|
||||
@@ -474,17 +452,73 @@ void mta_upddsta (UNIT *uptr, int32 newsta) /* drive status */
|
||||
{
|
||||
int32 change;
|
||||
|
||||
if ((uptr -> flags & UNIT_ATT) == 0) newsta = 0; /* offline? */
|
||||
change = (uptr -> USTAT ^ newsta) & STA_MON; /* changes? */
|
||||
uptr -> USTAT = newsta & STA_DYN; /* update status */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) newsta = 0; /* offline? */
|
||||
change = (uptr->USTAT ^ newsta) & STA_MON; /* changes? */
|
||||
uptr->USTAT = newsta & STA_DYN; /* update status */
|
||||
if (change) {
|
||||
/* if (mta_ep) { /* if polling */
|
||||
/* u = uptr -> UNUM; /* unit num */
|
||||
/* u = uptr - mta_dev.units; /* unit num */
|
||||
/* mta_sta = (mta_sta & ~STA_UNIT) | (u << STA_V_UNIT);
|
||||
/* set polling interupt... } */
|
||||
mta_sta = mta_sta | STA_CHG; } /* flag change */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read record length forward - return T if error, EOM, or EOF */
|
||||
|
||||
t_bool mta_rdlntf (UNIT *uptr, t_mtrlnt *tbc, int32 *err)
|
||||
{
|
||||
fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set tape pos */
|
||||
fxread (tbc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */
|
||||
if (*err = ferror (uptr->fileref)) { /* error? */
|
||||
mta_sta = mta_sta | STA_DAE; /* data error */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return TRUE; }
|
||||
if (feof (uptr->fileref) || (*tbc == MTR_EOM)) { /* eof or eom? */
|
||||
mta_sta = mta_sta | STA_BAT; /* bad tape */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return TRUE; }
|
||||
if (*tbc == MTR_TMK) { /* tape mark? */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY | STA_EOF);
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* spc over tmk */
|
||||
return TRUE; }
|
||||
if (MTRF (*tbc)) mta_sta = mta_sta | STA_DAE; /* record in error? */
|
||||
*tbc = MTRL (*tbc); /* clear error flag */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read record length reverse - return T if error, EOM, or EOF */
|
||||
|
||||
t_bool mta_rdlntr (UNIT *uptr, t_mtrlnt *tbc, int32 *err)
|
||||
{
|
||||
if (uptr->pos < sizeof (t_mtrlnt)) { /* at BOT? */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY | STA_BOT);
|
||||
return TRUE; }
|
||||
fseek (uptr->fileref, uptr->pos - sizeof (t_mtrlnt), SEEK_SET);
|
||||
fxread (tbc, sizeof (t_mtrlnt), 1, uptr->fileref);
|
||||
if (*err = ferror (uptr->fileref)) { /* error? */
|
||||
mta_sta = mta_sta | STA_DAE; /* data error */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
|
||||
return TRUE; }
|
||||
if (feof (uptr->fileref)) { /* eof? */
|
||||
mta_sta = mta_sta | STA_BAT; /* bad tape */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
|
||||
return TRUE; }
|
||||
if (*tbc == MTR_EOM) { /* eom? */
|
||||
mta_sta = mta_sta | STA_BAT; /* bad tape */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
|
||||
uptr->pos = uptr->pos - sizeof (t_mtrlnt); /* spc over eom */
|
||||
return TRUE; }
|
||||
if (*tbc == MTR_TMK) { /* tape mark? */
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_RDY | STA_EOF);
|
||||
uptr->pos = uptr->pos - sizeof (t_mtrlnt); /* spc over tmk */
|
||||
return TRUE; }
|
||||
if (MTRF (*tbc)) mta_sta = mta_sta | STA_DAE; /* record in error? */
|
||||
*tbc = MTRL (*tbc); /* clear error flag */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
@@ -500,13 +534,13 @@ mta_cu = mta_wc = mta_ma = mta_sta = 0; /* clear registers */
|
||||
mta_ep = 0;
|
||||
for (u = 0; u < MTA_NUMDR; u++) { /* loop thru units */
|
||||
uptr = mta_dev.units + u;
|
||||
MT_CLR_PNU (uptr); /* clear pos flag */
|
||||
sim_cancel (uptr); /* cancel activity */
|
||||
uptr -> UNUM = u;
|
||||
if (uptr -> flags & UNIT_ATT) uptr -> USTAT = STA_RDY |
|
||||
(uptr -> USTAT & STA_PEM) |
|
||||
((uptr -> flags & UNIT_WPRT)? STA_WLK: 0) |
|
||||
((uptr -> pos)? 0: STA_BOT);
|
||||
else uptr -> USTAT = 0; }
|
||||
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_RDY |
|
||||
(uptr->USTAT & STA_PEM) |
|
||||
((uptr->flags & UNIT_WPRT)? STA_WLK: 0) |
|
||||
((uptr->pos)? 0: STA_BOT);
|
||||
else uptr->USTAT = 0; }
|
||||
mta_updcsta (&mta_unit[0]); /* update status */
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -519,8 +553,9 @@ t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
MT_CLR_PNU (uptr);
|
||||
if (!sim_is_active (uptr)) mta_upddsta (uptr, STA_RDY | STA_BOT | STA_PEM |
|
||||
((uptr -> flags & UNIT_WPRT)? STA_WLK: 0));
|
||||
((uptr->flags & UNIT_WPRT)? STA_WLK: 0));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -528,6 +563,7 @@ return r;
|
||||
|
||||
t_stat mta_detach (UNIT* uptr)
|
||||
{
|
||||
MT_CLR_PNU (uptr);
|
||||
if (!sim_is_active (uptr)) mta_upddsta (uptr, 0);
|
||||
return detach_unit (uptr);
|
||||
}
|
||||
@@ -536,9 +572,9 @@ return detach_unit (uptr);
|
||||
|
||||
t_stat mta_vlock (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
if ((uptr -> flags & UNIT_ATT) && val)
|
||||
mta_upddsta (uptr, uptr -> USTAT | STA_WLK);
|
||||
else mta_upddsta (uptr, uptr -> USTAT & ~STA_WLK);
|
||||
if ((uptr->flags & UNIT_ATT) && val)
|
||||
mta_upddsta (uptr, uptr->USTAT | STA_WLK);
|
||||
else mta_upddsta (uptr, uptr->USTAT & ~STA_WLK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -569,7 +605,7 @@ static const int32 boot_rom[] = {
|
||||
000010 /* REWIND: 10 */
|
||||
};
|
||||
|
||||
t_stat mta_boot (int32 unitno)
|
||||
t_stat mta_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
int32 i;
|
||||
extern int32 saved_PC;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
plt plotter
|
||||
|
||||
03-Oct-02 RMS Added DIB
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
26-Apr-01 RMS Added device enable/disable support
|
||||
@@ -33,8 +34,12 @@
|
||||
|
||||
#include "nova_defs.h"
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 plt_stopioe = 0; /* stop on error */
|
||||
|
||||
DEVICE plt_dev;
|
||||
int32 plt (int32 pulse, int32 code, int32 AC);
|
||||
t_stat plt_svc (UNIT *uptr);
|
||||
t_stat plt_reset (DEVICE *dptr);
|
||||
|
||||
@@ -45,6 +50,8 @@ t_stat plt_reset (DEVICE *dptr);
|
||||
plt_reg PLT register list
|
||||
*/
|
||||
|
||||
DIB plt_dib = { DEV_PLT, INT_PLT, PI_PLT, &plt };
|
||||
|
||||
UNIT plt_unit = {
|
||||
UDATA (&plt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
@@ -57,19 +64,14 @@ REG plt_reg[] = {
|
||||
{ DRDATA (POS, plt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, plt_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, plt_stopioe, 0) },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_PLT), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB plt_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, INT_PLT, NULL, "ENABLED", &set_enb },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_PLT, NULL, "DISABLED", &set_dsb },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE plt_dev = {
|
||||
"PLT", &plt_unit, plt_reg, plt_mod,
|
||||
"PLT", &plt_unit, plt_reg, NULL,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &plt_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&plt_dib, DEV_DISABLE };
|
||||
|
||||
/* plotter: IOT routine */
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
ptr paper tape reader
|
||||
ptp paper tape punch
|
||||
|
||||
03-Oct-02 RMS Added DIBs
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
29-Nov-01 RMS Added read only unit support
|
||||
*/
|
||||
@@ -33,7 +34,11 @@
|
||||
#include "nova_defs.h"
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
|
||||
|
||||
int32 ptr (int32 pulse, int32 code, int32 AC);
|
||||
int32 ptp (int32 pulse, int32 code, int32 AC);
|
||||
t_stat ptr_svc (UNIT *uptr);
|
||||
t_stat ptp_svc (UNIT *uptr);
|
||||
t_stat ptr_reset (DEVICE *dptr);
|
||||
@@ -46,6 +51,8 @@ t_stat ptp_reset (DEVICE *dptr);
|
||||
ptr_reg PTR register list
|
||||
*/
|
||||
|
||||
DIB ptr_dib = { DEV_PTR, INT_PTR, PI_PTR, &ptr };
|
||||
|
||||
UNIT ptr_unit = {
|
||||
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
|
||||
SERIAL_IN_WAIT };
|
||||
@@ -65,7 +72,8 @@ DEVICE ptr_dev = {
|
||||
"PTR", &ptr_unit, ptr_reg, NULL,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &ptr_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&ptr_dib, 0 };
|
||||
|
||||
/* PTP data structures
|
||||
|
||||
@@ -74,6 +82,8 @@ DEVICE ptr_dev = {
|
||||
ptp_reg PTP register list
|
||||
*/
|
||||
|
||||
DIB ptp_dib = { DEV_PTP, INT_PTP, PI_PTP, &ptp };
|
||||
|
||||
UNIT ptp_unit = {
|
||||
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
@@ -92,7 +102,8 @@ DEVICE ptp_dev = {
|
||||
"PTP", &ptp_unit, ptp_reg, NULL,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &ptp_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&ptp_dib, 0 };
|
||||
|
||||
/* Paper tape reader: IOT routine */
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
tti terminal input
|
||||
tto terminal output
|
||||
|
||||
03-Oct-02 RMS Added DIBs
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
30-Nov-01 RMS Added extended SET/SHOW support
|
||||
17-Sep-01 RMS Removed multiconsole support
|
||||
@@ -38,6 +39,9 @@
|
||||
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
|
||||
#define UNIT_DASHER (1 << UNIT_V_DASHER)
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
|
||||
int32 tti (int32 pulse, int32 code, int32 AC);
|
||||
int32 tto (int32 pulse, int32 code, int32 AC);
|
||||
t_stat tti_svc (UNIT *uptr);
|
||||
t_stat tto_svc (UNIT *uptr);
|
||||
t_stat tti_reset (DEVICE *dptr);
|
||||
@@ -52,6 +56,8 @@ t_stat ttx_setmod (UNIT *uptr, int32 val, char *cptr);
|
||||
ttx_mod TTI/TTO modifiers list
|
||||
*/
|
||||
|
||||
DIB tti_dib = { DEV_TTI, INT_TTI, PI_TTI, &tti };
|
||||
|
||||
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG tti_reg[] = {
|
||||
@@ -62,7 +68,6 @@ REG tti_reg[] = {
|
||||
{ FLDATA (INT, int_req, INT_V_TTI) },
|
||||
{ DRDATA (POS, tti_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (MODE, tti_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB ttx_mod[] = {
|
||||
@@ -74,7 +79,8 @@ DEVICE tti_dev = {
|
||||
"TTI", &tti_unit, tti_reg, ttx_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tti_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&tti_dib, 0 };
|
||||
|
||||
/* TTO data structures
|
||||
|
||||
@@ -83,6 +89,8 @@ DEVICE tti_dev = {
|
||||
tto_reg TTO register list
|
||||
*/
|
||||
|
||||
DIB tto_dib = { DEV_TTO, INT_TTO, PI_TTO, &tto };
|
||||
|
||||
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto_reg[] = {
|
||||
@@ -93,14 +101,14 @@ REG tto_reg[] = {
|
||||
{ FLDATA (INT, int_req, INT_V_TTO) },
|
||||
{ DRDATA (POS, tto_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (MODE, tto_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE tto_dev = {
|
||||
"TTO", &tto_unit, tto_reg, ttx_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tto_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&tto_dib, 0 };
|
||||
|
||||
/* Terminal input: IOT routine */
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
tti1 second terminal input
|
||||
tto1 second terminal output
|
||||
|
||||
03-Oct-02 RMS Added DIBs
|
||||
22-Aug-02 RMS Updated for changes in sim_tmxr
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
30-Dec-01 RMS Added show statistics, set disconnect
|
||||
@@ -44,11 +46,14 @@
|
||||
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
|
||||
#define UNIT_DASHER (1 << UNIT_V_DASHER)
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
extern int32 tmxr_poll; /* calibrated poll */
|
||||
TMLN tt1_ldsc = { 0 }; /* line descriptors */
|
||||
TMXR tt_desc = { 1, 0, &tt1_ldsc }; /* mux descriptor */
|
||||
TMXR tt_desc = { 1, 0, 0, &tt1_ldsc }; /* mux descriptor */
|
||||
|
||||
DEVICE tti1_dev, tto1_dev;
|
||||
int32 tti1 (int32 pulse, int32 code, int32 AC);
|
||||
int32 tto1 (int32 pulse, int32 code, int32 AC);
|
||||
t_stat tti1_svc (UNIT *uptr);
|
||||
t_stat tto1_svc (UNIT *uptr);
|
||||
t_stat tti1_reset (DEVICE *dptr);
|
||||
@@ -58,7 +63,8 @@ t_stat tti1_attach (UNIT *uptr, char *cptr);
|
||||
t_stat tti1_detach (UNIT *uptr);
|
||||
t_stat tti1_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat tti1_show (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
||||
void ttx1_enbdis (int32 dis);
|
||||
|
||||
/* TTI1 data structures
|
||||
|
||||
tti1_dev TTI1 device descriptor
|
||||
@@ -67,6 +73,8 @@ t_stat tti1_show (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
ttx1_mod TTI1/TTO1 modifiers list
|
||||
*/
|
||||
|
||||
DIB tti1_dib = { DEV_TTI1, INT_TTI1, PI_TTI1, &tti1 };
|
||||
|
||||
UNIT tti1_unit = { UDATA (&tti1_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG tti1_reg[] = {
|
||||
@@ -77,8 +85,6 @@ REG tti1_reg[] = {
|
||||
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
||||
{ DRDATA (POS, tt1_ldsc.rxcnt, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (MODE, tti1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB tti1_mod[] = {
|
||||
@@ -91,15 +97,14 @@ MTAB tti1_mod[] = {
|
||||
NULL, &tti1_show, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
|
||||
NULL, &tti1_show, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_TTI1 | INT_TTO1, NULL, "ENABLED", &set_enb },
|
||||
{ MTAB_XTD|MTAB_VDV, INT_TTI1 | INT_TTO1, NULL, "DISABLED", &set_dsb },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE tti1_dev = {
|
||||
"TTI1", &tti1_unit, tti1_reg, tti1_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
&tmxr_ex, &tmxr_dep, &tti1_reset,
|
||||
NULL, &tti1_attach, &tti1_detach };
|
||||
NULL, &tti1_attach, &tti1_detach,
|
||||
&tti1_dib, DEV_DISABLE };
|
||||
|
||||
/* TTO1 data structures
|
||||
|
||||
@@ -108,6 +113,8 @@ DEVICE tti1_dev = {
|
||||
tto1_reg TTO1 register list
|
||||
*/
|
||||
|
||||
DIB tto1_dib = { DEV_TTO1, INT_TTO1, PI_TTO1, &tto1 };
|
||||
|
||||
UNIT tto1_unit = { UDATA (&tto1_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto1_reg[] = {
|
||||
@@ -118,8 +125,6 @@ REG tto1_reg[] = {
|
||||
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
||||
{ DRDATA (POS, tt1_ldsc.txcnt, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (MODE, tto1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||
{ FLDATA (*DEVENB, iot_enb, INT_V_TTO1), REG_HRO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB tto1_mod[] = {
|
||||
@@ -131,7 +136,8 @@ DEVICE tto1_dev = {
|
||||
"TTO1", &tto1_unit, tto1_reg, tto1_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tto1_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&tto1_dib, DEV_DISABLE };
|
||||
|
||||
/* Terminal input: IOT routine */
|
||||
|
||||
@@ -163,16 +169,16 @@ int32 temp, newln;
|
||||
if (tt1_ldsc.conn) { /* connected? */
|
||||
tmxr_poll_rx (&tt_desc); /* poll for input */
|
||||
if (temp = tmxr_getc_ln (&tt1_ldsc)) { /* get char */
|
||||
uptr -> buf = temp & 0177;
|
||||
if ((uptr -> flags & UNIT_DASHER) &&
|
||||
(uptr -> buf == '\r'))
|
||||
uptr -> buf = '\n'; /* Dasher: cr -> nl */
|
||||
uptr->buf = temp & 0177;
|
||||
if ((uptr->flags & UNIT_DASHER) &&
|
||||
(uptr->buf == '\r'))
|
||||
uptr->buf = '\n'; /* Dasher: cr->nl */
|
||||
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
|
||||
dev_done = dev_done | INT_TTI1; /* set done */
|
||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable); }
|
||||
sim_activate (uptr, uptr -> wait); } /* continue poll */
|
||||
if (uptr -> flags & UNIT_ATT) { /* attached? */
|
||||
newln = tmxr_poll_conn (&tt_desc, uptr); /* poll connect */
|
||||
sim_activate (uptr, uptr->wait); } /* continue poll */
|
||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
||||
newln = tmxr_poll_conn (&tt_desc); /* poll connect */
|
||||
if (newln >= 0) { /* got one? */
|
||||
sim_activate (&tti1_unit, tti1_unit.wait);
|
||||
tt1_ldsc.rcve = 1; } /* rcv enabled */
|
||||
@@ -184,6 +190,7 @@ return SCPE_OK;
|
||||
|
||||
t_stat tti1_reset (DEVICE *dptr)
|
||||
{
|
||||
ttx1_enbdis (dptr->flags & DEV_DIS); /* sync devices */
|
||||
tti1_unit.buf = 0;
|
||||
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
|
||||
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
|
||||
@@ -243,6 +250,7 @@ return SCPE_OK;
|
||||
|
||||
t_stat tto1_reset (DEVICE *dptr)
|
||||
{
|
||||
ttx1_enbdis (dptr->flags & DEV_DIS); /* sync devices */
|
||||
tto1_unit.buf = 0;
|
||||
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
|
||||
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
|
||||
@@ -299,3 +307,15 @@ if (val) tmxr_fconns (st, &tt1_ldsc, -1);
|
||||
else tmxr_fstats (st, &tt1_ldsc, -1);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Enable/disable device */
|
||||
|
||||
void ttx1_enbdis (int32 dis)
|
||||
{
|
||||
if (dis) {
|
||||
tti1_dev.flags = tto1_dev.flags | DEV_DIS;
|
||||
tto1_dev.flags = tto1_dev.flags | DEV_DIS; }
|
||||
else { tti1_dev.flags = tti1_dev.flags & ~DEV_DIS;
|
||||
tto1_dev.flags = tto1_dev.flags & ~DEV_DIS; }
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user