1
0
mirror of https://github.com/simh/simh.git synced 2026-03-28 10:43:00 +00:00

Notes For V3.5-0

The source set has been extensively overhauled.  For correct
viewing, set Visual C++ or Emacs to have tab stops every 4
characters.

1. New Features in 3.4-1

1.1 All Ethernet devices

- Added Windows user-defined adapter names (from Timothe Litt)

1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors

- Added support for SET <unit>n DISCONNECT

1.3 VAX

- Added latent QDSS support
- Revised autoconfigure to handle QDSS

1.4 PDP-11

- Revised autoconfigure to handle more casees

2. Bugs Fixed in 3.4-1

2.1 SCP and libraries

- Trim trailing spaces on all input (for example, attach file names)
- Fixed sim_sock spurious SIGPIPE error in Unix/Linux
- Fixed sim_tape misallocation of TPC map array for 64b simulators

2.2 1401

- Fixed bug, CPU reset was clearing SSB through SSG

2.3 PDP-11

- Fixed bug in VH vector display routine
- Fixed XU runt packet processing (found by Tim Chapman)

2.4 Interdata

- Fixed bug in SHOW PAS CONN/STATS
- Fixed potential integer overflow exception in divide

2.5 SDS

- Fixed bug in SHOW MUX CONN/STATS

2.6 HP

- Fixed bug in SHOW MUX CONN/STATS

2.7 PDP-8

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.8 PDP-18b

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.9 Nova, Eclipse

- Fixed potential integer overflow exception in divide
This commit is contained in:
Bob Supnik
2005-09-09 18:09:00 -07:00
committed by Mark Pizzolato
parent ec60bbf329
commit b7c1eae41f
257 changed files with 107140 additions and 97195 deletions

View File

@@ -21,4 +21,4 @@ The module eclipse_tt.c can be used with either an Eclipse or Nova CPU simulator
in place of nova_tt.c. It provides a full emulation of the cursor controls on
the Dasher video terminal but requires that the underlying operating system
interpret VT100 cursor controls. Thus, it works under VMS or UNIX but not under
Windows or OS/2.
Windows or OS/2.

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,43 @@
/* eclipse_tt.c: Eclipse console terminal simulator
Copyright (c) 1998-2003, Charles E Owen
Copyright (c) 1998-2005, Charles E Owen
Portions copyright (c) 1993-2002, Robert M Supnik
Written by Charles Owen, used by gracious permission
Commercial use prohibited
tti terminal input
tto terminal output
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:
25-Apr-03 RMS Revised for extended file support
03-Oct-02 RMS Added DIBs
30-May-02 RMS Widened POS to 32b
28-Jan-02 RMS Cleaned up compiler warnings
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
ROBERT M SUPNIK 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 author 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 author.
tti terminal input
tto terminal output
25-Apr-03 RMS Revised for extended file support
03-Oct-02 RMS Added DIBs
30-May-02 RMS Widened POS to 32b
28-Jan-02 RMS Cleaned up compiler warnings
*/
#include "nova_defs.h"
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
#define UNIT_DASHER (1 << UNIT_V_DASHER)
#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;
@@ -31,13 +51,13 @@ t_stat ttx_setmod (UNIT *uptr, int32 value, char *cptr, void *desc);
void translate_in();
int32 translate_out(int32 c);
int32 putseq(char *seq);
/* TTI data structures
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
ttx_mod TTI/TTO modifiers list
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
ttx_mod TTI/TTO modifiers list
*/
DIB tti_dib = { DEV_TTI, INT_TTI, PI_TTI, &tti };
@@ -45,32 +65,35 @@ DIB tti_dib = { DEV_TTI, INT_TTI, PI_TTI, &tti };
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
REG tti_reg[] = {
{ ORDATA (BUF, tti_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTI) },
{ FLDATA (DONE, dev_done, INT_V_TTI) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTI) },
{ FLDATA (INT, int_req, INT_V_TTI) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tti_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTI) },
{ FLDATA (DONE, dev_done, INT_V_TTI) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTI) },
{ FLDATA (INT, int_req, INT_V_TTI) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL }
};
MTAB ttx_mod[] = {
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
{ 0 } };
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0 };
"TTI", &tti_unit, tti_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
*/
DIB tto_dib = { DEV_TTO, INT_TTO, PI_TTO, &tto };
@@ -78,24 +101,26 @@ DIB tto_dib = { DEV_TTO, INT_TTO, PI_TTO, &tto };
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
REG tto_reg[] = {
{ ORDATA (BUF, tto_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTO) },
{ FLDATA (DONE, dev_done, INT_V_TTO) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTO) },
{ FLDATA (INT, int_req, INT_V_TTO) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tto_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTO) },
{ FLDATA (DONE, dev_done, INT_V_TTO) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTO) },
{ FLDATA (INT, int_req, INT_V_TTO) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0 };
"TTO", &tto_unit, tto_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0
};
/* Terminal input: IOT routine */
int32 tti (int32 pulse, int32 code, int32 AC)
@@ -103,17 +128,21 @@ int32 tti (int32 pulse, int32 code, int32 AC)
int32 iodata;
iodata = (code == ioDIA)? tti_unit.buf & 0377: 0;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTI; /* set busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTI; /* set busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break;
} /* end switch */
return iodata;
}
@@ -123,15 +152,15 @@ t_stat tti_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
tti_unit.buf = temp & 0177;
/* --- BEGIN MODIFIED CODE --- */
if (tti_unit.flags & UNIT_DASHER) /* translate input */
translate_in();
/* --- END MODIFIED CODE --- */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done | INT_TTI; /* set done */
if (tti_unit.flags & UNIT_DASHER) /* translate input */
translate_in();
/* --- END MODIFIED CODE --- */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done | INT_TTI; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
tti_unit.pos = tti_unit.pos + 1;
return SCPE_OK;
@@ -139,22 +168,22 @@ return SCPE_OK;
/* -------------------- BEGIN INSERTION -----------------------*/
int curpos = 0; /* used by translate_out() */
int row = 0, col = 0; /* ditto - for cursor positioning */
int spec200 = 0; /* signals next char is 'special' */
int curpos = 0; /* used by translate_out() */
int row = 0, col = 0; /* ditto - for cursor positioning */
int spec200 = 0; /* signals next char is 'special' */
/* Translation: Vt100 input to D200 keycodes. */
/* Translation: VT100 input to D200 keycodes. */
void translate_in()
{
char rev = 0;
if (tti_unit.buf == '\r')
rev = '\n';
rev = '\n';
if (tti_unit.buf == '\n')
rev = '\r';
rev = '\r';
if (rev)
tti_unit.buf = rev;
tti_unit.buf = rev;
}
/* -------------------- END INSERTION -----------------------*/
@@ -164,31 +193,35 @@ void translate_in()
t_stat tti_reset (DEVICE *dptr)
{
tti_unit.buf = 0;
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK;
}
/* Terminal output: IOT routine */
int32 tto (int32 pulse, int32 code, int32 AC)
{
if (code == ioDOA) tto_unit.buf = AC & 0377;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTO; /* set busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_cancel (&tto_unit); /* deactivate unit */
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTO; /* set busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_cancel (&tto_unit); /* deactivate unit */
break;
} /* end switch */
return 0;
}
@@ -198,18 +231,18 @@ t_stat tto_svc (UNIT *uptr)
{
int32 c, temp;
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done | INT_TTO; /* set done */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done | INT_TTO; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
c = tto_unit.buf & 0177;
/* --- BEGIN MODIFIED CODE --- */
if (tto_unit.flags & UNIT_DASHER) {
if ((temp = translate_out(c)) != SCPE_OK) return temp;
} else {
if ((temp = sim_putchar (c)) != SCPE_OK) return temp;
tto_unit.pos = tto_unit.pos + 1;
}
/* --- END MODIFIED CODE --- */
if ((temp = translate_out(c)) != SCPE_OK) return temp;
} else {
if ((temp = sim_putchar (c)) != SCPE_OK) return temp;
tto_unit.pos = tto_unit.pos + 1;
}
/* --- END MODIFIED CODE --- */
return SCPE_OK;
}
@@ -219,158 +252,158 @@ return SCPE_OK;
int32 translate_out(int32 c)
{
int32 temp;
char outstr[32];
if (spec200 == 1) { /* Special terminal control seq */
spec200 = 0;
switch (c) {
case 'C': /* read model ID */
return SCPE_OK;
case 'E': /* Reverse video off */
return SCPE_OK;
case 'D': /* Reverse video on */
return SCPE_OK;
default:
return SCPE_OK;
}
}
if (curpos == 1) { /* 2nd char of cursor position */
col = c & 0x7f;
curpos++;
return (SCPE_OK);
}
if (curpos == 2) { /* 3rd char of cursor position */
row = c & 0x7f;
curpos = 0;
sprintf(outstr, "\033[%d;%dH", row+1, col+1);
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
}
switch (c) { /* Single-char command or data */
case 003: /* Blink enable */
break;
case 004: /* Blink disable */
break;
case 005: /* Read cursor address */
break;
case 010: /* Cursor home */
sprintf(outstr, "\033[1;1H");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row = col = 0;
return (SCPE_OK);
case 012: /* Newline */
if ((temp = sim_putchar('\r')) != SCPE_OK) return temp;
tto_unit.pos += 1;
if ((temp = sim_putchar(c)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col = 1;
row++;
if (row > 24) row = 1;
return (SCPE_OK);
case 013: /* Erase EOL */
sprintf(outstr, "\033[K");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 014: /* Erase screen */
sprintf(outstr, "\033[1;1H\033[2J");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row = col = 0;
return (SCPE_OK);
case 015: /* CR */
if ((temp = sim_putchar(c)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col = 1;
return (SCPE_OK);
case 016: /* Blink On */
sprintf(outstr, "\033[5m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 017: /* Blink off */
sprintf(outstr, "\033[25m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 020: /* Write cursor address */
curpos = 1;
return SCPE_OK;
case 024: /* underscore on */
sprintf(outstr, "\033[4m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 025: /* underscore off */
sprintf(outstr, "\033[24m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
break;
case 027: /* cursor up */
sprintf(outstr, "\033[A");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row--;
if (row < 1) row = 24;
return (SCPE_OK);
case 030: /* cursor right */
sprintf(outstr, "\033[C");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
col++;
if (col > 80) {
col = 1;
row++;
if (row > 24) row = 1;
}
return (SCPE_OK);
case 031: /* Cursor left */
sprintf(outstr, "\033[D");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col--;
if (col < 1) {
col = 80;
row--;
if (row < 1) row = 24;
}
return (SCPE_OK);
case 032: /* Cursor down */
sprintf(outstr, "\033[B");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row++;
if (row > 24) row = 1;
return (SCPE_OK);
case 034: /* Dim on */
sprintf(outstr, "\033[22m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 035: /* Dim off */
sprintf(outstr, "\033[1m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 036: /* Special sequence */
spec200 = 1;
return SCPE_OK;
default: /* ..A character of data */
if ((temp = sim_putchar(c)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col++;
if (col > 80) {
col = 1;
row++;
if (row > 24) row = 24;
}
return (SCPE_OK);
}
return SCPE_OK;
int32 temp;
char outstr[32];
if (spec200 == 1) { /* Special terminal control seq */
spec200 = 0;
switch (c) {
case 'C': /* read model ID */
return SCPE_OK;
case 'E': /* Reverse video off */
return SCPE_OK;
case 'D': /* Reverse video on */
return SCPE_OK;
default:
return SCPE_OK;
}
}
if (curpos == 1) { /* 2nd char of cursor position */
col = c & 0x7f;
curpos++;
return (SCPE_OK);
}
if (curpos == 2) { /* 3rd char of cursor position */
row = c & 0x7f;
curpos = 0;
sprintf(outstr, "\033[%d;%dH", row+1, col+1);
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
}
switch (c) { /* Single-char command or data */
case 003: /* Blink enable */
break;
case 004: /* Blink disable */
break;
case 005: /* Read cursor address */
break;
case 010: /* Cursor home */
sprintf(outstr, "\033[1;1H");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row = col = 0;
return (SCPE_OK);
case 012: /* Newline */
if ((temp = sim_putchar('\r')) != SCPE_OK) return temp;
tto_unit.pos += 1;
if ((temp = sim_putchar(c)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col = 1;
row++;
if (row > 24) row = 1;
return (SCPE_OK);
case 013: /* Erase EOL */
sprintf(outstr, "\033[K");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 014: /* Erase screen */
sprintf(outstr, "\033[1;1H\033[2J");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row = col = 0;
return (SCPE_OK);
case 015: /* CR */
if ((temp = sim_putchar(c)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col = 1;
return (SCPE_OK);
case 016: /* Blink On */
sprintf(outstr, "\033[5m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 017: /* Blink off */
sprintf(outstr, "\033[25m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 020: /* Write cursor address */
curpos = 1;
return SCPE_OK;
case 024: /* underscore on */
sprintf(outstr, "\033[4m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 025: /* underscore off */
sprintf(outstr, "\033[24m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
break;
case 027: /* cursor up */
sprintf(outstr, "\033[A");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row--;
if (row < 1) row = 24;
return (SCPE_OK);
case 030: /* cursor right */
sprintf(outstr, "\033[C");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
col++;
if (col > 80) {
col = 1;
row++;
if (row > 24) row = 1;
}
return (SCPE_OK);
case 031: /* Cursor left */
sprintf(outstr, "\033[D");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col--;
if (col < 1) {
col = 80;
row--;
if (row < 1) row = 24;
}
return (SCPE_OK);
case 032: /* Cursor down */
sprintf(outstr, "\033[B");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
row++;
if (row > 24) row = 1;
return (SCPE_OK);
case 034: /* Dim on */
sprintf(outstr, "\033[22m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 035: /* Dim off */
sprintf(outstr, "\033[1m");
if ((temp = putseq(outstr)) != SCPE_OK) return temp;
return (SCPE_OK);
case 036: /* Special sequence */
spec200 = 1;
return SCPE_OK;
default: /* ..A character of data */
if ((temp = sim_putchar(c)) != SCPE_OK) return temp;
tto_unit.pos += 1;
col++;
if (col > 80) {
col = 1;
row++;
if (row > 24) row = 24;
}
return (SCPE_OK);
}
return SCPE_OK;
}
int32 putseq(char *seq)
{
int i, len, temp;
len = strlen(seq);
for (i = 0; i < len; i++) {
if ((temp = sim_putchar(seq[i])) != SCPE_OK)
return temp;
tto_unit.pos += 1;
}
return SCPE_OK;
int i, len, temp;
len = strlen(seq);
for (i = 0; i < len; i++) {
if ((temp = sim_putchar(seq[i])) != SCPE_OK)
return temp;
tto_unit.pos += 1;
}
return SCPE_OK;
}
/* -------------------- END INSERTION -----------------------*/
@@ -380,10 +413,10 @@ int32 putseq(char *seq)
t_stat tto_reset (DEVICE *dptr)
{
tto_unit.buf = 0;
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_cancel (&tto_unit); /* deactivate unit */
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* nova_clk.c: NOVA real-time clock simulator
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,29 +19,29 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
clk real-time clock
clk real-time clock
01-Mar-03 RMS Added SET/SHOW CLK FREQ support
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
24-Sep-97 RMS Fixed bug in unit service (found by Charles Owen)
01-Mar-03 RMS Added SET/SHOW CLK FREQ support
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
24-Sep-97 RMS Fixed bug in unit service (found by Charles Owen)
*/
#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_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);
@@ -51,9 +51,9 @@ t_stat clk_show_freq (FILE *st, UNIT *uptr, int32 val, void *desc);
/* CLK data structures
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
*/
DIB clk_dib = { DEV_CLK, INT_CLK, PI_CLK, &clk };
@@ -61,56 +61,64 @@ DIB clk_dib = { DEV_CLK, INT_CLK, PI_CLK, &clk };
UNIT clk_unit = { UDATA (&clk_svc, 0, 0) };
REG clk_reg[] = {
{ ORDATA (SELECT, clk_sel, 2) },
{ FLDATA (BUSY, dev_busy, INT_V_CLK) },
{ FLDATA (DONE, dev_done, INT_V_CLK) },
{ FLDATA (DISABLE, dev_disable, INT_V_CLK) },
{ FLDATA (INT, int_req, INT_V_CLK) },
{ DRDATA (TIME0, clk_time[0], 24), REG_NZ + PV_LEFT },
{ DRDATA (TIME1, clk_time[1], 24), REG_NZ + PV_LEFT },
{ DRDATA (TIME2, clk_time[2], 24), REG_NZ + PV_LEFT },
{ DRDATA (TIME3, clk_time[3], 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS0, clk_tps[0], 6), PV_LEFT + REG_HRO },
{ NULL } };
{ ORDATA (SELECT, clk_sel, 2) },
{ FLDATA (BUSY, dev_busy, INT_V_CLK) },
{ FLDATA (DONE, dev_done, INT_V_CLK) },
{ FLDATA (DISABLE, dev_disable, INT_V_CLK) },
{ FLDATA (INT, int_req, INT_V_CLK) },
{ DRDATA (TIME0, clk_time[0], 24), REG_NZ + PV_LEFT },
{ DRDATA (TIME1, clk_time[1], 24), REG_NZ + PV_LEFT },
{ DRDATA (TIME2, clk_time[2], 24), REG_NZ + PV_LEFT },
{ DRDATA (TIME3, clk_time[3], 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS0, clk_tps[0], 6), PV_LEFT + REG_HRO },
{ NULL }
};
MTAB clk_mod[] = {
{ MTAB_XTD|MTAB_VDV, 50, NULL, "50HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 60, NULL, "60HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "LINE", NULL,
NULL, &clk_show_freq, NULL },
{ 0 } };
{ MTAB_XTD|MTAB_VDV, 50, NULL, "50HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 60, NULL, "60HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "LINE", NULL,
NULL, &clk_show_freq, NULL },
{ 0 }
};
DEVICE clk_dev = {
"CLK", &clk_unit, clk_reg, clk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, 0 };
"CLK", &clk_unit, clk_reg, clk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, 0
};
/* IOT routine */
int32 clk (int32 pulse, int32 code, int32 AC)
{
if (code == ioDOA) { /* DOA */
clk_sel = AC & 3; /* save select */
sim_rtc_init (clk_time[clk_sel]); } /* init calibr */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_CLK; /* set busy */
dev_done = dev_done & ~INT_CLK; /* clear done, int */
int_req = int_req & ~INT_CLK;
if (!sim_is_active (&clk_unit)) /* not running? */
sim_activate (&clk_unit, /* activate */
sim_rtc_init (clk_time[clk_sel])); /* init calibr */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
dev_done = dev_done & ~INT_CLK; /* clear done, int */
int_req = int_req & ~INT_CLK;
sim_cancel (&clk_unit); /* deactivate unit */
break; } /* end switch */
if (code == ioDOA) { /* DOA */
clk_sel = AC & 3; /* save select */
sim_rtc_init (clk_time[clk_sel]); /* init calibr */
}
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_CLK; /* set busy */
dev_done = dev_done & ~INT_CLK; /* clear done, int */
int_req = int_req & ~INT_CLK;
if (!sim_is_active (&clk_unit)) /* not running? */
sim_activate (&clk_unit, /* activate */
sim_rtc_init (clk_time[clk_sel])); /* init calibr */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
dev_done = dev_done & ~INT_CLK; /* clear done, int */
int_req = int_req & ~INT_CLK;
sim_cancel (&clk_unit); /* deactivate unit */
break;
} /* end switch */
return 0;
}
@@ -120,14 +128,14 @@ t_stat clk_svc (UNIT *uptr)
{
int32 t;
dev_done = dev_done | INT_CLK; /* set done */
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
dev_done = dev_done | INT_CLK; /* set done */
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
t = sim_rtc_calb (clk_tps[clk_sel]); /* calibrate delay */
sim_activate (&clk_unit, t); /* reactivate unit */
if (clk_adj[clk_sel] > 0) /* clk >= 60Hz? */
tmxr_poll = t * clk_adj[clk_sel]; /* poll is longer */
else tmxr_poll = t / (-clk_adj[clk_sel]); /* poll is shorter */
t = sim_rtc_calb (clk_tps[clk_sel]); /* calibrate delay */
sim_activate (&clk_unit, t); /* reactivate unit */
if (clk_adj[clk_sel] > 0) /* clk >= 60Hz? */
tmxr_poll = t * clk_adj[clk_sel]; /* poll is longer */
else tmxr_poll = t / (-clk_adj[clk_sel]); /* poll is shorter */
return SCPE_OK;
}
@@ -136,11 +144,11 @@ return SCPE_OK;
t_stat clk_reset (DEVICE *dptr)
{
clk_sel = 0;
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
dev_done = dev_done & ~INT_CLK; /* clear done, int */
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
dev_done = dev_done & ~INT_CLK; /* clear done, int */
int_req = int_req & ~INT_CLK;
sim_cancel (&clk_unit); /* deactivate unit */
tmxr_poll = clk_time[0]; /* poll is default */
sim_cancel (&clk_unit); /* deactivate unit */
tmxr_poll = clk_time[0]; /* poll is default */
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* nova_defs.h: NOVA/Eclipse simulator definitions
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,267 +19,270 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
14-Jan-04 BKR Added support for QTY and ALM
22-Nov-03 CEO Added support for PIT device
19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev kit conflict
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
15-Oct-00 RMS Added stack, byte, trap instructions
14-Apr-99 RMS Changed t_addr to unsigned
16-Mar-95 RMS Added dynamic memory size
06-Dec-95 RMS Added magnetic tape
14-Jan-04 BKR Added support for QTY and ALM
22-Nov-03 CEO Added support for PIT device
19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev kit conflict
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
15-Oct-00 RMS Added stack, byte, trap instructions
14-Apr-99 RMS Changed t_addr to unsigned
16-Mar-95 RMS Added dynamic memory size
06-Dec-95 RMS Added magnetic tape
The author gratefully acknowledges the help of Tom West, Diana Englebart,
Carl Friend, Bruce Ray, and Charles Owen in resolving questions about
the NOVA.
*/
#include "sim_defs.h" /* simulator defns */
#ifndef _NOVA_DEFS_H_
#define _NOVA_DEFS_H_ 0
#include "sim_defs.h" /* simulator defns */
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_IND 4 /* indirect loop */
#define STOP_IND_INT 5 /* ind loop, intr */
#define STOP_IND_TRP 6 /* ind loop, trap */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_IND 4 /* indirect loop */
#define STOP_IND_INT 5 /* ind loop, intr */
#define STOP_IND_TRP 6 /* ind loop, trap */
/* Memory */
#if defined (ECLIPSE)
#define MAXMEMSIZE 1048576 /* max memory size */
#define MAXMEMSIZE 1048576 /* max memory size */
#else
#define MAXMEMSIZE 32768 /* max memory size */
#define MAXMEMSIZE 32768 /* max memory size */
#endif
#define AMASK 077777 /* logical addr mask */
#define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define A_V_IND 15 /* ind: indirect */
#define A_IND (1 << A_V_IND)
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
#define AMASK 077777 /* logical addr mask */
#define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define A_V_IND 15 /* ind: indirect */
#define A_IND (1 << A_V_IND)
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* Architectural constants */
#define SIGN 0100000 /* sign */
#define DMASK 0177777 /* data mask */
#define CBIT (DMASK + 1) /* carry bit */
#define CDMASK (CBIT | DMASK) /* carry + data */
#define SIGN 0100000 /* sign */
#define DMASK 0177777 /* data mask */
#define CBIT (DMASK + 1) /* carry bit */
#define CDMASK (CBIT | DMASK) /* carry + data */
/* Reserved memory locations */
#define INT_SAV 0 /* intr saved PC */
#define INT_JMP 1 /* intr jmp @ */
#define STK_JMP 3 /* stack jmp @ */
#define TRP_SAV 046 /* trap saved PC */
#define TRP_JMP 047 /* trap jmp @ */
#define AUTO_INC 020 /* start autoinc */
#define AUTO_DEC 030 /* start autodec */
#define INT_SAV 0 /* intr saved PC */
#define INT_JMP 1 /* intr jmp @ */
#define STK_JMP 3 /* stack jmp @ */
#define TRP_SAV 046 /* trap saved PC */
#define TRP_JMP 047 /* trap jmp @ */
#define AUTO_INC 020 /* start autoinc */
#define AUTO_DEC 030 /* start autodec */
/* Instruction format */
#define I_OPR 0100000 /* operate */
#define I_M_SRC 03 /* OPR: src AC */
#define I_V_SRC 13
#define I_GETSRC(x) (((x) >> I_V_SRC) & I_M_SRC)
#define I_M_DST 03 /* dst AC */
#define I_V_DST 11
#define I_GETDST(x) (((x) >> I_V_DST) & I_M_DST)
#define I_M_ALU 07 /* OPR: ALU op */
#define I_V_ALU 8
#define I_GETALU(x) (((x) >> I_V_ALU) & I_M_ALU)
#define I_M_SHF 03 /* OPR: shift */
#define I_V_SHF 6
#define I_GETSHF(x) (((x) >> I_V_SHF) & I_M_SHF)
#define I_M_CRY 03 /* OPR: carry */
#define I_V_CRY 4
#define I_GETCRY(x) (((x) >> I_V_CRY) & I_M_CRY)
#define I_V_NLD 3 /* OPR: no load */
#define I_NLD (1 << I_V_NLD)
#define I_M_SKP 07 /* OPR: skip */
#define I_V_SKP 0
#define I_GETSKP(x) (((x) >> I_V_SKP) & I_M_SKP)
#define I_OPR 0100000 /* operate */
#define I_M_SRC 03 /* OPR: src AC */
#define I_V_SRC 13
#define I_GETSRC(x) (((x) >> I_V_SRC) & I_M_SRC)
#define I_M_DST 03 /* dst AC */
#define I_V_DST 11
#define I_GETDST(x) (((x) >> I_V_DST) & I_M_DST)
#define I_M_ALU 07 /* OPR: ALU op */
#define I_V_ALU 8
#define I_GETALU(x) (((x) >> I_V_ALU) & I_M_ALU)
#define I_M_SHF 03 /* OPR: shift */
#define I_V_SHF 6
#define I_GETSHF(x) (((x) >> I_V_SHF) & I_M_SHF)
#define I_M_CRY 03 /* OPR: carry */
#define I_V_CRY 4
#define I_GETCRY(x) (((x) >> I_V_CRY) & I_M_CRY)
#define I_V_NLD 3 /* OPR: no load */
#define I_NLD (1 << I_V_NLD)
#define I_M_SKP 07 /* OPR: skip */
#define I_V_SKP 0
#define I_GETSKP(x) (((x) >> I_V_SKP) & I_M_SKP)
#define I_M_OPAC 017 /* MRF: opcode + AC */
#define I_V_OPAC 11
#define I_GETOPAC(x) (((x) >> I_V_OPAC) & I_M_OPAC)
#define I_V_IND 10 /* MRF: indirect */
#define I_IND (1 << I_V_IND)
#define I_M_MODE 03 /* MRF: mode */
#define I_V_MODE 8
#define I_GETMODE(x) (((x) >> I_V_MODE) & I_M_MODE)
#define I_M_DISP 0377 /* MRF: disp */
#define I_V_DISP 0
#define I_GETDISP(x) (((x) >> I_V_DISP) & I_M_DISP)
#define DISPSIZE (I_M_DISP + 1) /* page size */
#define DISPSIGN (DISPSIZE >> 1) /* page sign */
#define I_M_OPAC 017 /* MRF: opcode + AC */
#define I_V_OPAC 11
#define I_GETOPAC(x) (((x) >> I_V_OPAC) & I_M_OPAC)
#define I_V_IND 10 /* MRF: indirect */
#define I_IND (1 << I_V_IND)
#define I_M_MODE 03 /* MRF: mode */
#define I_V_MODE 8
#define I_GETMODE(x) (((x) >> I_V_MODE) & I_M_MODE)
#define I_M_DISP 0377 /* MRF: disp */
#define I_V_DISP 0
#define I_GETDISP(x) (((x) >> I_V_DISP) & I_M_DISP)
#define DISPSIZE (I_M_DISP + 1) /* page size */
#define DISPSIGN (DISPSIZE >> 1) /* page sign */
#define I_M_IOT 07 /* IOT: code */
#define I_V_IOT 8
#define I_GETIOT(x) (((x) >> I_V_IOT) & I_M_IOT)
#define I_M_PULSE 03 /* IOT pulse */
#define I_V_PULSE 6
#define I_GETPULSE(x) (((x) >> I_V_PULSE) & I_M_PULSE)
#define I_M_DEV 077 /* IOT: device */
#define I_V_DEV 0
#define I_GETDEV(x) (((x) >> I_V_DEV) & I_M_DEV)
#define I_M_IOT 07 /* IOT: code */
#define I_V_IOT 8
#define I_GETIOT(x) (((x) >> I_V_IOT) & I_M_IOT)
#define I_M_PULSE 03 /* IOT pulse */
#define I_V_PULSE 6
#define I_GETPULSE(x) (((x) >> I_V_PULSE) & I_M_PULSE)
#define I_M_DEV 077 /* IOT: device */
#define I_V_DEV 0
#define I_GETDEV(x) (((x) >> I_V_DEV) & I_M_DEV)
#define I_M_XOP 037 /* XOP: code */
#define I_V_XOP 6
#define I_GETXOP(x) (((x) >> I_V_XOP) & I_M_XOP)
#define I_M_XOP 037 /* XOP: code */
#define I_V_XOP 6
#define I_GETXOP(x) (((x) >> I_V_XOP) & I_M_XOP)
/* IOT return codes */
#define IOT_V_REASON 16 /* set reason */
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
#define IOT_V_REASON 16 /* set reason */
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
/* IOT fields */
#define ioNIO 0 /* opcode field */
#define ioDIA 1
#define ioDOA 2
#define ioDIB 3
#define ioDOB 4
#define ioDIC 5
#define ioDOC 6
#define ioSKP 7
#define ioNIO 0 /* opcode field */
#define ioDIA 1
#define ioDOA 2
#define ioDIB 3
#define ioDOB 4
#define ioDIC 5
#define ioDOC 6
#define ioSKP 7
#define iopN 0 /* pulse field */
#define iopS 1
#define iopC 2
#define iopP 3
#define iopN 0 /* pulse field */
#define iopS 1
#define iopC 2
#define iopP 3
/* Device numbers */
#define DEV_LOW 010 /* lowest intr dev */
#define DEV_HIGH 051 /* highest intr dev */
#define DEV_MDV 001 /* multiply/divide */
#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_QTY 030 /* 4060 multiplexor */
#define DEV_DKP 033 /* disk pack */
#define DEV_CAS 034 /* cassette */
#define DEV_ALM 034 /* ALM/ULM multiplexor */
#define DEV_PIT 043 /* programmable interval timer */
#define DEV_TTI1 050 /* second console input */
#define DEV_TTO1 051 /* second console output */
#define DEV_CPU 077 /* CPU control */
#define DEV_LOW 010 /* lowest intr dev */
#define DEV_HIGH 051 /* highest intr dev */
#define DEV_MDV 001 /* multiply/divide */
#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_QTY 030 /* 4060 multiplexor */
#define DEV_DKP 033 /* disk pack */
#define DEV_CAS 034 /* cassette */
#define DEV_ALM 034 /* ALM/ULM multiplexor */
#define DEV_PIT 043 /* programmable interval timer */
#define DEV_TTI1 050 /* second console input */
#define DEV_TTO1 051 /* second console output */
#define DEV_CPU 077 /* CPU control */
/* I/O structure
The NOVA I/O structure is tied together by dev_table, indexed by
the device number. Each entry in dev_table consists of
mask device mask for busy, done (simulator representation)
pi pi disable bit (hardware representation)
routine IOT action routine
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 {
int32 mask; /* done/busy mask */
int32 pi; /* assigned pi bit */
int32 (*routine)(); /* dispatch routine */
};
int32 mask; /* done/busy mask */
int32 pi; /* assigned pi bit */
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;
typedef struct {
int32 dnum; /* device number */
int32 mask; /* done/busy mask */
int32 pi; /* assigned pi bit */
int32 (*routine)(); /* dispatch routine */
} DIB;
/* Device flags (simulator representation)
Priority (for INTA) runs from low numbers to high
*/
#define INT_V_PIT 2 /* PIT */
#define INT_V_DKP 3 /* moving head disk */
#define INT_V_DSK 4 /* fixed head disk */
#define INT_V_MTA 5 /* magnetic tape */
#define INT_V_LPT 6 /* line printer */
#define INT_V_CLK 7 /* clock */
#define INT_V_PTR 8 /* paper tape reader */
#define INT_V_PTP 9 /* paper tape punch */
#define INT_V_PLT 10 /* plotter */
#define INT_V_TTI 11 /* keyboard */
#define INT_V_TTO 12 /* terminal */
#define INT_V_TTI1 13 /* second keyboard */
#define INT_V_TTO1 14 /* second terminal */
#define INT_V_QTY 15 /* QTY multiplexor */
#define INT_V_ALM 16 /* ALM multiplexor */
#define INT_V_STK 17 /* stack overflow */
#define INT_V_NO_ION_PENDING 18 /* ion delay */
#define INT_V_ION 19 /* interrupts on */
#define INT_V_PIT 2 /* PIT */
#define INT_V_DKP 3 /* moving head disk */
#define INT_V_DSK 4 /* fixed head disk */
#define INT_V_MTA 5 /* magnetic tape */
#define INT_V_LPT 6 /* line printer */
#define INT_V_CLK 7 /* clock */
#define INT_V_PTR 8 /* paper tape reader */
#define INT_V_PTP 9 /* paper tape punch */
#define INT_V_PLT 10 /* plotter */
#define INT_V_TTI 11 /* keyboard */
#define INT_V_TTO 12 /* terminal */
#define INT_V_TTI1 13 /* second keyboard */
#define INT_V_TTO1 14 /* second terminal */
#define INT_V_QTY 15 /* QTY multiplexor */
#define INT_V_ALM 16 /* ALM multiplexor */
#define INT_V_STK 17 /* stack overflow */
#define INT_V_NO_ION_PENDING 18 /* ion delay */
#define INT_V_ION 19 /* interrupts on */
#define INT_PIT (1 << INT_V_PIT)
#define INT_DKP (1 << INT_V_DKP)
#define INT_DSK (1 << INT_V_DSK)
#define INT_MTA (1 << INT_V_MTA)
#define INT_LPT (1 << INT_V_LPT)
#define INT_CLK (1 << INT_V_CLK)
#define INT_PTR (1 << INT_V_PTR)
#define INT_PTP (1 << INT_V_PTP)
#define INT_PLT (1 << INT_V_PLT)
#define INT_TTI (1 << INT_V_TTI)
#define INT_TTO (1 << INT_V_TTO)
#define INT_TTI1 (1 << INT_V_TTI1)
#define INT_TTO1 (1 << INT_V_TTO1)
#define INT_QTY (1 << INT_V_QTY)
#define INT_ALM (1 << INT_V_ALM)
#define INT_STK (1 << INT_V_STK)
#define INT_PIT (1 << INT_V_PIT)
#define INT_DKP (1 << INT_V_DKP)
#define INT_DSK (1 << INT_V_DSK)
#define INT_MTA (1 << INT_V_MTA)
#define INT_LPT (1 << INT_V_LPT)
#define INT_CLK (1 << INT_V_CLK)
#define INT_PTR (1 << INT_V_PTR)
#define INT_PTP (1 << INT_V_PTP)
#define INT_PLT (1 << INT_V_PLT)
#define INT_TTI (1 << INT_V_TTI)
#define INT_TTO (1 << INT_V_TTO)
#define INT_TTI1 (1 << INT_V_TTI1)
#define INT_TTO1 (1 << INT_V_TTO1)
#define INT_QTY (1 << INT_V_QTY)
#define INT_ALM (1 << INT_V_ALM)
#define INT_STK (1 << INT_V_STK)
#define INT_NO_ION_PENDING (1 << INT_V_NO_ION_PENDING)
#define INT_ION (1 << INT_V_ION)
#define INT_DEV ((1 << INT_V_STK) - 1) /* device ints */
#define INT_PENDING INT_ION+INT_NO_ION_PENDING
#define INT_ION (1 << INT_V_ION)
#define INT_DEV ((1 << INT_V_STK) - 1) /* device ints */
#define INT_PENDING INT_ION+INT_NO_ION_PENDING
/* PI disable bits */
#define PI_PIT 0001000
#define PI_DKP 0000400
#define PI_DSK 0000100
#define PI_MTA 0000040
#define PI_LPT 0000010
#define PI_CLK 0000004
#define PI_PTR 0000020
#define PI_PTP 0000004
#define PI_PLT 0000010
#define PI_QTY 0000002
#define PI_ALM 0000002
#define PI_TTI 0000002
#define PI_TTO 0000001
#define PI_TTI1 PI_TTI
#define PI_TTO1 PI_TTO
/* #define PI_CDR 0000040 */
/* #define PI_DCM 0100000 */
/* #define PI_CAS 0000040 */
/* #define PI_ADCV 0000002 */
#define PI_PIT 0001000
#define PI_DKP 0000400
#define PI_DSK 0000100
#define PI_MTA 0000040
#define PI_LPT 0000010
#define PI_CLK 0000004
#define PI_PTR 0000020
#define PI_PTP 0000004
#define PI_PLT 0000010
#define PI_QTY 0000002
#define PI_ALM 0000002
#define PI_TTI 0000002
#define PI_TTO 0000001
#define PI_TTI1 PI_TTI
#define PI_TTO1 PI_TTO
/* #define PI_CDR 0000040 */
/* #define PI_DCM 0100000 */
/* #define PI_CAS 0000040 */
/* #define PI_ADCV 0000002 */
/* Function prototypes */
int32 MapAddr (int32 map, int32 addr);
t_stat set_enb (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat set_dsb (UNIT *uptr, int32 val, char *cptr, void *desc);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -7,8 +7,8 @@ Date: 15-Nov-2004
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2004, written by Robert M Supnik
Copyright (c) 1993-2004, Robert M Supnik
Original code published in 1993-2005, written by Robert M Supnik
Copyright (c) 1993-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -27,8 +27,8 @@ The following copyright notice applies to both the SIMH source and binary:
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
This memorandum documents the Nova simulator.

View File

@@ -1,6 +1,6 @@
/* nova_dsk.c: 4019 fixed head disk simulator
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,23 +19,23 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
dsk fixed head disk
dsk fixed head disk
04-Jan-04 RMS Changed sim_fsize calling sequence
26-Jul-03 RMS Fixed bug in set size routine
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
03-Mar-03 RMS Fixed variable capacity and autosizing
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
10-Dec-00 RMS Added Eclipse support
15-Oct-00 RMS Editorial changes
14-Apr-99 RMS Changed t_addr to unsigned
04-Jan-04 RMS Changed sim_fsize calling sequence
26-Jul-03 RMS Fixed bug in set size routine
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
03-Mar-03 RMS Fixed variable capacity and autosizing
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
10-Dec-00 RMS Added Eclipse support
15-Oct-00 RMS Editorial changes
14-Apr-99 RMS Changed t_addr to unsigned
The 4019 is a head-per-track disk. To minimize overhead, the entire disk
is buffered in memory.
@@ -44,61 +44,62 @@
#include "nova_defs.h"
#include <math.h>
#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */
#define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */
#define UNIT_M_PLAT 07
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
#define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1)
#define UNIT_AUTO (1 << UNIT_V_AUTO)
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */
#define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */
#define UNIT_M_PLAT 07
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
#define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1)
#define UNIT_AUTO (1 << UNIT_V_AUTO)
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
/* Constants */
#define DSK_NUMWD 256 /* words/sector */
#define DSK_NUMSC 8 /* sectors/track */
#define DSK_NUMTR 128 /* tracks/disk */
#define DSK_DKSIZE (DSK_NUMTR*DSK_NUMSC*DSK_NUMWD) /* words/disk */
#define DSK_AMASK ((DSK_NUMDK*DSK_NUMTR*DSK_NUMSC) - 1) /* address mask */
#define DSK_NUMDK 8 /* disks/controller */
#define GET_DISK(x) (((x) / (DSK_NUMSC * DSK_NUMTR)) & (DSK_NUMDK - 1))
#define DSK_NUMWD 256 /* words/sector */
#define DSK_NUMSC 8 /* sectors/track */
#define DSK_NUMTR 128 /* tracks/disk */
#define DSK_DKSIZE (DSK_NUMTR*DSK_NUMSC*DSK_NUMWD) /* words/disk */
#define DSK_AMASK ((DSK_NUMDK*DSK_NUMTR*DSK_NUMSC) - 1) /* address mask */
#define DSK_NUMDK 8 /* disks/controller */
#define GET_DISK(x) (((x) / (DSK_NUMSC * DSK_NUMTR)) & (DSK_NUMDK - 1))
/* Parameters in the unit descriptor */
#define FUNC u4 /* function */
#define FUNC u4 /* function */
/* Status register */
#define DSKS_WLS 020 /* write lock status */
#define DSKS_DLT 010 /* data late error */
#define DSKS_NSD 004 /* non-existent disk */
#define DSKS_CRC 002 /* parity error */
#define DSKS_ERR 001 /* error summary */
#define DSKS_ALLERR (DSKS_WLS | DSKS_DLT | DSKS_NSD | DSKS_CRC | DSKS_ERR)
#define DSKS_WLS 020 /* write lock status */
#define DSKS_DLT 010 /* data late error */
#define DSKS_NSD 004 /* non-existent disk */
#define DSKS_CRC 002 /* parity error */
#define DSKS_ERR 001 /* error summary */
#define DSKS_ALLERR (DSKS_WLS | DSKS_DLT | DSKS_NSD | DSKS_CRC | DSKS_ERR)
/* Map logical sector numbers to physical sector numbers
(indexed by track<2:0>'sector)
*/
static const int32 sector_map[] = {
0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 2, 4, 6, 0,
2, 4, 6, 0, 3, 5, 7, 1, 3, 5, 7, 1, 4, 6, 0, 2,
4, 6, 0, 2, 5, 7, 1, 3, 5, 7, 1, 3, 6, 0, 2, 4,
6, 0, 2, 4, 7, 1, 3, 5, 7, 1, 3, 5, 0, 2, 4, 6 };
0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 2, 4, 6, 0,
2, 4, 6, 0, 3, 5, 7, 1, 3, 5, 7, 1, 4, 6, 0, 2,
4, 6, 0, 2, 5, 7, 1, 3, 5, 7, 1, 3, 6, 0, 2, 4,
6, 0, 2, 4, 7, 1, 3, 5, 7, 1, 3, 5, 0, 2, 4, 6
};
#define DSK_MMASK 077
#define GET_SECTOR(x) ((int) fmod (sim_gtime() / ((double) (x)), \
((double) DSK_NUMSC)))
#define DSK_MMASK 077
#define GET_SECTOR(x) ((int) fmod (sim_gtime() / ((double) (x)), \
((double) DSK_NUMSC)))
extern uint16 M[];
extern UNIT cpu_unit;
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 */
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);
@@ -110,49 +111,53 @@ t_stat dsk_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
/* DSK data structures
dsk_dev device descriptor
dsk_unit unit descriptor
dsk_reg register list
dsk_dev device descriptor
dsk_unit unit descriptor
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_DKSIZE) };
UNIT dsk_unit = {
UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
DSK_DKSIZE)
};
REG dsk_reg[] = {
{ ORDATA (STAT, dsk_stat, 16) },
{ ORDATA (DA, dsk_da, 16) },
{ ORDATA (MA, dsk_ma, 16) },
{ FLDATA (BUSY, dev_busy, INT_V_DSK) },
{ FLDATA (DONE, dev_done, INT_V_DSK) },
{ FLDATA (DISABLE, dev_disable, INT_V_DSK) },
{ FLDATA (INT, int_req, INT_V_DSK) },
{ ORDATA (WLK, dsk_wlk, 8) },
{ DRDATA (TIME, dsk_time, 24), REG_NZ + PV_LEFT },
{ FLDATA (STOP_IOE, dsk_stopioe, 0) },
{ NULL } };
{ ORDATA (STAT, dsk_stat, 16) },
{ ORDATA (DA, dsk_da, 16) },
{ ORDATA (MA, dsk_ma, 16) },
{ FLDATA (BUSY, dev_busy, INT_V_DSK) },
{ FLDATA (DONE, dev_done, INT_V_DSK) },
{ FLDATA (DISABLE, dev_disable, INT_V_DSK) },
{ FLDATA (INT, int_req, INT_V_DSK) },
{ ORDATA (WLK, dsk_wlk, 8) },
{ DRDATA (TIME, dsk_time, 24), REG_NZ + PV_LEFT },
{ FLDATA (STOP_IOE, dsk_stopioe, 0) },
{ NULL }
};
MTAB dsk_mod[] = {
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &dsk_set_size },
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &dsk_set_size },
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &dsk_set_size },
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &dsk_set_size },
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &dsk_set_size },
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &dsk_set_size },
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &dsk_set_size },
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &dsk_set_size },
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
{ 0 } };
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &dsk_set_size },
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &dsk_set_size },
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &dsk_set_size },
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &dsk_set_size },
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &dsk_set_size },
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &dsk_set_size },
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &dsk_set_size },
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &dsk_set_size },
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
{ 0 }
};
DEVICE dsk_dev = {
"DK", &dsk_unit, dsk_reg, dsk_mod,
1, 8, 21, 1, 8, 16,
NULL, NULL, &dsk_reset,
&dsk_boot, &dsk_attach, NULL,
&dsk_dib, DEV_DISABLE };
"DK", &dsk_unit, dsk_reg, dsk_mod,
1, 8, 21, 1, 8, 16,
NULL, NULL, &dsk_reset,
&dsk_boot, &dsk_attach, NULL,
&dsk_dib, DEV_DISABLE
};
/* IOT routine */
int32 dsk (int32 pulse, int32 code, int32 AC)
@@ -160,47 +165,56 @@ int32 dsk (int32 pulse, int32 code, int32 AC)
int32 t, rval;
rval = 0;
switch (code) { /* decode IR<5:7> */
case ioDIA: /* DIA */
rval = dsk_stat & DSKS_ALLERR; /* read status */
break;
case ioDOA: /* DOA */
dsk_da = AC & DSK_AMASK; /* save disk addr */
break;
case ioDIB: /* DIB */
rval = dsk_ma & AMASK; /* read mem addr */
break;
case ioDOB: /* DOB */
dsk_ma = AC & AMASK; /* save mem addr */
break; } /* end switch code */
switch (code) { /* decode IR<5:7> */
if (pulse) { /* any pulse? */
dev_busy = dev_busy & ~INT_DSK; /* clear busy */
dev_done = dev_done & ~INT_DSK; /* clear done */
int_req = int_req & ~INT_DSK; /* clear int */
dsk_stat = 0; /* clear status */
sim_cancel (&dsk_unit); } /* stop I/O */
case ioDIA: /* DIA */
rval = dsk_stat & DSKS_ALLERR; /* read status */
break;
if ((pulse == iopP) && ((dsk_wlk >> GET_DISK (dsk_da)) & 1)) { /* wrt lock? */
dev_done = dev_done | INT_DSK; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
dsk_stat = DSKS_ERR + DSKS_WLS; /* set status */
return rval; }
case ioDOA: /* DOA */
dsk_da = AC & DSK_AMASK; /* save disk addr */
break;
if (pulse & 1) { /* read or write? */
if (((uint32) (dsk_da * DSK_NUMWD)) >= dsk_unit.capac) { /* inv sev? */
dev_done = dev_done | INT_DSK; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
dsk_stat = DSKS_ERR + DSKS_NSD; /* set status */
return rval; } /* done */
dsk_unit.FUNC = pulse; /* save command */
dev_busy = dev_busy | INT_DSK; /* set busy */
t = sector_map[dsk_da & DSK_MMASK] - GET_SECTOR (dsk_time);
if (t < 0) t = t + DSK_NUMSC;
sim_activate (&dsk_unit, t * dsk_time); } /* activate */
case ioDIB: /* DIB */
rval = dsk_ma & AMASK; /* read mem addr */
break;
case ioDOB: /* DOB */
dsk_ma = AC & AMASK; /* save mem addr */
break;
} /* end switch code */
if (pulse) { /* any pulse? */
dev_busy = dev_busy & ~INT_DSK; /* clear busy */
dev_done = dev_done & ~INT_DSK; /* clear done */
int_req = int_req & ~INT_DSK; /* clear int */
dsk_stat = 0; /* clear status */
sim_cancel (&dsk_unit); /* stop I/O */
}
if ((pulse == iopP) && ((dsk_wlk >> GET_DISK (dsk_da)) & 1)) { /* wrt lock? */
dev_done = dev_done | INT_DSK; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
dsk_stat = DSKS_ERR + DSKS_WLS; /* set status */
return rval;
}
if (pulse & 1) { /* read or write? */
if (((uint32) (dsk_da * DSK_NUMWD)) >= dsk_unit.capac) { /* inv sev? */
dev_done = dev_done | INT_DSK; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
dsk_stat = DSKS_ERR + DSKS_NSD; /* set status */
return rval; /* done */
}
dsk_unit.FUNC = pulse; /* save command */
dev_busy = dev_busy | INT_DSK; /* set busy */
t = sector_map[dsk_da & DSK_MMASK] - GET_SECTOR (dsk_time);
if (t < 0) t = t + DSK_NUMSC;
sim_activate (&dsk_unit, t * dsk_time); /* activate */
}
return rval;
}
/* Unit service */
t_stat dsk_svc (UNIT *uptr)
@@ -208,58 +222,63 @@ t_stat dsk_svc (UNIT *uptr)
int32 i, da, pa;
int16 *fbuf = uptr->filebuf;
dev_busy = dev_busy & ~INT_DSK; /* clear busy */
dev_done = dev_done | INT_DSK; /* set done */
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 */
dsk_stat = DSKS_ERR + DSKS_NSD; /* set status */
return IORETURN (dsk_stopioe, SCPE_UNATT); }
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? */
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] = fbuf[da + i]; }
dsk_ma = (dsk_ma + DSK_NUMWD) & AMASK; }
if (uptr->FUNC == iopP) { /* write? */
for (i = 0; i < DSK_NUMWD; i++) { /* copy sector */
pa = MapAddr (0, (dsk_ma + i) & AMASK); /* map address */
fbuf[da + i] = M[pa]; }
if (((uint32) (da + i)) >= uptr->hwmark) /* past end? */
uptr->hwmark = da + i + 1; /* upd hwmark */
dsk_ma = (dsk_ma + DSK_NUMWD + 3) & AMASK; }
da = dsk_da * DSK_NUMWD; /* calc disk addr */
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] = fbuf[da + i];
}
dsk_ma = (dsk_ma + DSK_NUMWD) & AMASK;
}
if (uptr->FUNC == iopP) { /* write? */
for (i = 0; i < DSK_NUMWD; i++) { /* copy sector */
pa = MapAddr (0, (dsk_ma + i) & AMASK); /* map address */
fbuf[da + i] = M[pa];
}
if (((uint32) (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 */
dsk_stat = 0; /* set status */
return SCPE_OK;
}
/* Reset routine */
t_stat dsk_reset (DEVICE *dptr)
{
dsk_stat = dsk_da = dsk_ma = 0;
dev_busy = dev_busy & ~INT_DSK; /* clear busy */
dev_done = dev_done & ~INT_DSK; /* clear done */
int_req = int_req & ~INT_DSK; /* clear int */
dev_busy = dev_busy & ~INT_DSK; /* clear busy */
dev_done = dev_done & ~INT_DSK; /* clear done */
int_req = int_req & ~INT_DSK; /* clear int */
sim_cancel (&dsk_unit);
return SCPE_OK;
}
/* Bootstrap routine */
#define BOOT_START 2000
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
#define BOOT_START 2000
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
static const int32 boot_rom[] = {
060220, /* NIOC DSK ; clear disk */
0102400, /* SUB 0,0 ; addr = 0 */
061020, /* DOA 0,DSK ; set disk addr */
062120, /* DOBS 0,DSK ; set mem addr, rd */
063620, /* SKPDN DSK ; done? */
000776, /* JMP .-2 */
000377, /* JMP 377 */
};
060220, /* NIOC DSK ; clear disk */
0102400, /* SUB 0,0 ; addr = 0 */
061020, /* DOA 0,DSK ; set disk addr */
062120, /* DOBS 0,DSK ; set mem addr, rd */
063620, /* SKPDN DSK ; done? */
000776, /* JMP .-2 */
000377, /* JMP 377 */
};
t_stat dsk_boot (int32 unitno, DEVICE *dptr)
{
@@ -282,11 +301,11 @@ t_stat r;
r = attach_unit (uptr, cptr);
if (r != SCPE_OK) return r;
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
p = (sz + ds_bytes - 1) / ds_bytes;
if (p >= DSK_NUMDK) p = DSK_NUMDK - 1;
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
(p << UNIT_V_PLAT); }
uptr->capac = UNIT_GETP (uptr->flags) * DSK_DKSIZE; /* set capacity */
p = (sz + ds_bytes - 1) / ds_bytes;
if (p >= DSK_NUMDK) p = DSK_NUMDK - 1;
uptr->flags = (uptr->flags & ~UNIT_PLAT) | (p << UNIT_V_PLAT);
}
uptr->capac = UNIT_GETP (uptr->flags) * DSK_DKSIZE; /* set capacity */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* nova_lp.c: NOVA line printer simulator
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,21 +19,21 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
lpt line printer
lpt line printer
25-Apr-03 RMS Revised for extended file support
30-May-02 RMS Widened POS to 32b
25-Apr-03 RMS Revised for extended file support
30-May-02 RMS Widened POS to 32b
*/
#include "nova_defs.h"
extern int32 int_req, dev_busy, dev_done, dev_disable;
int32 lpt_stopioe = 0; /* stop on error */
int32 lpt_stopioe = 0; /* stop on error */
int32 lpt (int32 pulse, int32 code, int32 AC);
t_stat lpt_svc (UNIT *uptr);
@@ -41,56 +41,63 @@ t_stat lpt_reset (DEVICE *dptr);
/* LPT data structures
lpt_dev LPT device descriptor
lpt_unit LPT unit descriptor
lpt_reg LPT register list
lpt_dev LPT device descriptor
lpt_unit LPT unit descriptor
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 };
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
};
REG lpt_reg[] = {
{ ORDATA (BUF, lpt_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_LPT) },
{ FLDATA (DONE, dev_done, INT_V_LPT) },
{ FLDATA (DISABLE, dev_disable, INT_V_LPT) },
{ FLDATA (INT, int_req, INT_V_LPT) },
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
{ NULL } };
{ ORDATA (BUF, lpt_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_LPT) },
{ FLDATA (DONE, dev_done, INT_V_LPT) },
{ FLDATA (DISABLE, dev_disable, INT_V_LPT) },
{ FLDATA (INT, int_req, INT_V_LPT) },
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
{ NULL }
};
DEVICE lpt_dev = {
"LPT", &lpt_unit, lpt_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &lpt_reset,
NULL, NULL, NULL,
&lpt_dib, DEV_DISABLE };
"LPT", &lpt_unit, lpt_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &lpt_reset,
NULL, NULL, NULL,
&lpt_dib, DEV_DISABLE
};
/* IOT routine */
int32 lpt (int32 pulse, int32 code, int32 AC)
{
if (code == ioDOA) lpt_unit.buf = AC & 0177;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_LPT; /* set busy */
dev_done = dev_done & ~INT_LPT; /* clear done, int */
int_req = int_req & ~INT_LPT;
if ((lpt_unit.buf != 015) && (lpt_unit.buf != 014) &&
(lpt_unit.buf != 012))
return (lpt_svc (&lpt_unit) << IOT_V_REASON);
sim_activate (&lpt_unit, lpt_unit.wait);
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_LPT; /* clear busy */
dev_done = dev_done & ~INT_LPT; /* clear done, int */
int_req = int_req & ~INT_LPT;
sim_cancel (&lpt_unit); /* deactivate unit */
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_LPT; /* set busy */
dev_done = dev_done & ~INT_LPT; /* clear done, int */
int_req = int_req & ~INT_LPT;
if ((lpt_unit.buf != 015) && (lpt_unit.buf != 014) &&
(lpt_unit.buf != 012))
return (lpt_svc (&lpt_unit) << IOT_V_REASON);
sim_activate (&lpt_unit, lpt_unit.wait);
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_LPT; /* clear busy */
dev_done = dev_done & ~INT_LPT; /* clear done, int */
int_req = int_req & ~INT_LPT;
sim_cancel (&lpt_unit); /* deactivate unit */
break;
} /* end switch */
return 0;
}
@@ -98,15 +105,16 @@ return 0;
t_stat lpt_svc (UNIT *uptr)
{
dev_busy = dev_busy & ~INT_LPT; /* clear busy */
dev_done = dev_done | INT_LPT; /* set done */
dev_busy = dev_busy & ~INT_LPT; /* clear busy */
dev_done = dev_done | INT_LPT; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lpt_stopioe, SCPE_UNATT);
if ((lpt_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lpt_stopioe, SCPE_UNATT);
if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) {
perror ("LPT I/O error");
clearerr (lpt_unit.fileref);
return SCPE_IOERR; }
perror ("LPT I/O error");
clearerr (lpt_unit.fileref);
return SCPE_IOERR;
}
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK;
}
@@ -116,9 +124,9 @@ return SCPE_OK;
t_stat lpt_reset (DEVICE *dptr)
{
lpt_unit.buf = 0;
dev_busy = dev_busy & ~INT_LPT; /* clear busy */
dev_done = dev_done & ~INT_LPT; /* clear done, int */
dev_busy = dev_busy & ~INT_LPT; /* clear busy */
dev_done = dev_done & ~INT_LPT; /* clear done, int */
int_req = int_req & ~INT_LPT;
sim_cancel (&lpt_unit); /* deactivate unit */
sim_cancel (&lpt_unit); /* deactivate unit */
return SCPE_OK;
}

View File

@@ -19,46 +19,47 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
mta magnetic tape
mta magnetic tape
18-Mar-05 RMS Added attached test to detach routine
22-Nov-03 CEO DIB returns # records skipped after space fwd
22-Nov-03 CEO Removed cancel of tape events in IORST
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
28-Feb-03 RMS Revised for magtape library
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
30-Nov-01 RMS Added read only unit, extended SET/SHOW support
24-Nov-01 RMS Changed POS, USTAT, FLG to an array
26-Apr-01 RMS Added device enable/disable support
18-Apr-01 RMS Changed to rewind tape before boot
10-Dec-00 RMS Added Eclipse support from Charles Owen
15-Oct-00 RMS Editorial changes
11-Nov-98 CEO Removed clear of mta_ma on iopC
04-Oct-98 RMS V2.4 magtape format
18-Jan-97 RMS V2.3 magtape format
29-Jun-96 RMS Added unit enable/disable support
16-Aug-05 RMS Fixed C++ declaration and cast problems
18-Mar-05 RMS Added attached test to detach routine
22-Nov-03 CEO DIB returns # records skipped after space fwd
22-Nov-03 CEO Removed cancel of tape events in IORST
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
28-Feb-03 RMS Revised for magtape library
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
30-Nov-01 RMS Added read only unit, extended SET/SHOW support
24-Nov-01 RMS Changed POS, USTAT, FLG to an array
26-Apr-01 RMS Added device enable/disable support
18-Apr-01 RMS Changed to rewind tape before boot
10-Dec-00 RMS Added Eclipse support from Charles Owen
15-Oct-00 RMS Editorial changes
11-Nov-98 CEO Removed clear of mta_ma on iopC
04-Oct-98 RMS V2.4 magtape format
18-Jan-97 RMS V2.3 magtape format
29-Jun-96 RMS Added unit enable/disable support
Magnetic tapes are represented as a series of variable records
of the form:
32b byte count byte count is little endian
byte 0
byte 1
:
byte n-2
byte n-1
32b byte count
32b byte count byte count is little endian
byte 0
byte 1
:
byte n-2
byte n-1
32b byte count
If the byte count is odd, the record is padded with an extra byte
of junk. File marks are represented by a byte count of 0 and are
@@ -68,95 +69,95 @@
#include "nova_defs.h"
#include "sim_tape.h"
#define MTA_NUMDR 8 /* #drives */
#define USTAT u3 /* unit status */
#define MTA_MAXFR (1 << 16) /* max record lnt */
#define WC_SIZE (1 << 14) /* max word count */
#define WC_MASK (WC_SIZE - 1)
#define MTA_NUMDR 8 /* #drives */
#define USTAT u3 /* unit status */
#define MTA_MAXFR (1 << 16) /* max record lnt */
#define WC_SIZE (1 << 14) /* max word count */
#define WC_MASK (WC_SIZE - 1)
/* Command/unit */
#define CU_CI 0100000 /* clear interrupt */
#define CU_EP 0002000 /* poll enable */
#define CU_DE 0001000 /* disable erase */
#define CU_DA 0000400 /* disable autoretry */
#define CU_PE 0000400 /* PE mode */
#define CU_V_CMD 3 /* command */
#define CU_M_CMD 027
#define CU_READ 000
#define CU_REWIND 001
#define CU_CMODE 002
#define CU_SPACEF 003
#define CU_SPACER 004
#define CU_WRITE 005
#define CU_WREOF 006
#define CU_ERASE 007
#define CU_READNS 020
#define CU_UNLOAD 021
#define CU_DMODE 022
#define CU_V_UNIT 0 /* unit */
#define CU_M_UNIT 07
#define GET_CMD(x) (((x) >> CU_V_CMD) & CU_M_CMD)
#define GET_UNIT(x) (((x) >> CU_V_UNIT) & CU_M_UNIT)
#define CU_CI 0100000 /* clear interrupt */
#define CU_EP 0002000 /* poll enable */
#define CU_DE 0001000 /* disable erase */
#define CU_DA 0000400 /* disable autoretry */
#define CU_PE 0000400 /* PE mode */
#define CU_V_CMD 3 /* command */
#define CU_M_CMD 027
#define CU_READ 000
#define CU_REWIND 001
#define CU_CMODE 002
#define CU_SPACEF 003
#define CU_SPACER 004
#define CU_WRITE 005
#define CU_WREOF 006
#define CU_ERASE 007
#define CU_READNS 020
#define CU_UNLOAD 021
#define CU_DMODE 022
#define CU_V_UNIT 0 /* unit */
#define CU_M_UNIT 07
#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> */
#define STA_ERR1 (0100000u << 16) /* error */
#define STA_DLT (0040000 << 16) /* data late */
#define STA_REW (0020000 << 16) /* *rewinding */
#define STA_ILL (0010000 << 16) /* illegal */
#define STA_HDN (0004000 << 16) /* high density */
#define STA_DAE (0002000 << 16) /* data error */
#define STA_EOT (0001000 << 16) /* *end of tape */
#define STA_EOF (0000400 << 16) /* *end of file */
#define STA_BOT (0000200 << 16) /* *start of tape */
#define STA_9TK (0000100 << 16) /* nine track */
#define STA_BAT (0000040 << 16) /* bad tape */
#define STA_CHG (0000010 << 16) /* status change */
#define STA_WLK (0000004 << 16) /* *write lock */
#define STA_ODD (0000002 << 16) /* odd character */
#define STA_RDY (0000001 << 16) /* *drive ready */
#define STA_ERR1 (0100000u << 16) /* error */
#define STA_DLT (0040000 << 16) /* data late */
#define STA_REW (0020000 << 16) /* *rewinding */
#define STA_ILL (0010000 << 16) /* illegal */
#define STA_HDN (0004000 << 16) /* high density */
#define STA_DAE (0002000 << 16) /* data error */
#define STA_EOT (0001000 << 16) /* *end of tape */
#define STA_EOF (0000400 << 16) /* *end of file */
#define STA_BOT (0000200 << 16) /* *start of tape */
#define STA_9TK (0000100 << 16) /* nine track */
#define STA_BAT (0000040 << 16) /* bad tape */
#define STA_CHG (0000010 << 16) /* status change */
#define STA_WLK (0000004 << 16) /* *write lock */
#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> */
#define STA_ERR2 0100000 /* error */
#define STA_RWY 0040000 /* runaway tape */
#define STA_FGP 0020000 /* false gap */
#define STA_CDL 0004000 /* corrected dlt */
#define STA_V_UNIT 8
#define STA_M_UNIT 07 /* unit */
#define STA_WCO 0000200 /* word count ovflo */
#define STA_BDS 0000100 /* bad signal */
#define STA_OVS 0000040 /* overskew */
#define STA_CRC 0000020 /* check error */
#define STA_STE 0000010 /* single trk error */
#define STA_FPR 0000004 /* false preamble */
#define STA_FMT 0000002 /* format error */
#define STA_PEM 0000001 /* *PE mode */
#define STA_ERR2 0100000 /* error */
#define STA_RWY 0040000 /* runaway tape */
#define STA_FGP 0020000 /* false gap */
#define STA_CDL 0004000 /* corrected dlt */
#define STA_V_UNIT 8
#define STA_M_UNIT 07 /* unit */
#define STA_WCO 0000200 /* word count ovflo */
#define STA_BDS 0000100 /* bad signal */
#define STA_OVS 0000040 /* overskew */
#define STA_CRC 0000020 /* check error */
#define STA_STE 0000010 /* single trk error */
#define STA_FPR 0000004 /* false preamble */
#define STA_FMT 0000002 /* format error */
#define STA_PEM 0000001 /* *PE mode */
#define STA_EFLGS1 (STA_DLT | STA_ILL | STA_DAE | STA_EOT | \
STA_EOF | STA_BOT | STA_BAT | STA_ODD)
#define STA_EFLGS2 (STA_FGP | STA_CDL | STA_BDS | STA_OVS | \
STA_CRC | STA_FPR | STA_FPR) /* set error 2 */
#define STA_CLR ((020 << 16) | 0010000) /* always clear */
#define STA_SET (STA_HDN | STA_9TK) /* always set */
#define STA_DYN (STA_REW | STA_EOT | STA_EOF | STA_BOT | \
STA_WLK | STA_RDY | STA_PEM) /* kept in USTAT */
#define STA_MON (STA_REW | STA_BOT | STA_WLK | STA_RDY | \
STA_PEM) /* set status chg */
#define STA_EFLGS1 (STA_DLT | STA_ILL | STA_DAE | STA_EOT | \
STA_EOF | STA_BOT | STA_BAT | STA_ODD)
#define STA_EFLGS2 (STA_FGP | STA_CDL | STA_BDS | STA_OVS | \
STA_CRC | STA_FPR | STA_FPR) /* set error 2 */
#define STA_CLR ((020 << 16) | 0010000) /* always clear */
#define STA_SET (STA_HDN | STA_9TK) /* always set */
#define STA_DYN (STA_REW | STA_EOT | STA_EOF | STA_BOT | \
STA_WLK | STA_RDY | STA_PEM) /* kept in USTAT */
#define STA_MON (STA_REW | STA_BOT | STA_WLK | STA_RDY | \
STA_PEM) /* set status chg */
extern uint16 M[];
extern UNIT cpu_unit;
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 */
int32 mta_sta = 0; /* status register */
int32 mta_ep = 0; /* enable polling */
int32 mta_cwait = 100; /* command latency */
int32 mta_rwait = 100; /* record latency */
uint8 *mtxb = NULL; /* transfer buffer */
int32 mta_ma = 0; /* memory address */
int32 mta_wc = 0; /* word count */
int32 mta_cu = 0; /* command/unit */
int32 mta_sta = 0; /* status register */
int32 mta_ep = 0; /* enable polling */
int32 mta_cwait = 100; /* command latency */
int32 mta_rwait = 100; /* record latency */
uint8 *mtxb = NULL; /* transfer buffer */
DEVICE mta_dev;
int32 mta (int32 pulse, int32 code, int32 AC);
@@ -170,62 +171,67 @@ void mta_upddsta (UNIT *uptr, int32 newsta);
t_stat mta_map_err (UNIT *uptr, t_stat st);
t_stat mta_vlock (UNIT *uptr, int32 val, char *cptr, void *desc);
static const int ctype[32] = { /* c vs r timing */
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,
0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 };
0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1
};
/* MTA data structures
mta_dev MTA device descriptor
mta_unit MTA unit list
mta_reg MTA register list
mta_mod MTA modifier list
mta_dev MTA device descriptor
mta_unit MTA unit list
mta_reg MTA register list
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) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) } };
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
{ UDATA (&mta_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }
};
REG mta_reg[] = {
{ ORDATA (CU, mta_cu, 16) },
{ ORDATA (MA, mta_ma, 16) },
{ ORDATA (WC, mta_wc, 16) },
{ GRDATA (STA1, mta_sta, 8, 16, 16) },
{ ORDATA (STA2, mta_sta, 16) },
{ FLDATA (EP, mta_ep, 0) },
{ FLDATA (BUSY, dev_busy, INT_V_MTA) },
{ FLDATA (DONE, dev_done, INT_V_MTA) },
{ FLDATA (DISABLE, dev_disable, INT_V_MTA) },
{ FLDATA (INT, int_req, INT_V_MTA) },
{ DRDATA (CTIME, mta_cwait, 24), PV_LEFT },
{ DRDATA (RTIME, mta_rwait, 24), PV_LEFT },
{ URDATA (UST, mta_unit[0].USTAT, 8, 32, 0, MTA_NUMDR, 0) },
{ URDATA (POS, mta_unit[0].pos, 8, T_ADDR_W, 0,
MTA_NUMDR, REG_RO | PV_LEFT) },
{ NULL } };
{ ORDATA (CU, mta_cu, 16) },
{ ORDATA (MA, mta_ma, 16) },
{ ORDATA (WC, mta_wc, 16) },
{ GRDATA (STA1, mta_sta, 8, 16, 16) },
{ ORDATA (STA2, mta_sta, 16) },
{ FLDATA (EP, mta_ep, 0) },
{ FLDATA (BUSY, dev_busy, INT_V_MTA) },
{ FLDATA (DONE, dev_done, INT_V_MTA) },
{ FLDATA (DISABLE, dev_disable, INT_V_MTA) },
{ FLDATA (INT, int_req, INT_V_MTA) },
{ DRDATA (CTIME, mta_cwait, 24), PV_LEFT },
{ DRDATA (RTIME, mta_rwait, 24), PV_LEFT },
{ URDATA (UST, mta_unit[0].USTAT, 8, 32, 0, MTA_NUMDR, 0) },
{ URDATA (POS, mta_unit[0].pos, 8, T_ADDR_W, 0,
MTA_NUMDR, REG_RO | PV_LEFT) },
{ NULL }
};
MTAB mta_mod[] = {
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", &mta_vlock },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &mta_vlock },
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ 0 } };
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", &mta_vlock },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &mta_vlock },
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ 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_dib, DEV_DISABLE };
"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_dib, DEV_DISABLE
};
/* IOT routine */
int32 mta (int32 pulse, int32 code, int32 AC)
@@ -234,73 +240,88 @@ UNIT *uptr;
int32 u, c, rval;
rval = 0;
uptr = mta_dev.units + GET_UNIT(mta_cu); /* get unit */
switch (code) { /* decode IR<5:7> */
case ioDIA: /* DIA */
rval = (mta_updcsta (uptr) >> 16) & DMASK; /* return status 1 */
break;
case ioDOA: /* DOA */
/* if (AC & CU_CI) ... clear ep int */
mta_cu = AC; /* save cmd/unit */
uptr = mta_dev.units + GET_UNIT(mta_cu); /* get unit */
mta_updcsta (uptr); /* update status */
break;
case ioDIB: /* DIB */
rval = mta_ma & AMASK; /* return ma */
break;
case ioDOB: /* DOB */
mta_ma = AC & AMASK; /* save ma */
break;
case ioDIC: /* DIC */
rval = mta_updcsta (uptr) & DMASK; /* return status 2 */
break;
case ioDOC: /* DOC */
mta_wc = ((AC & 040000) << 1) | (AC & 077777); /* save wc */
break; } /* end switch code */
/* IOT, continued */
uptr = mta_dev.units + GET_UNIT(mta_cu); /* get unit */
switch (code) { /* decode IR<5:7> */
case ioDIA: /* DIA */
rval = (mta_updcsta (uptr) >> 16) & DMASK; /* return status 1 */
break;
case ioDOA: /* DOA */
/* if (AC & CU_CI) ... clear ep int */
mta_cu = AC; /* save cmd/unit */
uptr = mta_dev.units + GET_UNIT(mta_cu); /* get unit */
mta_updcsta (uptr); /* update status */
break;
case ioDIB: /* DIB */
rval = mta_ma & AMASK; /* return ma */
break;
case ioDOB: /* DOB */
mta_ma = AC & AMASK; /* save ma */
break;
case ioDIC: /* DIC */
rval = mta_updcsta (uptr) & DMASK; /* return status 2 */
break;
case ioDOC: /* DOC */
mta_wc = ((AC & 040000) << 1) | (AC & 077777); /* save wc */
break;
} /* end switch code */
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? */
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 */
~(STA_BOT | STA_EOF | STA_EOT | STA_RDY)) | STA_REW);
sim_activate (uptr, mta_rwait); /* start IO */
if (c == CU_UNLOAD) detach_unit (uptr);
}
else {
mta_sta = 0; /* clear errors */
dev_busy = dev_busy | INT_MTA; /* set busy */
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 &
~(STA_BOT | STA_EOF | STA_EOT | STA_RDY));
sim_activate (uptr, mta_rwait);
}
}
mta_updcsta (uptr); /* update status */
break;
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);
sim_cancel (uptr);
}
}
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
dev_done = dev_done & ~INT_MTA; /* clear done */
int_req = int_req & ~INT_MTA; /* clear int */
mta_sta = mta_cu = 0; /* clear registers */
mta_updcsta (&mta_unit[0]); /* update status */
break;
} /* end case pulse */
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? */
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 */
~(STA_BOT | STA_EOF | STA_EOT | STA_RDY)) | STA_REW);
sim_activate (uptr, mta_rwait); /* start IO */
if (c == CU_UNLOAD) detach_unit (uptr); }
else {
mta_sta = 0; /* clear errors */
dev_busy = dev_busy | INT_MTA; /* set busy */
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 &
~(STA_BOT | STA_EOF | STA_EOT | STA_RDY));
sim_activate (uptr, mta_rwait); } }
mta_updcsta (uptr); /* update status */
break;
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);
sim_cancel (uptr); } }
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
dev_done = dev_done & ~INT_MTA; /* clear done */
int_req = int_req & ~INT_MTA; /* clear int */
mta_sta = mta_cu = 0; /* clear registers */
mta_updcsta (&mta_unit[0]); /* update status */
break; } /* end case pulse */
return rval;
}
/* Unit service
If rewind done, reposition to start of tape, set status
@@ -314,125 +335,130 @@ t_mtrlnt i, cbc, tbc, wc;
uint16 c1, c2;
t_stat st, r = SCPE_OK;
u = uptr - mta_dev.units; /* get unit number */
c = GET_CMD (mta_cu); /* command */
wc = WC_SIZE - (mta_wc & WC_MASK); /* io wc */
u = uptr - mta_dev.units; /* get unit number */
c = GET_CMD (mta_cu); /* command */
wc = WC_SIZE - (mta_wc & WC_MASK); /* io wc */
if (uptr->USTAT & STA_REW) { /* rewind? */
sim_tape_rewind (uptr); /* update tape */
mta_upddsta (uptr, (uptr->USTAT & ~STA_REW) | STA_BOT | STA_RDY);
if (u == GET_UNIT (mta_cu)) mta_updcsta (uptr);
return SCPE_OK; }
if (uptr->USTAT & STA_REW) { /* rewind? */
sim_tape_rewind (uptr); /* update tape */
mta_upddsta (uptr, (uptr->USTAT & ~STA_REW) | STA_BOT | STA_RDY);
if (u == GET_UNIT (mta_cu)) mta_updcsta (uptr);
return SCPE_OK;
}
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
mta_upddsta (uptr, 0); /* unit off line */
mta_sta = mta_sta | STA_ILL; } /* illegal operation */
else switch (c) { /* case on command */
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
mta_upddsta (uptr, 0); /* unit off line */
mta_sta = mta_sta | STA_ILL; /* illegal operation */
}
else switch (c) { /* case on command */
case CU_CMODE: /* controller mode */
mta_ep = mta_cu & CU_EP;
break;
case CU_DMODE: /* drive mode */
if (!sim_tape_bot (uptr)) 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);
break;
/* Unit service, continued */
case CU_CMODE: /* controller mode */
mta_ep = mta_cu & CU_EP;
break;
case CU_READ: /* read */
case CU_READNS: /* read non-stop */
st = sim_tape_rdrecf (uptr, mtxb, &tbc, MTA_MAXFR); /* read rec */
if (st == MTSE_RECE) mta_sta = mta_sta | STA_DAE; /* rec in err? */
else if (st != MTSE_OK) { /* other error? */
r = mta_map_err (uptr, st); /* map error */
break; }
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 */
for (i = p = 0; i < wc; i++) { /* copy buf to mem */
c1 = mtxb[p++];
c2 = mtxb[p++];
pa = MapAddr (0, mta_ma); /* map address */
if (MEM_ADDR_OK (pa)) M[pa] = (c1 << 8) | c2;
mta_ma = (mta_ma + 1) & AMASK; }
mta_wc = (mta_wc + wc) & DMASK;
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break;
case CU_DMODE: /* drive mode */
if (!sim_tape_bot (uptr)) 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);
break;
case CU_WRITE: /* write */
tbc = wc * 2; /* io byte count */
for (i = p = 0; i < wc; i++) { /* copy to buffer */
pa = MapAddr (0, mta_ma); /* map address */
mtxb[p++] = (M[pa] >> 8) & 0377;
mtxb[p++] = M[pa] & 0377;
mta_ma = (mta_ma + 1) & AMASK; }
if (st = sim_tape_wrrecf (uptr, mtxb, tbc)) { /* write rec, err? */
r = mta_map_err (uptr, st); /* map error */
mta_ma = (mta_ma - wc) & AMASK; } /* restore wc */
else mta_wc = 0; /* clear wc */
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break;
/* Unit service, continued */
case CU_READ: /* read */
case CU_READNS: /* read non-stop */
st = sim_tape_rdrecf (uptr, mtxb, &tbc, MTA_MAXFR); /* read rec */
if (st == MTSE_RECE) mta_sta = mta_sta | STA_DAE; /* rec in err? */
else if (st != MTSE_OK) { /* other error? */
r = mta_map_err (uptr, st); /* map error */
break;
}
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 */
}
for (i = p = 0; i < wc; i++) { /* copy buf to mem */
c1 = mtxb[p++];
c2 = mtxb[p++];
pa = MapAddr (0, mta_ma); /* map address */
if (MEM_ADDR_OK (pa)) M[pa] = (c1 << 8) | c2;
mta_ma = (mta_ma + 1) & AMASK;
}
mta_wc = (mta_wc + wc) & DMASK;
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break;
case CU_WREOF: /* write eof */
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
r = mta_map_err (uptr, st); /* map error */
else mta_upddsta (uptr, uptr->USTAT | STA_EOF | STA_RDY);
break;
case CU_WRITE: /* write */
tbc = wc * 2; /* io byte count */
for (i = p = 0; i < wc; i++) { /* copy to buffer */
pa = MapAddr (0, mta_ma); /* map address */
mtxb[p++] = (M[pa] >> 8) & 0377;
mtxb[p++] = M[pa] & 0377;
mta_ma = (mta_ma + 1) & AMASK;
}
if (st = sim_tape_wrrecf (uptr, mtxb, tbc)) { /* write rec, err? */
r = mta_map_err (uptr, st); /* map error */
mta_ma = (mta_ma - wc) & AMASK; /* restore wc */
}
else mta_wc = 0; /* clear wc */
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break;
case CU_ERASE: /* erase */
if (sim_tape_wrp (uptr)) /* write protected? */
r = mta_map_err (uptr, MTSE_WRP); /* map error */
else mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break;
case CU_WREOF: /* write eof */
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
r = mta_map_err (uptr, st); /* map error */
else mta_upddsta (uptr, uptr->USTAT | STA_EOF | STA_RDY);
break;
case CU_SPACEF: /* space forward */
do {
mta_wc = (mta_wc + 1) & DMASK; /* incr wc */
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
r = mta_map_err (uptr, st); /* map error */
break; }
}
while (mta_wc != 0);
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
mta_ma = mta_wc; /* Word count = # records */
break;
case CU_ERASE: /* erase */
if (sim_tape_wrp (uptr)) /* write protected? */
r = mta_map_err (uptr, MTSE_WRP); /* map error */
else mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break;
case CU_SPACER: /* space reverse */
do {
mta_wc = (mta_wc + 1) & DMASK; /* incr wc */
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
r = mta_map_err (uptr, st); /* map error */
break; }
}
while (mta_wc != 0);
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
mta_ma = mta_wc; /* Word count = # records */
break;
case CU_SPACEF: /* space forward */
do {
mta_wc = (mta_wc + 1) & DMASK; /* incr wc */
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
r = mta_map_err (uptr, st); /* map error */
break;
}
} while (mta_wc != 0);
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
mta_ma = mta_wc; /* word count = # records */
break;
default: /* reserved */
mta_sta = mta_sta | STA_ILL;
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break; } /* end case */
case CU_SPACER: /* space reverse */
do {
mta_wc = (mta_wc + 1) & DMASK; /* incr wc */
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
r = mta_map_err (uptr, st); /* map error */
break;
}
} while (mta_wc != 0);
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
mta_ma = mta_wc; /* word count = # records */
break;
mta_updcsta (uptr); /* update status */
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
dev_done = dev_done | INT_MTA; /* set done */
default: /* reserved */
mta_sta = mta_sta | STA_ILL;
mta_upddsta (uptr, uptr->USTAT | STA_RDY);
break;
} /* end case */
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 r;
}
/* Update controller status */
int32 mta_updcsta (UNIT *uptr) /* update ctrl */
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;
@@ -440,19 +466,21 @@ return mta_sta;
/* Update drive status */
void mta_upddsta (UNIT *uptr, int32 newsta) /* drive status */
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 - 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 */
/* if (mta_ep) { /* if polling */
/* 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;
}
@@ -461,41 +489,51 @@ return;
t_stat mta_map_err (UNIT *uptr, t_stat st)
{
switch (st) {
case MTSE_FMT: /* illegal fmt */
mta_upddsta (uptr, uptr->USTAT | STA_WLK | STA_RDY);
case MTSE_UNATT: /* unattached */
mta_sta = mta_sta | STA_ILL;
case MTSE_OK: /* no error */
return SCPE_IERR; /* never get here! */
case MTSE_TMK: /* end of file */
mta_upddsta (uptr, uptr->USTAT | STA_RDY | STA_EOF);
break;
case MTSE_IOERR: /* IO error */
mta_sta = mta_sta | STA_DAE; /* data error */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
return SCPE_IOERR;
case MTSE_INVRL: /* invalid rec lnt */
mta_sta = mta_sta | STA_DAE; /* data error */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
return SCPE_MTRLNT;
case MTSE_RECE: /* record in error */
mta_sta = mta_sta | STA_DAE; /* data error */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
break;
case MTSE_EOM: /* end of medium */
mta_sta = mta_sta | STA_BAT; /* bad tape */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
break;
case MTSE_BOT: /* reverse into BOT */
mta_upddsta (uptr, uptr->USTAT | STA_RDY | STA_BOT);
break;
case MTSE_WRP: /* write protect */
mta_upddsta (uptr, uptr->USTAT | STA_WLK | STA_RDY);
mta_sta = mta_sta | STA_ILL; /* illegal operation */
break; }
case MTSE_FMT: /* illegal fmt */
mta_upddsta (uptr, uptr->USTAT | STA_WLK | STA_RDY);
case MTSE_UNATT: /* unattached */
mta_sta = mta_sta | STA_ILL;
case MTSE_OK: /* no error */
return SCPE_IERR; /* never get here! */
case MTSE_TMK: /* end of file */
mta_upddsta (uptr, uptr->USTAT | STA_RDY | STA_EOF);
break;
case MTSE_IOERR: /* IO error */
mta_sta = mta_sta | STA_DAE; /* data error */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
return SCPE_IOERR;
case MTSE_INVRL: /* invalid rec lnt */
mta_sta = mta_sta | STA_DAE; /* data error */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
return SCPE_MTRLNT;
case MTSE_RECE: /* record in error */
mta_sta = mta_sta | STA_DAE; /* data error */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
break;
case MTSE_EOM: /* end of medium */
mta_sta = mta_sta | STA_BAT; /* bad tape */
mta_upddsta (uptr, uptr->USTAT | STA_RDY); /* ready */
break;
case MTSE_BOT: /* reverse into BOT */
mta_upddsta (uptr, uptr->USTAT | STA_RDY | STA_BOT);
break;
case MTSE_WRP: /* write protect */
mta_upddsta (uptr, uptr->USTAT | STA_WLK | STA_RDY);
mta_sta = mta_sta | STA_ILL; /* illegal operation */
break;
}
return SCPE_OK;
}
/* Reset routine */
t_stat mta_reset (DEVICE *dptr)
@@ -503,29 +541,30 @@ t_stat mta_reset (DEVICE *dptr)
int32 u;
UNIT *uptr;
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
dev_done = dev_done & ~INT_MTA; /* clear done, int */
dev_busy = dev_busy & ~INT_MTA; /* clear busy */
dev_done = dev_done & ~INT_MTA; /* clear done, int */
int_req = int_req & ~INT_MTA;
mta_cu = mta_wc = mta_ma = mta_sta = 0; /* clear registers */
mta_cu = mta_wc = mta_ma = mta_sta = 0; /* clear registers */
mta_ep = 0;
/* AOS Installer does an IORST after a tape rewind command but before it can
be serviced, yet expects the tape to have been rewound */
for (u = 0; u < MTA_NUMDR; u++) { /* loop thru units */
uptr = mta_dev.units + u;
if (sim_is_active (uptr) && /* active and */
(uptr->flags & STA_REW)) /* rewinding? */
sim_tape_rewind (uptr); /* update tape */
sim_tape_reset (uptr); /* clear pos flag */
sim_cancel (uptr); /* cancel activity */
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_RDY |
for (u = 0; u < MTA_NUMDR; u++) { /* loop thru units */
uptr = mta_dev.units + u;
if (sim_is_active (uptr) && /* active and */
(uptr->flags & STA_REW)) /* rewinding? */
sim_tape_rewind (uptr); /* update tape */
sim_tape_reset (uptr); /* clear pos flag */
sim_cancel (uptr); /* cancel activity */
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_RDY |
(uptr->USTAT & STA_PEM) |
(sim_tape_wrp (uptr)? STA_WLK: 0) |
(sim_tape_bot (uptr)? STA_BOT: 0);
else uptr->USTAT = 0; }
mta_updcsta (&mta_unit[0]); /* update status */
if (mtxb == NULL) mtxb = calloc (MTA_MAXFR, sizeof (uint8));
else uptr->USTAT = 0;
}
mta_updcsta (&mta_unit[0]); /* update status */
if (mtxb == NULL) mtxb = (uint8 *) calloc (MTA_MAXFR, sizeof (uint8));
if (mtxb == NULL) return SCPE_MEM;
return SCPE_OK;
}
@@ -539,7 +578,7 @@ t_stat r;
r = sim_tape_attach (uptr, cptr);
if (r != SCPE_OK) return r;
if (!sim_is_active (uptr)) mta_upddsta (uptr, STA_RDY | STA_BOT | STA_PEM |
(sim_tape_wrp (uptr)? STA_WLK: 0));
(sim_tape_wrp (uptr)? STA_WLK: 0));
return r;
}
@@ -547,7 +586,7 @@ return r;
t_stat mta_detach (UNIT* uptr)
{
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
if (!sim_is_active (uptr)) mta_upddsta (uptr, 0);
return sim_tape_detach (uptr);
}
@@ -557,11 +596,11 @@ return sim_tape_detach (uptr);
t_stat mta_vlock (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if ((uptr->flags & UNIT_ATT) && (val || sim_tape_wrp (uptr)))
mta_upddsta (uptr, uptr->USTAT | STA_WLK);
mta_upddsta (uptr, uptr->USTAT | STA_WLK);
else mta_upddsta (uptr, uptr->USTAT & ~STA_WLK);
return SCPE_OK;
}
/* Bootstrap routine */
#define BOOT_START 02000
@@ -569,25 +608,25 @@ return SCPE_OK;
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
static const int32 boot_rom[] = {
0060222, /* NIOC 0,MTA ; clear disk */
0020417, /* LDA 0,UNIT ; unit */
0024417, /* LDA 1,REWIND ; cmd */
0107000, /* ADD 0,1 ; cmd + unit */
0065122, /* DOAS 1,MTA ; start rewind */
0070422, /* DIA 2,MTA ; get status */
0151213, /* MOVR# 2,2,SNC ; skip if done */
0000776, /* JMP .-2 */
0126400, /* SUB 1,1 ; ma, wc = 0 */
0066022, /* DOB 1,MTA */
0067022, /* DOC 1,MTA */
0061122, /* DOAS 0,MTA ; start read */
0070422, /* DIA 2,MTA ; get status */
0151213, /* MOVR# 2,2,SNC ; skip if done */
0000776, /* JMP .-2 */
0000377, /* JMP 377 */
0000000, /* UNIT: */
0000010 /* REWIND: 10 */
};
0060222, /* NIOC 0,MTA ; clear disk */
0020417, /* LDA 0,UNIT ; unit */
0024417, /* LDA 1,REWIND ; cmd */
0107000, /* ADD 0,1 ; cmd + unit */
0065122, /* DOAS 1,MTA ; start rewind */
0070422, /* DIA 2,MTA ; get status */
0151213, /* MOVR# 2,2,SNC ; skip if done */
0000776, /* JMP .-2 */
0126400, /* SUB 1,1 ; ma, wc = 0 */
0066022, /* DOB 1,MTA */
0067022, /* DOC 1,MTA */
0061122, /* DOAS 0,MTA ; start read */
0070422, /* DIA 2,MTA ; get status */
0151213, /* MOVR# 2,2,SNC ; skip if done */
0000776, /* JMP .-2 */
0000377, /* JMP 377 */
0000000, /* UNIT: */
0000010 /* REWIND: 10 */
};
t_stat mta_boot (int32 unitno, DEVICE *dptr)
{

View File

@@ -1,6 +1,6 @@
/* nova_plt.c: NOVA plotter simulator
Copyright (c) 2000-2004, Robert M. Supnik
Copyright (c) 2000-2005, Robert M. Supnik
Written by Bruce Ray and used with his gracious permission.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -20,78 +20,85 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
plt plotter
plt plotter
25-Apr-03 RMS Revised for extended file support
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
25-Apr-03 RMS Revised for extended file support
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
*/
#include "nova_defs.h"
extern int32 int_req, dev_busy, dev_done, dev_disable;
int32 plt_stopioe = 0; /* stop on error */
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);
/* PLT data structures
plt_dev PLT device descriptor
plt_unit PLT unit descriptor
plt_reg PLT register list
plt_dev PLT device descriptor
plt_unit PLT unit descriptor
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 };
UDATA (&plt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
};
REG plt_reg[] = {
{ ORDATA (BUF, plt_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PLT) },
{ FLDATA (DONE, dev_done, INT_V_PLT) },
{ FLDATA (DISABLE, dev_disable, INT_V_PLT) },
{ FLDATA (INT, int_req, INT_V_PLT) },
{ DRDATA (POS, plt_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, plt_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, plt_stopioe, 0) },
{ NULL } };
{ ORDATA (BUF, plt_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PLT) },
{ FLDATA (DONE, dev_done, INT_V_PLT) },
{ FLDATA (DISABLE, dev_disable, INT_V_PLT) },
{ FLDATA (INT, int_req, INT_V_PLT) },
{ DRDATA (POS, plt_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, plt_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, plt_stopioe, 0) },
{ NULL }
};
DEVICE plt_dev = {
"PLT", &plt_unit, plt_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &plt_reset,
NULL, NULL, NULL,
&plt_dib, DEV_DISABLE };
"PLT", &plt_unit, plt_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &plt_reset,
NULL, NULL, NULL,
&plt_dib, DEV_DISABLE
};
/* plotter: IOT routine */
int32 plt (int32 pulse, int32 code, int32 AC)
{
if (code == ioDOA) plt_unit.buf = AC & 0377;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_PLT; /* set busy */
dev_done = dev_done & ~INT_PLT; /* clear done, int */
int_req = int_req & ~INT_PLT;
sim_activate (&plt_unit, plt_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_PLT; /* clear busy */
dev_done = dev_done & ~INT_PLT; /* clear done, int */
int_req = int_req & ~INT_PLT;
sim_cancel (&plt_unit); /* deactivate unit */
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_PLT; /* set busy */
dev_done = dev_done & ~INT_PLT; /* clear done, int */
int_req = int_req & ~INT_PLT;
sim_activate (&plt_unit, plt_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_PLT; /* clear busy */
dev_done = dev_done & ~INT_PLT; /* clear done, int */
int_req = int_req & ~INT_PLT;
sim_cancel (&plt_unit); /* deactivate unit */
break;
} /* end switch */
return 0;
}
@@ -99,15 +106,16 @@ return 0;
t_stat plt_svc (UNIT *uptr)
{
dev_busy = dev_busy & ~INT_PLT; /* clear busy */
dev_done = dev_done | INT_PLT; /* set done */
dev_busy = dev_busy & ~INT_PLT; /* clear busy */
dev_done = dev_done | INT_PLT; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
if ((plt_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (plt_stopioe, SCPE_UNATT);
if ((plt_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (plt_stopioe, SCPE_UNATT);
if (putc (plt_unit.buf, plt_unit.fileref) == EOF) {
perror ("PLT I/O error");
clearerr (plt_unit.fileref);
return SCPE_IOERR; }
perror ("PLT I/O error");
clearerr (plt_unit.fileref);
return SCPE_IOERR;
}
plt_unit.pos = plt_unit.pos + 1;
return SCPE_OK;
}
@@ -117,9 +125,9 @@ return SCPE_OK;
t_stat plt_reset (DEVICE *dptr)
{
plt_unit.buf = 0;
dev_busy = dev_busy & ~INT_PLT; /* clear busy */
dev_done = dev_done & ~INT_PLT; /* clear done, int */
dev_busy = dev_busy & ~INT_PLT; /* clear busy */
dev_done = dev_done & ~INT_PLT; /* clear done, int */
int_req = int_req & ~INT_PLT;
sim_cancel (&plt_unit); /* deactivate unit */
sim_cancel (&plt_unit); /* deactivate unit */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* nova_pt.c: NOVA paper tape read/punch simulator
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,24 +19,24 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
ptr paper tape reader
ptp paper tape punch
ptr paper tape reader
ptp paper tape punch
25-Apr-03 RMS Revised for extended file support
03-Oct-02 RMS Added DIBs
30-May-02 RMS Widened POS to 32b
29-Nov-01 RMS Added read only unit support
25-Apr-03 RMS Revised for extended file support
03-Oct-02 RMS Added DIBs
30-May-02 RMS Widened POS to 32b
29-Nov-01 RMS Added read only unit support
*/
#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_stopioe = 0, ptp_stopioe = 0; /* stop on error */
int32 ptr (int32 pulse, int32 code, int32 AC);
int32 ptp (int32 pulse, int32 code, int32 AC);
@@ -44,68 +44,74 @@ t_stat ptr_svc (UNIT *uptr);
t_stat ptp_svc (UNIT *uptr);
t_stat ptr_reset (DEVICE *dptr);
t_stat ptp_reset (DEVICE *dptr);
/* PTR data structures
ptr_dev PTR device descriptor
ptr_unit PTR unit descriptor
ptr_reg PTR register list
ptr_dev PTR device descriptor
ptr_unit PTR unit descriptor
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 };
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
SERIAL_IN_WAIT
};
REG ptr_reg[] = {
{ ORDATA (BUF, ptr_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PTR) },
{ FLDATA (DONE, dev_done, INT_V_PTR) },
{ FLDATA (DISABLE, dev_disable, INT_V_PTR) },
{ FLDATA (INT, int_req, INT_V_PTR) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
{ NULL } };
{ ORDATA (BUF, ptr_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PTR) },
{ FLDATA (DONE, dev_done, INT_V_PTR) },
{ FLDATA (DISABLE, dev_disable, INT_V_PTR) },
{ FLDATA (INT, int_req, INT_V_PTR) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
{ NULL }
};
DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset,
NULL, NULL, NULL,
&ptr_dib, 0 };
"PTR", &ptr_unit, ptr_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset,
NULL, NULL, NULL,
&ptr_dib, 0
};
/* PTP data structures
ptp_dev PTP device descriptor
ptp_unit PTP unit descriptor
ptp_reg PTP register list
ptp_dev PTP device descriptor
ptp_unit PTP unit descriptor
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 };
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
};
REG ptp_reg[] = {
{ ORDATA (BUF, ptp_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PTP) },
{ FLDATA (DONE, dev_done, INT_V_PTP) },
{ FLDATA (DISABLE, dev_disable, INT_V_PTP) },
{ FLDATA (INT, int_req, INT_V_PTP) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
{ NULL } };
{ ORDATA (BUF, ptp_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_PTP) },
{ FLDATA (DONE, dev_done, INT_V_PTP) },
{ FLDATA (DISABLE, dev_disable, INT_V_PTP) },
{ FLDATA (INT, int_req, INT_V_PTP) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
{ NULL }
};
DEVICE ptp_dev = {
"PTP", &ptp_unit, ptp_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset,
NULL, NULL, NULL,
&ptp_dib, 0 };
"PTP", &ptp_unit, ptp_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset,
NULL, NULL, NULL,
&ptp_dib, 0
};
/* Paper tape reader: IOT routine */
int32 ptr (int32 pulse, int32 code, int32 AC)
@@ -113,19 +119,23 @@ int32 ptr (int32 pulse, int32 code, int32 AC)
int32 iodata;
iodata = (code == ioDIA)? ptr_unit.buf & 0377: 0;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_PTR; /* set busy */
dev_done = dev_done & ~INT_PTR; /* clear done, int */
int_req = int_req & ~INT_PTR;
sim_activate (&ptr_unit, ptr_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_PTR; /* clear busy */
dev_done = dev_done & ~INT_PTR; /* clear done, int */
int_req = int_req & ~INT_PTR;
sim_cancel (&ptr_unit); /* deactivate unit */
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_PTR; /* set busy */
dev_done = dev_done & ~INT_PTR; /* clear done, int */
int_req = int_req & ~INT_PTR;
sim_activate (&ptr_unit, ptr_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_PTR; /* clear busy */
dev_done = dev_done & ~INT_PTR; /* clear done, int */
int_req = int_req & ~INT_PTR;
sim_cancel (&ptr_unit); /* deactivate unit */
break;
} /* end switch */
return iodata;
}
@@ -135,17 +145,19 @@ t_stat ptr_svc (UNIT *uptr)
{
int32 temp;
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptr_stopioe, SCPE_UNATT);
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */
if (feof (ptr_unit.fileref)) {
if (ptr_stopioe) printf ("PTR end of file\n");
else return SCPE_OK; }
else perror ("PTR I/O error");
clearerr (ptr_unit.fileref);
return SCPE_IOERR; }
dev_busy = dev_busy & ~INT_PTR; /* clear busy */
dev_done = dev_done | INT_PTR; /* set done */
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptr_stopioe, SCPE_UNATT);
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* end of file? */
if (feof (ptr_unit.fileref)) {
if (ptr_stopioe) printf ("PTR end of file\n");
else return SCPE_OK;
}
else perror ("PTR I/O error");
clearerr (ptr_unit.fileref);
return SCPE_IOERR;
}
dev_busy = dev_busy & ~INT_PTR; /* clear busy */
dev_done = dev_done | INT_PTR; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
ptr_unit.buf = temp & 0377;
ptr_unit.pos = ptr_unit.pos + 1;
@@ -157,31 +169,35 @@ return SCPE_OK;
t_stat ptr_reset (DEVICE *dptr)
{
ptr_unit.buf = 0;
dev_busy = dev_busy & ~INT_PTR; /* clear busy */
dev_done = dev_done & ~INT_PTR; /* clear done, int */
dev_busy = dev_busy & ~INT_PTR; /* clear busy */
dev_done = dev_done & ~INT_PTR; /* clear done, int */
int_req = int_req & ~INT_PTR;
sim_cancel (&ptr_unit); /* deactivate unit */
sim_cancel (&ptr_unit); /* deactivate unit */
return SCPE_OK;
}
/* Paper tape punch: IOT routine */
int32 ptp (int32 pulse, int32 code, int32 AC)
{
if (code == ioDOA) ptp_unit.buf = AC & 0377;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_PTP; /* set busy */
dev_done = dev_done & ~INT_PTP; /* clear done, int */
int_req = int_req & ~INT_PTP;
sim_activate (&ptp_unit, ptp_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_PTP; /* clear busy */
dev_done = dev_done & ~INT_PTP; /* clear done, int */
int_req = int_req & ~INT_PTP;
sim_cancel (&ptp_unit); /* deactivate unit */
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_PTP; /* set busy */
dev_done = dev_done & ~INT_PTP; /* clear done, int */
int_req = int_req & ~INT_PTP;
sim_activate (&ptp_unit, ptp_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_PTP; /* clear busy */
dev_done = dev_done & ~INT_PTP; /* clear done, int */
int_req = int_req & ~INT_PTP;
sim_cancel (&ptp_unit); /* deactivate unit */
break;
} /* end switch */
return 0;
}
@@ -189,15 +205,16 @@ return 0;
t_stat ptp_svc (UNIT *uptr)
{
dev_busy = dev_busy & ~INT_PTP; /* clear busy */
dev_done = dev_done | INT_PTP; /* set done */
dev_busy = dev_busy & ~INT_PTP; /* clear busy */
dev_done = dev_done | INT_PTP; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptp_stopioe, SCPE_UNATT);
if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptp_stopioe, SCPE_UNATT);
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) {
perror ("PTP I/O error");
clearerr (ptp_unit.fileref);
return SCPE_IOERR; }
perror ("PTP I/O error");
clearerr (ptp_unit.fileref);
return SCPE_IOERR;
}
ptp_unit.pos = ptp_unit.pos + 1;
return SCPE_OK;
}
@@ -207,9 +224,9 @@ return SCPE_OK;
t_stat ptp_reset (DEVICE *dptr)
{
ptp_unit.buf = 0;
dev_busy = dev_busy & ~INT_PTP; /* clear busy */
dev_done = dev_done & ~INT_PTP; /* clear done, int */
dev_busy = dev_busy & ~INT_PTP; /* clear busy */
dev_done = dev_done & ~INT_PTP; /* clear done, int */
int_req = int_req & ~INT_PTP;
sim_cancel (&ptp_unit); /* deactivate unit */
sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* nova_tt.c: NOVA console terminal simulator
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,28 +19,28 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
tti terminal input
tto terminal output
tti terminal input
tto terminal output
29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support
05-Jan-02 RMS Fixed calling sequence for setmod
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
07-Sep-01 RMS Moved function prototypes
31-May-01 RMS Added multiconsole support
29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support
05-Jan-02 RMS Fixed calling sequence for setmod
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
07-Sep-01 RMS Moved function prototypes
31-May-01 RMS Added multiconsole support
*/
#include "nova_defs.h"
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
#define UNIT_DASHER (1 << UNIT_V_DASHER)
#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);
@@ -50,13 +50,13 @@ t_stat tto_svc (UNIT *uptr);
t_stat tti_reset (DEVICE *dptr);
t_stat tto_reset (DEVICE *dptr);
t_stat ttx_setmod (UNIT *uptr, int32 val, char *cptr, void *desc);
/* TTI data structures
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
ttx_mod TTI/TTO modifiers list
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
ttx_mod TTI/TTO modifiers list
*/
DIB tti_dib = { DEV_TTI, INT_TTI, PI_TTI, &tti };
@@ -64,32 +64,35 @@ DIB tti_dib = { DEV_TTI, INT_TTI, PI_TTI, &tti };
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
REG tti_reg[] = {
{ ORDATA (BUF, tti_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTI) },
{ FLDATA (DONE, dev_done, INT_V_TTI) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTI) },
{ FLDATA (INT, int_req, INT_V_TTI) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tti_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTI) },
{ FLDATA (DONE, dev_done, INT_V_TTI) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTI) },
{ FLDATA (INT, int_req, INT_V_TTI) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL }
};
MTAB ttx_mod[] = {
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
{ 0 } };
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0 };
"TTI", &tti_unit, tti_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
*/
DIB tto_dib = { DEV_TTO, INT_TTO, PI_TTO, &tto };
@@ -97,22 +100,24 @@ DIB tto_dib = { DEV_TTO, INT_TTO, PI_TTO, &tto };
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
REG tto_reg[] = {
{ ORDATA (BUF, tto_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTO) },
{ FLDATA (DONE, dev_done, INT_V_TTO) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTO) },
{ FLDATA (INT, int_req, INT_V_TTO) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tto_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTO) },
{ FLDATA (DONE, dev_done, INT_V_TTO) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTO) },
{ FLDATA (INT, int_req, INT_V_TTO) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0 };
"TTO", &tto_unit, tto_reg, ttx_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0
};
/* Terminal input: IOT routine */
int32 tti (int32 pulse, int32 code, int32 AC)
@@ -120,17 +125,21 @@ int32 tti (int32 pulse, int32 code, int32 AC)
int32 iodata;
iodata = (code == ioDIA)? tti_unit.buf & 0377: 0;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTI; /* set busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTI; /* set busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
break;
} /* end switch */
return iodata;
}
@@ -140,13 +149,13 @@ t_stat tti_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
tti_unit.buf = temp & 0177;
if ((tti_unit.flags & UNIT_DASHER) && (tti_unit.buf == '\r'))
tti_unit.buf = '\n'; /* Dasher: cr -> nl */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done | INT_TTI; /* set done */
tti_unit.buf = '\n'; /* Dasher: cr -> nl */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done | INT_TTI; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
tti_unit.pos = tti_unit.pos + 1;
return SCPE_OK;
@@ -157,31 +166,35 @@ return SCPE_OK;
t_stat tti_reset (DEVICE *dptr)
{
tti_unit.buf = 0;
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
dev_done = dev_done & ~INT_TTI; /* clear done, int */
int_req = int_req & ~INT_TTI;
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK;
}
/* Terminal output: IOT routine */
int32 tto (int32 pulse, int32 code, int32 AC)
{
if (code == ioDOA) tto_unit.buf = AC & 0377;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTO; /* set busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_cancel (&tto_unit); /* deactivate unit */
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTO; /* set busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_cancel (&tto_unit); /* deactivate unit */
break;
} /* end switch */
return 0;
}
@@ -194,11 +207,12 @@ t_stat r;
c = tto_unit.buf & 0177;
if ((tto_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* try again */
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done | INT_TTO; /* set done */
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* try again */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
}
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done | INT_TTO; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
tto_unit.pos = tto_unit.pos + 1;
return SCPE_OK;
@@ -209,10 +223,10 @@ return SCPE_OK;
t_stat tto_reset (DEVICE *dptr)
{
tto_unit.buf = 0;
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
dev_busy = dev_busy & ~INT_TTO; /* clear busy */
dev_done = dev_done & ~INT_TTO; /* clear done, int */
int_req = int_req & ~INT_TTO;
sim_cancel (&tto_unit); /* deactivate unit */
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;
}

View File

@@ -20,38 +20,38 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
tti1 second terminal input
tto1 second terminal output
tti1 second terminal input
tto1 second terminal output
09-May-03 RMS Added network device flag
05-Jan-03 RMS Fixed calling sequence for setmod
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
30-Nov-01 RMS Added extended SET/SHOW support
17-Sep-01 RMS Changed to use terminal multiplexor library
07-Sep-01 RMS Moved function prototypes
31-May-01 RMS Added multiconsole support
26-Apr-01 RMS Added device enable/disable support
09-May-03 RMS Added network device flag
05-Jan-03 RMS Fixed calling sequence for setmod
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
30-Nov-01 RMS Added extended SET/SHOW support
17-Sep-01 RMS Changed to use terminal multiplexor library
07-Sep-01 RMS Moved function prototypes
31-May-01 RMS Added multiconsole support
26-Apr-01 RMS Added device enable/disable support
*/
#include "nova_defs.h"
#include "sim_sock.h"
#include "sim_tmxr.h"
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
#define UNIT_DASHER (1 << UNIT_V_DASHER)
#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;
extern int32 tmxr_poll; /* calibrated poll */
TMLN tt1_ldsc = { 0 }; /* line descriptors */
TMXR tt_desc = { 1, 0, 0, &tt1_ldsc }; /* mux descriptor */
extern int32 tmxr_poll; /* calibrated poll */
TMLN tt1_ldsc = { 0 }; /* line descriptors */
TMXR tt_desc = { 1, 0, 0, &tt1_ldsc }; /* mux descriptor */
DEVICE tti1_dev, tto1_dev;
int32 tti1 (int32 pulse, int32 code, int32 AC);
@@ -66,13 +66,13 @@ 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
tti1_unit TTI1 unit descriptor
tti1_reg TTI1 register list
ttx1_mod TTI1/TTO1 modifiers list
tti1_dev TTI1 device descriptor
tti1_unit TTI1 unit descriptor
tti1_reg TTI1 register list
ttx1_mod TTI1/TTO1 modifiers list
*/
DIB tti1_dib = { DEV_TTI1, INT_TTI1, PI_TTI1, &tti1 };
@@ -80,39 +80,42 @@ 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[] = {
{ ORDATA (BUF, tti1_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTI1) },
{ FLDATA (DONE, dev_done, INT_V_TTI1) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTI1) },
{ 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 },
{ NULL } };
{ ORDATA (BUF, tti1_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTI1) },
{ FLDATA (DONE, dev_done, INT_V_TTI1) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTI1) },
{ 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 },
{ NULL }
};
MTAB tti1_mod[] = {
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx1_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
{ UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &tti1_summ },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &tt_desc },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &tti1_show, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
NULL, &tti1_show, NULL },
{ 0 } };
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx1_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
{ UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &tti1_summ },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &tt_desc },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &tti1_show, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
NULL, &tti1_show, NULL },
{ 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,
&tti1_dib, DEV_NET | DEV_DISABLE };
"TTI1", &tti1_unit, tti1_reg, tti1_mod,
1, 10, 31, 1, 8, 8,
&tmxr_ex, &tmxr_dep, &tti1_reset,
NULL, &tti1_attach, &tti1_detach,
&tti1_dib, DEV_NET | DEV_DISABLE
};
/* TTO1 data structures
tto1_dev TTO1 device descriptor
tto1_unit TTO1 unit descriptor
tto1_reg TTO1 register list
tto1_dev TTO1 device descriptor
tto1_unit TTO1 unit descriptor
tto1_reg TTO1 register list
*/
DIB tto1_dib = { DEV_TTO1, INT_TTO1, PI_TTO1, &tto1 };
@@ -120,27 +123,30 @@ DIB tto1_dib = { DEV_TTO1, INT_TTO1, PI_TTO1, &tto1 };
UNIT tto1_unit = { UDATA (&tto1_svc, 0, 0), SERIAL_OUT_WAIT };
REG tto1_reg[] = {
{ ORDATA (BUF, tto1_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTO1) },
{ FLDATA (DONE, dev_done, INT_V_TTO1) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTO1) },
{ FLDATA (INT, int_req, INT_V_TTO1) },
{ DRDATA (POS, tt1_ldsc.txcnt, 32), PV_LEFT },
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tto1_unit.buf, 8) },
{ FLDATA (BUSY, dev_busy, INT_V_TTO1) },
{ FLDATA (DONE, dev_done, INT_V_TTO1) },
{ FLDATA (DISABLE, dev_disable, INT_V_TTO1) },
{ FLDATA (INT, int_req, INT_V_TTO1) },
{ DRDATA (POS, tt1_ldsc.txcnt, 32), PV_LEFT },
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tto1_mod[] = {
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx1_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
{ 0 } };
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx1_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
{ 0 }
};
DEVICE tto1_dev = {
"TTO1", &tto1_unit, tto1_reg, tto1_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto1_reset,
NULL, NULL, NULL,
&tto1_dib, DEV_DISABLE };
"TTO1", &tto1_unit, tto1_reg, tto1_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto1_reset,
NULL, NULL, NULL,
&tto1_dib, DEV_DISABLE
};
/* Terminal input: IOT routine */
int32 tti1 (int32 pulse, int32 code, int32 AC)
@@ -148,17 +154,21 @@ int32 tti1 (int32 pulse, int32 code, int32 AC)
int32 iodata;
iodata = (code == ioDIA)? tti1_unit.buf & 0377: 0;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTI1; /* set busy */
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
int_req = int_req & ~INT_TTI1;
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
int_req = int_req & ~INT_TTI1;
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTI1; /* set busy */
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
int_req = int_req & ~INT_TTI1;
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
int_req = int_req & ~INT_TTI1;
break;
} /* end switch */
return iodata;
}
@@ -168,23 +178,27 @@ t_stat tti1_svc (UNIT *uptr)
{
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 */
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); /* poll connect */
if (newln >= 0) { /* got one? */
sim_activate (&tti1_unit, tti1_unit.wait);
tt1_ldsc.rcve = 1; } /* rcv enabled */
sim_activate (uptr, tmxr_poll); } /* sched poll */
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 */
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); /* poll connect */
if (newln >= 0) { /* got one? */
sim_activate (&tti1_unit, tti1_unit.wait);
tt1_ldsc.rcve = 1; /* rcv enabled */
}
sim_activate (uptr, tmxr_poll); /* sched poll */
}
return SCPE_OK;
}
@@ -192,38 +206,43 @@ return SCPE_OK;
t_stat tti1_reset (DEVICE *dptr)
{
ttx1_enbdis (dptr->flags & DEV_DIS); /* sync devices */
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 */
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
int_req = int_req & ~INT_TTI1;
if (tt1_ldsc.conn) { /* if conn, */
sim_activate (&tti1_unit, tti1_unit.wait); /* activate, */
tt1_ldsc.rcve = 1; } /* enable */
else if (tti1_unit.flags & UNIT_ATT) /* if attached, */
sim_activate (&tti1_unit, tmxr_poll); /* activate */
else sim_cancel (&tti1_unit); /* else stop */
if (tt1_ldsc.conn) { /* if conn, */
sim_activate (&tti1_unit, tti1_unit.wait); /* activate, */
tt1_ldsc.rcve = 1; /* enable */
}
else if (tti1_unit.flags & UNIT_ATT) /* if attached, */
sim_activate (&tti1_unit, tmxr_poll); /* activate */
else sim_cancel (&tti1_unit); /* else stop */
return SCPE_OK;
}
/* Terminal output: IOT routine */
int32 tto1 (int32 pulse, int32 code, int32 AC)
{
if (code == ioDOA) tto1_unit.buf = AC & 0377;
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTO1; /* set busy */
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
int_req = int_req & ~INT_TTO1;
sim_activate (&tto1_unit, tto1_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
int_req = int_req & ~INT_TTO1;
sim_cancel (&tto1_unit); /* deactivate unit */
break; } /* end switch */
switch (pulse) { /* decode IR<8:9> */
case iopS: /* start */
dev_busy = dev_busy | INT_TTO1; /* set busy */
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
int_req = int_req & ~INT_TTO1;
sim_activate (&tto1_unit, tto1_unit.wait); /* activate unit */
break;
case iopC: /* clear */
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
int_req = int_req & ~INT_TTO1;
sim_cancel (&tto1_unit); /* deactivate unit */
break;
} /* end switch */
return 0;
}
@@ -233,18 +252,21 @@ t_stat tto1_svc (UNIT *uptr)
{
int32 c;
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
dev_done = dev_done | INT_TTO1; /* set done */
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
dev_done = dev_done | INT_TTO1; /* set done */
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
c = tto1_unit.buf & 0177;
if ((tto1_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
if (tt1_ldsc.conn) { /* connected? */
if (tt1_ldsc.xmte) { /* tx enabled? */
tmxr_putc_ln (&tt1_ldsc, c); /* output char */
tmxr_poll_tx (&tt_desc); } /* poll xmt */
else { tmxr_poll_tx (&tt_desc); /* poll xmt */
sim_activate (&tto1_unit, tmxr_poll); /* wait */
return SCPE_OK; } }
if (tt1_ldsc.conn) { /* connected? */
if (tt1_ldsc.xmte) { /* tx enabled? */
tmxr_putc_ln (&tt1_ldsc, c); /* output char */
tmxr_poll_tx (&tt_desc); /* poll xmt */
}
else {
tmxr_poll_tx (&tt_desc); /* poll xmt */
sim_activate (&tto1_unit, tmxr_poll); /* wait */
}
}
return SCPE_OK;
}
@@ -252,12 +274,12 @@ return SCPE_OK;
t_stat tto1_reset (DEVICE *dptr)
{
ttx1_enbdis (dptr->flags & DEV_DIS); /* sync devices */
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 */
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
int_req = int_req & ~INT_TTO1;
sim_cancel (&tto1_unit); /* deactivate unit */
sim_cancel (&tto1_unit); /* deactivate unit */
return SCPE_OK;
}
@@ -274,9 +296,9 @@ t_stat tti1_attach (UNIT *uptr, char *cptr)
{
t_stat r;
r = tmxr_attach (&tt_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error */
sim_activate (uptr, tmxr_poll); /* start poll */
r = tmxr_attach (&tt_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) return r; /* error */
sim_activate (uptr, tmxr_poll); /* start poll */
return SCPE_OK;
}
@@ -286,9 +308,9 @@ t_stat tti1_detach (UNIT *uptr)
{
t_stat r;
r = tmxr_detach (&tt_desc, uptr); /* detach */
tt1_ldsc.rcve = 0; /* disable rcv */
sim_cancel (uptr); /* stop poll */
r = tmxr_detach (&tt_desc, uptr); /* detach */
tt1_ldsc.rcve = 0; /* disable rcv */
sim_cancel (uptr); /* stop poll */
return r;
}
@@ -315,9 +337,12 @@ return SCPE_OK;
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; }
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;
}