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:
committed by
Mark Pizzolato
parent
ec60bbf329
commit
b7c1eae41f
@@ -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.
|
||||
|
||||
7861
NOVA/eclipse_cpu.c
7861
NOVA/eclipse_cpu.c
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
150
NOVA/nova_clk.c
150
NOVA/nova_clk.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
1374
NOVA/nova_cpu.c
1374
NOVA/nova_cpu.c
File diff suppressed because it is too large
Load Diff
397
NOVA/nova_defs.h
397
NOVA/nova_defs.h
@@ -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
|
||||
|
||||
1137
NOVA/nova_dkp.c
1137
NOVA/nova_dkp.c
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
|
||||
333
NOVA/nova_dsk.c
333
NOVA/nova_dsk.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
112
NOVA/nova_lp.c
112
NOVA/nova_lp.c
@@ -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;
|
||||
}
|
||||
|
||||
825
NOVA/nova_mta.c
825
NOVA/nova_mta.c
@@ -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)
|
||||
{
|
||||
|
||||
114
NOVA/nova_plt.c
114
NOVA/nova_plt.c
@@ -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;
|
||||
}
|
||||
|
||||
217
NOVA/nova_pt.c
217
NOVA/nova_pt.c
@@ -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;
|
||||
}
|
||||
|
||||
1730
NOVA/nova_qty.c
1730
NOVA/nova_qty.c
File diff suppressed because it is too large
Load Diff
1137
NOVA/nova_sys.c
1137
NOVA/nova_sys.c
File diff suppressed because it is too large
Load Diff
204
NOVA/nova_tt.c
204
NOVA/nova_tt.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
311
NOVA/nova_tt1.c
311
NOVA/nova_tt1.c
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user