mirror of
https://github.com/rcornwell/sims.git
synced 2026-04-05 05:13:22 +00:00
KA10: Added support for KS10 processor.
This commit is contained in:
268
PDP10/ks10_cty.c
Normal file
268
PDP10/ks10_cty.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/* ks10_cty.c: KS-10 front end (console terminal) simulator
|
||||
|
||||
Copyright (c) 2021, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
RICHARD CORNWELL 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 Richard Cornwell shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Richard Cornwell
|
||||
|
||||
*/
|
||||
|
||||
#include "kx10_defs.h"
|
||||
#include "sim_sock.h"
|
||||
#include "sim_tmxr.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#if KS
|
||||
#define UNIT_DUMMY (1 << UNIT_V_UF)
|
||||
|
||||
#define STATUS 031
|
||||
#define CTY_IN 032
|
||||
#define CTY_OUT 033
|
||||
#define KLINK_IN 034
|
||||
#define KLINK_OUT 035
|
||||
#define BOOT_ADDR 036
|
||||
#define BOOT_DRIVE 037
|
||||
#define MAG_FMT 040
|
||||
|
||||
#define KA_FAIL 0000000000001 /* Keep Alive failed to change */
|
||||
#define FORCE_RELOAD 0000000000002 /* Force reload */
|
||||
#define PWR_FAIL1 0000000000004 /* Power failure */
|
||||
#define BOOT_SW 0000000000010 /* Boot switch */
|
||||
#define KEEP_ALIVE 0000000077400 /* Keep alive */
|
||||
#define TRAPS_ENB 0000400000000 /* Traps enabled */
|
||||
#define ONE_MS 0001000000000 /* 1ms enabled */
|
||||
#define CACHE_ENB 0002000000000 /* Cache enable */
|
||||
#define DP_PAR_ENB 0004000000000 /* DP parity error enable */
|
||||
#define CRAM_PAR_ENB 0010000000000 /* CRAM parity error enable */
|
||||
#define PAR_ENB 0020000000000 /* Parity error detect enable */
|
||||
#define KLINK_ENB 0040000000000 /* Klink active */
|
||||
#define EX_KEEP_ALV 0100000000000 /* Examine Keep Alive */
|
||||
#define RELOAD 0200000000000 /* Reload */
|
||||
|
||||
#define CTY_CHAR 0000000000400 /* Character pending */
|
||||
#define KLINK_CHAR 0000000000400 /* Character pending */
|
||||
#define KLINK_ACT 0000000001000 /* KLINK ACTIVE */
|
||||
#define KLINK_HANG 0000000001400 /* KLINK HANGUP */
|
||||
|
||||
extern int32 tmxr_poll;
|
||||
t_stat ctyi_svc (UNIT *uptr);
|
||||
t_stat ctyo_svc (UNIT *uptr);
|
||||
t_stat ctyrtc_srv(UNIT * uptr);
|
||||
t_stat cty_reset (DEVICE *dptr);
|
||||
t_stat cty_stop_os (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat tty_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat cty_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
const char *cty_description (DEVICE *dptr);
|
||||
|
||||
static int32 rtc_tps = 1;
|
||||
|
||||
struct _buffer {
|
||||
int in_ptr; /* Insert pointer */
|
||||
int out_ptr; /* Remove pointer */
|
||||
char buff[32]; /* Buffer */
|
||||
} cty_in, cty_out;
|
||||
|
||||
#define full(q) ((((q)->in_ptr + 1) & 0x1f) == (q)->out_ptr)
|
||||
#define empty(q) ((q)->in_ptr == (q)->out_ptr)
|
||||
#define not_empty(q) ((q)->in_ptr != (q)->out_ptr)
|
||||
#define inco(q) (q)->out_ptr = ((q)->out_ptr + 1) & 0x1f
|
||||
#define inci(q) (q)->in_ptr = ((q)->in_ptr + 1) & 0x1f
|
||||
|
||||
MTAB cty_mod[] = {
|
||||
{ UNIT_DUMMY, 0, NULL, "STOP", &cty_stop_os },
|
||||
{ TT_MODE, TT_MODE_UC, "UC", "UC", &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_7P, "7p", "7P", &tty_set_mode },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
UNIT cty_unit[] = {
|
||||
{ UDATA (&ctyo_svc, TT_MODE_7B, 0), 100},
|
||||
{ UDATA (&ctyi_svc, TT_MODE_7B|UNIT_DIS, 0), 1000 },
|
||||
{ UDATA (&ctyrtc_srv, UNIT_IDLE|UNIT_DIS, 0), 1000 }
|
||||
};
|
||||
|
||||
REG cty_reg[] = {
|
||||
{SAVEDATA(IN, cty_in) },
|
||||
{SAVEDATA(OUT, cty_out) },
|
||||
{HRDATAD(WRU, sim_int_char, 8, "interrupt character") },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
|
||||
DEVICE cty_dev = {
|
||||
"CTY", cty_unit, cty_reg, cty_mod,
|
||||
3, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &cty_reset,
|
||||
NULL, NULL, NULL, NULL, DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &cty_help, NULL, NULL, &cty_description
|
||||
};
|
||||
|
||||
void
|
||||
cty_wakeup()
|
||||
{
|
||||
sim_debug(DEBUG_EXP, &cty_dev, "CTY wakeup\n");
|
||||
sim_activate(&cty_unit[0], cty_unit[0].wait);
|
||||
}
|
||||
|
||||
|
||||
/* Check for input from CTY and put on queue. */
|
||||
t_stat ctyi_svc (UNIT *uptr)
|
||||
{
|
||||
uint64 buffer;
|
||||
int32 ch;
|
||||
|
||||
sim_clock_coschedule (uptr, tmxr_poll);
|
||||
|
||||
/* If we have room see if any new lines */
|
||||
while (!full(&cty_in)) {
|
||||
ch = sim_poll_kbd ();
|
||||
if (ch & SCPE_KFLAG) {
|
||||
ch = 0177 & sim_tt_inpcvt(ch, TT_GET_MODE (uptr->flags));
|
||||
cty_in.buff[cty_in.in_ptr] =ch & 0377;
|
||||
inci(&cty_in);
|
||||
sim_debug(DEBUG_DETAIL, &cty_dev, "CTY char %o '%c'\n", ch,
|
||||
((ch > 040 && ch < 0177)? ch: '.'));
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
if (not_empty(&cty_in)) {
|
||||
if (Mem_read_word(CTY_IN, &buffer, 0))
|
||||
return SCPE_OK;
|
||||
if (buffer & CTY_CHAR)
|
||||
return SCPE_OK;
|
||||
sim_debug(DEBUG_DETAIL, &cty_dev, "CTY Read %012llo\n", buffer);
|
||||
ch = cty_in.buff[cty_in.out_ptr];
|
||||
if (ch != 0) {
|
||||
buffer = (uint64)(ch) | CTY_CHAR;
|
||||
if (Mem_write_word(CTY_IN, &buffer, 0))
|
||||
return SCPE_OK;
|
||||
inco(&cty_in);
|
||||
cty_interrupt();
|
||||
} else {
|
||||
inco(&cty_in);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Handle output of characters to CTY. Started whenever there is output pending */
|
||||
t_stat ctyo_svc (UNIT *uptr)
|
||||
{
|
||||
uint64 buffer;
|
||||
/* Check if any input pending? */
|
||||
if (Mem_read_word(CTY_OUT, &buffer, 0))
|
||||
return SCPE_OK;
|
||||
sim_debug(DEBUG_DETAIL, &cty_dev, "CTY Write %012llo\n", buffer);
|
||||
if (buffer & CTY_CHAR) {
|
||||
if (!full(&cty_out)) {
|
||||
cty_out.buff[cty_out.in_ptr] = (uint8)(buffer & 0377);
|
||||
buffer = 0;
|
||||
if (Mem_write_word(CTY_OUT, &buffer, 0) == 0) {
|
||||
inci(&cty_out);
|
||||
cty_interrupt();
|
||||
}
|
||||
} else {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush out any pending CTY output */
|
||||
while(not_empty(&cty_out)) {
|
||||
char ch = cty_out.buff[cty_out.out_ptr];
|
||||
if (ch != 0) {
|
||||
if (sim_putchar_s(ch) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
inco(&cty_out);
|
||||
sim_debug(DEBUG_DETAIL, &cty_dev, "CTY outch %o '%c'\n", ch,
|
||||
((ch > 040 && ch < 0177)? ch: '.'));
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Handle FE timer interrupts. And keepalive counts */
|
||||
t_stat
|
||||
ctyrtc_srv(UNIT * uptr)
|
||||
{
|
||||
|
||||
sim_activate_after(uptr, 1000000/rtc_tps);
|
||||
/* Check if clock requested */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
t_stat cty_reset (DEVICE *dptr)
|
||||
{
|
||||
cty_in.in_ptr = cty_in.out_ptr = 0;
|
||||
cty_out.in_ptr = cty_out.out_ptr = 0;
|
||||
sim_activate(&cty_unit[1], cty_unit[1].wait);
|
||||
sim_activate(&cty_unit[2], cty_unit[2].wait);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat tty_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
cty_unit[0].flags = (cty_unit[0].flags & ~TT_MODE) | val;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Stop operating system */
|
||||
|
||||
t_stat cty_stop_os (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
M[CTY_SWITCH] = 1; /* tell OS to stop */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
t_stat cty_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "To stop the cpu use the command:\n\n");
|
||||
fprintf (st, " sim> SET CTY STOP\n\n");
|
||||
fprintf (st, "This will write a 1 to location %03o, causing TOPS10 to stop\n\n", CTY_SWITCH);
|
||||
fprintf (st, "The additional terminals can be set to one of four modes: UC, 7P, 7B, or 8B.\n\n");
|
||||
fprintf (st, " mode input characters output characters\n\n");
|
||||
fprintf (st, " UC lower case converted lower case converted to upper case,\n");
|
||||
fprintf (st, " to upper case, high-order bit cleared,\n");
|
||||
fprintf (st, " high-order bit cleared non-printing characters suppressed\n");
|
||||
fprintf (st, " 7P high-order bit cleared high-order bit cleared,\n");
|
||||
fprintf (st, " non-printing characters suppressed\n");
|
||||
fprintf (st, " 7B high-order bit cleared high-order bit cleared\n");
|
||||
fprintf (st, " 8B no changes no changes\n\n");
|
||||
fprintf (st, "The default mode is 7P. In addition, each line can be configured to\n");
|
||||
fprintf (st, "behave as though it was attached to a dataset, or hardwired to a terminal:\n\n");
|
||||
fprint_reg_help (st, &cty_dev);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *cty_description (DEVICE *dptr)
|
||||
{
|
||||
return "Console TTY Line";
|
||||
}
|
||||
|
||||
#endif
|
||||
1103
PDP10/ks10_rp.c
Normal file
1103
PDP10/ks10_rp.c
Normal file
File diff suppressed because it is too large
Load Diff
975
PDP10/ks10_tu.c
Normal file
975
PDP10/ks10_tu.c
Normal file
@@ -0,0 +1,975 @@
|
||||
/* ks10_tu.c: DEC Massbus TM03/TU10 tape controller
|
||||
|
||||
Copyright (c) 2021, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PUTUOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
RICHARD CORNWELL 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.
|
||||
|
||||
*/
|
||||
|
||||
#include "kx10_defs.h"
|
||||
#include "sim_tape.h"
|
||||
|
||||
#ifndef NUM_DEVS_TU
|
||||
#define NUM_DEVS_TU 0
|
||||
#endif
|
||||
|
||||
#if (NUM_DEVS_TU > 0)
|
||||
|
||||
#define NUM_UNITS_TU 8
|
||||
#define TU_NUMFR (64*1024)
|
||||
|
||||
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
|
||||
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
|
||||
|
||||
/* Flags in the unit flags word */
|
||||
|
||||
#define TU_UNIT UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE
|
||||
|
||||
#define CMD u3
|
||||
/* u3 low */
|
||||
/* TUC - 772440 - control */
|
||||
|
||||
#define CS1_GO 1 /* go */
|
||||
#define CS1_V_FNC 1 /* function pos */
|
||||
#define CS1_M_FNC 037 /* function mask */
|
||||
#define CS1_FNC (CS1_M_FNC << CS1_V_FNC)
|
||||
#define FNC_NOP 000 /* no operation */
|
||||
#define FNC_UNLOAD 001 /* unload */
|
||||
#define FNC_REWIND 003 /* rewind */
|
||||
#define FNC_DCLR 004 /* drive clear */
|
||||
#define FNC_PRESET 010 /* read-in preset */
|
||||
#define FNC_ERASE 012 /* Erase */
|
||||
#define FNC_WTM 013 /* Write Tape Mark */
|
||||
#define FNC_SPACEF 014 /* Space record forward */
|
||||
#define FNC_SPACEB 015 /* Space record backward */
|
||||
#define FNC_XFER 024 /* >=? data xfr */
|
||||
#define FNC_WCHK 024 /* write check */
|
||||
#define FNC_WCHKREV 027 /* write check reverse */
|
||||
#define FNC_WRITE 030 /* write */
|
||||
#define FNC_READ 034 /* read */
|
||||
#define FNC_READREV 037 /* read reverse */
|
||||
#define CS1_IE 0000100 /* Enable interrupts */
|
||||
#define CS1_RDY 0000200 /* Drive ready */
|
||||
#define CS1_UBA 0001400 /* High order UBA bits */
|
||||
#define CS1_PSEL 0002000 /* */
|
||||
#define CS1_DVA 0004000 /* drive avail NI */
|
||||
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
||||
#define CS1_MCPE 0020000 /* */
|
||||
#define CS1_TRE 0040000 /* */
|
||||
#define CS1_SC 0100000 /* */
|
||||
|
||||
/* TUWC - 772442 - word count. */
|
||||
|
||||
/* TUBA - 772444 - bus address */
|
||||
|
||||
/* TUFC - 772446 - Frame count */
|
||||
|
||||
/* TUCS2 -772450 - Control Status 2 */
|
||||
#define CS2_V_UNIT 0 /* unit pos */
|
||||
#define CS2_M_UNIT 07 /* unit mask */
|
||||
#define CS2_UNIT (CS2_M_UNIT << CS2_V_UNIT)
|
||||
#define CS2_UAI 0000010 /* addr inhibit */
|
||||
#define CS2_PAT 0000020 /* parity test NI */
|
||||
#define CS2_CLR 0000040 /* controller clear */
|
||||
#define CS2_IR 0000100 /* input ready */
|
||||
#define CS2_OR 0000200 /* output ready */
|
||||
#define CS2_MDPE 0000400 /* Mbus par err NI set TRE*/
|
||||
#define CS2_MXF 0001000 /* missed xfer NI set TRE*/
|
||||
#define CS2_PGE 0002000 /* program err set TRE*/
|
||||
#define CS2_NEM 0004000 /* nx mem err set TRE*/
|
||||
#define CS2_NED 0010000 /* nx drive err set TRE */
|
||||
#define CS2_PE 0020000 /* parity err NI set TRE */
|
||||
#define CS2_WCE 0040000 /* write check err set TRE */
|
||||
#define CS2_DLT 0100000 /* data late NI set TRE */
|
||||
|
||||
#define STATUS u5
|
||||
/* u5 low */
|
||||
/* TUDS - 772452 - drive status */
|
||||
|
||||
#define DS_SLA 0000001 /* Drive has become ready */
|
||||
#define DS_BOT 0000002 /* Beginning of tape */
|
||||
#define DS_TM 0000004 /* Tape mark */
|
||||
#define DS_IDB 0000010 /* Identification burst */
|
||||
#define DS_SDWN 0000020 /* Tape stoped */
|
||||
#define DS_PES 0000040 /* Phase Encoding */
|
||||
#define DS_SSC 0000100 /* Status change */
|
||||
#define DS_DRY 0000200 /* drive ready */
|
||||
#define DS_DPR 0000400 /* drive present */
|
||||
#define DS_PGM 0001000 /* programable NI */
|
||||
#define DS_EOT 0002000 /* end of tape */
|
||||
#define DS_WRL 0004000 /* write locked */
|
||||
#define DS_MOL 0010000 /* medium online */
|
||||
#define DS_PIP 0020000 /* pos in progress */
|
||||
#define DS_ERR 0040000 /* error */
|
||||
#define DS_ATA 0100000 /* attention active */
|
||||
|
||||
/* u5 high */
|
||||
/* TUER1 - 772454 - error status 1 */
|
||||
|
||||
#define ER1_ILF 0000001 /* illegal func */
|
||||
#define ER1_ILR 0000002 /* illegal register */
|
||||
#define ER1_RMR 0000004 /* reg mod refused */
|
||||
#define ER1_CPAR 0000010 /* control parity err NI */
|
||||
#define ER1_FMT 0000020 /* format err */
|
||||
#define ER1_DPAR 0000040 /* data parity error */
|
||||
#define ER1_INC 0000100 /* Incorrectable data */
|
||||
#define ER1_PEF 0000200 /* format error */
|
||||
#define ER1_NSG 0000400 /* Nonstandard gap NI */
|
||||
#define ER1_FCE 0001000 /* Frame count error */
|
||||
#define ER1_ITM 0002000 /* Illegal tape mark */
|
||||
#define ER1_NEF 0004000 /* Non executable function */
|
||||
#define ER1_DTE 0010000 /* drive time err NI */
|
||||
#define ER1_OPI 0020000 /* op incomplete */
|
||||
#define ER1_UNS 0040000 /* drive unsafe */
|
||||
#define ER1_DCK 0100000 /* data check NI */
|
||||
|
||||
/* TUDB - 772462 - Data buffer */
|
||||
|
||||
/* TUMR - 772464 - maintenace register */
|
||||
|
||||
/* TUAS - 772456 - attention summary */
|
||||
|
||||
#define AS_U0 0000001 /* unit 0 flag */
|
||||
|
||||
/* TUDT - 772466 - drive type */
|
||||
|
||||
/* TULA - 772460 - Check Character */
|
||||
|
||||
/* TUSN - 772470 - serial number */
|
||||
|
||||
/* TUTC - 772472 - Tape control register */
|
||||
#define TC_SS 0000007 /* Slave select mask */
|
||||
#define TC_EVPAR 0000010 /* Even parity */
|
||||
#define TC_FMTSEL 0000360 /* Format select */
|
||||
#define TC_10CORE 000 /* PDP 10 Core */
|
||||
/* 4 8 bit chars + 1 4 bit char */
|
||||
#define TC_15CORE 001 /* PDP 15 core */
|
||||
/* 3 6 bit chars per word */
|
||||
#define TC_10NORM 003 /* PDP 10 Compatible */
|
||||
/* 4 8 bit chars per word */
|
||||
#define TC_11NORM 014 /* PDP 11 Normal */
|
||||
/* 2 8 bit chars per word */
|
||||
#define TC_11CORE 015 /* PDP 11 Core */
|
||||
/* 4 4 bit chars per word */
|
||||
#define TC_15NORM 016 /* PDP 15 Normal */
|
||||
/* 2 8 bit chars per word */
|
||||
#define TC_DENS 0003400 /* Density (ignored) */
|
||||
#define TC_800 0001400 /* 800 BPI */
|
||||
#define TC_1600 0002000 /* 1600 BPI */
|
||||
#define TC_EAODTE 0010000 /* Enable abort */
|
||||
#define TC_SAC 0020000 /* Slave address change */
|
||||
#define TC_FCS 0040000 /* Frame count status */
|
||||
#define TC_ACCL 0100000 /* Acceleration */
|
||||
|
||||
|
||||
/* TUER3 - 15 - error status 3 - more unsafe conditions - unimplemented */
|
||||
|
||||
#define CPOS u4
|
||||
#define DATAPTR u6
|
||||
|
||||
uint8 tu_buf[TU_NUMFR];
|
||||
uint64 tu_cbuf;
|
||||
uint16 tu_frame;
|
||||
uint16 tu_tcr;
|
||||
uint16 tu_wc;
|
||||
uint16 tu_db;
|
||||
uint16 tu_cs2;
|
||||
t_addr tu_ba;
|
||||
uint8 tu_attn;
|
||||
uint8 tu_ie;
|
||||
uint16 tu_mr;
|
||||
static uint64 tu_boot_buffer;
|
||||
|
||||
int tu_write(t_addr addr, uint16 data, int32 access);
|
||||
int tu_read(t_addr addr, uint16 *data, int32 access);
|
||||
void tu_rst(DEVICE *dptr);
|
||||
t_stat tu_srv(UNIT *);
|
||||
t_stat tu_boot(int32, DEVICE *);
|
||||
void tu_ini(UNIT *, t_bool);
|
||||
t_stat tu_reset(DEVICE *);
|
||||
t_stat tu_attach(UNIT *, CONST char *);
|
||||
t_stat tu_detach(UNIT *);
|
||||
t_stat tu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *tu_description (DEVICE *dptr);
|
||||
|
||||
|
||||
UNIT tua_unit[] = {
|
||||
/* Controller 1 */
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
};
|
||||
|
||||
DIB tua_dib = {0772440, 037, 0224, 6, 3, &tu_read, &tu_write, 0};
|
||||
|
||||
MTAB tu_mod[] = {
|
||||
{MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL},
|
||||
{MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL},
|
||||
{MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL},
|
||||
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LENGTH", "LENGTH",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL},
|
||||
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DENSITY", "DENSITY",
|
||||
&sim_tape_set_dens, &sim_tape_show_dens, NULL},
|
||||
{MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "addr", "addr", &uba_set_addr, uba_show_addr,
|
||||
NULL, "Sets address of RH11" },
|
||||
{MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "vect", "vect", &uba_set_vect, uba_show_vect,
|
||||
NULL, "Sets vect of RH11" },
|
||||
{MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "br", "br", &uba_set_br, uba_show_br,
|
||||
NULL, "Sets br of RH11" },
|
||||
{MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "ctl", "ctl", &uba_set_ctl, uba_show_ctl,
|
||||
NULL, "Sets br of RH11" },
|
||||
{0}
|
||||
};
|
||||
|
||||
REG tua_reg[] = {
|
||||
{ORDATA(WC, tu_wc, 16)},
|
||||
{ORDATA(BA, tu_ba, 18)},
|
||||
{ORDATA(ATTN, tu_attn, 8)},
|
||||
{ORDATA(UNIT, tu_cs2, 8)},
|
||||
{ORDATA(IE, tu_ie, 8), REG_HRO},
|
||||
{ORDATA(FRAME, tu_frame, 16)},
|
||||
{ORDATA(TCR, tu_tcr, 16)},
|
||||
{BRDATA(BUFF, tu_buf, 16, 8, TU_NUMFR), REG_HRO},
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE tua_dev = {
|
||||
"TU", tua_unit, tua_reg, tu_mod,
|
||||
NUM_UNITS_TU, 8, 18, 1, 8, 36,
|
||||
NULL, NULL, &tu_reset, &tu_boot, &tu_attach, &tu_detach,
|
||||
&tua_dib, DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug,
|
||||
NULL, NULL, &tu_help, NULL, NULL, &tu_description
|
||||
};
|
||||
|
||||
int
|
||||
tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
int i;
|
||||
int unit = tu_tcr & 07;
|
||||
UNIT *uptr = &tua_unit[unit];
|
||||
|
||||
if (access == BYTE && addr & 1)
|
||||
data <<= 8;
|
||||
|
||||
if (uptr->CMD & CS1_GO) {
|
||||
uptr->STATUS |= (ER1_RMR << 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(addr & 036) {
|
||||
case 000: /* TUCS - control */
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %d Status=%06o\n", unit, uptr->STATUS);
|
||||
if (access == BYTE && addr & 1)
|
||||
return 0;
|
||||
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %d Status=%06o\n", unit, uptr->CMD);
|
||||
tu_ba = ((data << 7) & 0600000) | (tu_ba & 0177777);
|
||||
tu_ie = data & CS1_IE;
|
||||
uptr->CMD = data & 076;
|
||||
|
||||
if ((data & 01) != 0 && (uptr->flags & UNIT_ATT) != 0) {
|
||||
switch (GET_FNC(data)) {
|
||||
case FNC_NOP:
|
||||
break;
|
||||
|
||||
case FNC_PRESET: /* read-in preset */
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READREV: /* read w/ headers */
|
||||
tu_frame = 0;
|
||||
tu_tcr |= TC_FCS;
|
||||
/* Fall through */
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
case FNC_SPACEF: /* Space forward */
|
||||
case FNC_SPACEB: /* Space backward */
|
||||
if ((tu_tcr & TC_FCS) == 0) {
|
||||
uptr->STATUS |= ER1_NEF << 16;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case FNC_ERASE: /* Erase gap */
|
||||
case FNC_WTM: /* Write tape mark */
|
||||
case FNC_WCHK: /* write check */
|
||||
case FNC_REWIND: /* rewind */
|
||||
case FNC_UNLOAD: /* unload */
|
||||
case FNC_WCHKREV: /* write w/ headers */
|
||||
uptr->CMD |= CS1_GO;
|
||||
uptr->STATUS |= DS_PIP;
|
||||
tu_attn = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (tua_unit[i].STATUS & DS_ATA)
|
||||
tu_attn = 1;
|
||||
}
|
||||
CLR_BUF(uptr);
|
||||
uptr->DATAPTR = 0;
|
||||
sim_activate(uptr, 100);
|
||||
break;
|
||||
|
||||
case FNC_DCLR: /* drive clear */
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
uptr->STATUS = 0;
|
||||
tu_ie = 0;
|
||||
tu_attn = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (tua_unit[i].STATUS & DS_ATA)
|
||||
tu_attn = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
uptr->STATUS |= (ER1_ILF << 16) | DS_ATA;
|
||||
tu_attn = 1;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o AStatus=%06o\n", unit, uptr->CMD);
|
||||
}
|
||||
break;
|
||||
case 002: /* TUWC - 172442 - word count */
|
||||
if (access == BYTE) {
|
||||
if (addr & 1)
|
||||
data = data | (tu_wc & 0377);
|
||||
else
|
||||
data = (tu_wc & 0177600) | data;
|
||||
}
|
||||
tu_wc = data;
|
||||
break;
|
||||
case 004: /* TUBA - 172444 - base address */
|
||||
if (access == BYTE) {
|
||||
if (addr & 1)
|
||||
data = data | (tu_ba & 0377);
|
||||
else
|
||||
data = (tu_ba & 0177600) | data;
|
||||
}
|
||||
tu_ba = (tu_ba & 0600000) | (data & 0177776);
|
||||
break;
|
||||
|
||||
case 006: /* 772446 frame count */
|
||||
tu_frame = data;
|
||||
tu_tcr |= TC_FCS;
|
||||
break;
|
||||
|
||||
case 010: /* 772450 CS2 */
|
||||
if (access == BYTE) {
|
||||
if (addr & 1)
|
||||
data = data | tu_cs2;
|
||||
}
|
||||
if (data & 040) {
|
||||
tu_reset(&tua_dev);
|
||||
}
|
||||
tu_cs2 = data & (CS2_PAT|CS2_UAI|CS2_UNIT);
|
||||
break;
|
||||
|
||||
|
||||
case 012: /* 772452 status */
|
||||
break;
|
||||
|
||||
case 014: /* 772454 error register 1 */
|
||||
uptr->STATUS &= 0177777;
|
||||
uptr->STATUS |= (uint32)data << 16;
|
||||
break;
|
||||
case 016: /* 772456 atten summary */
|
||||
tu_attn = 0;
|
||||
if (data & 1) {
|
||||
for (i = 0; i < 8; i++)
|
||||
tua_unit[i].STATUS &= ~DS_ATA;
|
||||
}
|
||||
break;
|
||||
|
||||
case 020: /* 772460 TCK maintenance */
|
||||
break;
|
||||
case 022: /* 772462 Data buffer */
|
||||
tu_db = data;
|
||||
tu_cs2 |= CS2_OR;
|
||||
break;
|
||||
case 024: /* 772464 Maintenance register */
|
||||
tu_mr = data;
|
||||
break;
|
||||
case 026: /* 772466 drive type */
|
||||
break;
|
||||
case 032: /* 772472 tape control register */
|
||||
tu_tcr = data;
|
||||
break;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o write %02o %06o\n", tu_tcr & 7,
|
||||
addr & 036, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tu_read(t_addr addr, uint16 *data, int32 access)
|
||||
{
|
||||
UNIT *uptr = &tua_unit[tu_tcr & 07];
|
||||
int tu_drive = tu_tcr & 07;
|
||||
uint16 temp = 0;
|
||||
int i;
|
||||
|
||||
|
||||
switch(addr & 036) {
|
||||
case 000: /* 772440 control */
|
||||
temp = uptr->CMD & 076;
|
||||
temp |= CS1_DVA;
|
||||
temp |= (uint16)tu_ie;
|
||||
temp |= (tu_ba & 0600000) << 7;
|
||||
if (uptr->CMD & CS1_GO)
|
||||
temp |= CS1_GO;
|
||||
else if ((uptr->STATUS & DS_PIP) == 0)
|
||||
temp |= CS1_RDY;
|
||||
if ((tu_cs2 & 07) != 0 || (uptr->STATUS & (ER1_RMR << 16)) != 0)
|
||||
temp |= CS1_TRE;
|
||||
if (tu_attn || temp & CS1_TRE)
|
||||
temp |= CS1_SC;
|
||||
break;
|
||||
case 002: /* 772442 - word count */
|
||||
temp = tu_wc;
|
||||
break;
|
||||
case 004: /* 772444 - base addresss */
|
||||
temp = (uint16)(tu_ba & 0177776);
|
||||
break;
|
||||
case 006: /* 772446 - frame count */
|
||||
temp = tu_frame;
|
||||
break;
|
||||
case 010: /* 772450 - CS2 */
|
||||
temp = tu_cs2;
|
||||
if ((tu_cs2 & 07) != 0)
|
||||
temp |= CS2_NED;
|
||||
break;
|
||||
case 012: /* 772452 - status */
|
||||
temp = uptr->STATUS & 0177777;
|
||||
if (((uptr->STATUS >> 16) & 0177777) != 0)
|
||||
temp |= DS_ERR;
|
||||
if ((uptr->flags & UNIT_ATT) != 0) {
|
||||
temp |= DS_MOL;
|
||||
if (uptr->flags & MTUF_WLK)
|
||||
temp |= DS_WRL;
|
||||
if ((uptr->CMD & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0)
|
||||
temp |= DS_DRY;
|
||||
if (sim_tape_bot(uptr))
|
||||
temp |= DS_BOT;
|
||||
if (sim_tape_eot(uptr))
|
||||
temp |= DS_EOT;
|
||||
}
|
||||
break;
|
||||
case 014: /* 772454 - error register 1 */
|
||||
temp = (uptr->STATUS >> 16) & 0177777;
|
||||
break;
|
||||
case 016: /* 772456 - atten summary */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (tua_unit[i].STATUS & DS_ATA)
|
||||
temp |= 1;
|
||||
}
|
||||
break;
|
||||
case 022: /* 772462 Data buffer */
|
||||
temp = tu_db;
|
||||
tu_cs2 &= ~CS2_OR;
|
||||
break;
|
||||
case 020: /* 772460 - character check */
|
||||
break;
|
||||
case 024: /* 772464 - maintenance */
|
||||
temp = tu_mr;
|
||||
break;
|
||||
case 026: /* 772466 - drive type */
|
||||
if ((uptr->flags & UNIT_DIS) == 0)
|
||||
temp = 042054;
|
||||
break;
|
||||
case 030: /* 772470 - serial no */
|
||||
temp = 020 + (tu_drive + 1);
|
||||
break;
|
||||
case 032: /* 772472 - tape control register */
|
||||
temp = tu_tcr;
|
||||
break;
|
||||
default:
|
||||
uptr->STATUS |= (ER1_ILR << 16);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
tu_attn = 1;
|
||||
}
|
||||
*data = temp;
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o read %02o %06o\n", tu_tcr & 7,
|
||||
addr & 036, *data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Map simH errors into machine errors */
|
||||
void tu_error(UNIT * uptr, t_stat r)
|
||||
{
|
||||
DEVICE *dptr = uptr->dptr;
|
||||
|
||||
switch (r) {
|
||||
case MTSE_OK: /* no error */
|
||||
break;
|
||||
|
||||
case MTSE_TMK: /* tape mark */
|
||||
uptr->STATUS |= DS_TM;
|
||||
break;
|
||||
|
||||
case MTSE_WRP: /* write protected */
|
||||
uptr->STATUS |= (ER1_NEF << 16) | DS_ATA;
|
||||
break;
|
||||
|
||||
case MTSE_UNATT: /* unattached */
|
||||
case MTSE_BOT: /* beginning of tape */
|
||||
case MTSE_EOM: /* end of medium */
|
||||
break;
|
||||
|
||||
case MTSE_IOERR: /* IO error */
|
||||
case MTSE_FMT: /* invalid format */
|
||||
uptr->STATUS |= (ER1_PEF << 16) | DS_ATA;
|
||||
break;
|
||||
|
||||
case MTSE_RECE: /* error in record */
|
||||
uptr->STATUS |= (ER1_DPAR << 16) | DS_ATA;
|
||||
break;
|
||||
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
uptr->STATUS |= (ER1_FCE << 16) | DS_ATA;
|
||||
break;
|
||||
|
||||
}
|
||||
if (uptr->STATUS & DS_ATA)
|
||||
tu_attn = 1;
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
sim_debug(DEBUG_EXP, dptr, "Setting status %d\n", r);
|
||||
if (tu_ie)
|
||||
uba_set_irq(&tua_dib);
|
||||
}
|
||||
|
||||
/* Handle processing of tape requests. */
|
||||
t_stat tu_srv(UNIT * uptr)
|
||||
{
|
||||
int unit;
|
||||
DEVICE *dptr;
|
||||
t_stat r;
|
||||
t_mtrlnt reclen;
|
||||
uint8 ch;
|
||||
int cc;
|
||||
int cc_max;
|
||||
|
||||
/* Find dptr, and df10 */
|
||||
dptr = uptr->dptr;
|
||||
unit = uptr - dptr->units;
|
||||
cc_max = (4 + ((tu_tcr & TC_FMTSEL) == 0));
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
tu_error(uptr, MTSE_UNATT); /* attached? */
|
||||
return SCPE_OK;
|
||||
}
|
||||
switch (GET_FNC(uptr->CMD)) {
|
||||
case FNC_NOP:
|
||||
case FNC_DCLR:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o nop\n", dptr->name, unit);
|
||||
tu_error(uptr, MTSE_OK); /* Nop */
|
||||
tu_attn = 1;
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_REWIND:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o rewind\n", dptr->name, unit);
|
||||
if (uptr->CMD & CS1_GO) {
|
||||
sim_activate(uptr,40000);
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
} else {
|
||||
uptr->STATUS |= DS_SSC|DS_ATA;
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
tu_attn = 1;
|
||||
if (tu_ie)
|
||||
uba_set_irq(&tua_dib);
|
||||
(void)sim_tape_rewind(uptr);
|
||||
}
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_UNLOAD:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o unload\n", dptr->name, unit);
|
||||
uptr->CMD &= ~(CS1_GO);
|
||||
uptr->STATUS &= ~(DS_PIP);
|
||||
uptr->STATUS |= DS_SSC|DS_ATA;
|
||||
tu_error(uptr, sim_tape_detach(uptr));
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_WCHKREV:
|
||||
case FNC_READREV:
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
if ((r = sim_tape_rdrecr(uptr, &tu_buf[0], &reclen,
|
||||
TU_NUMFR)) != MTSE_OK) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
|
||||
if (r == MTSE_BOT)
|
||||
uptr->STATUS |= ER1_NEF << 16;
|
||||
tu_error(uptr, r);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d\n", dptr->name, unit, reclen);
|
||||
uptr->hwmark = reclen;
|
||||
uptr->DATAPTR = uptr->hwmark-1;
|
||||
uptr->CPOS = cc_max;
|
||||
tu_cbuf = 0;
|
||||
sim_activate(uptr, 120);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (uptr->DATAPTR >= 0) {
|
||||
tu_frame++;
|
||||
cc = (8 * (3 - uptr->CPOS)) + 4;
|
||||
ch = tu_buf[uptr->DATAPTR];
|
||||
if (cc < 0)
|
||||
tu_cbuf |= (uint64)(ch & 0x0f);
|
||||
else
|
||||
tu_cbuf |= (uint64)(ch & 0xff) << cc;
|
||||
uptr->DATAPTR--;
|
||||
uptr->CPOS--;
|
||||
if (uptr->CPOS == 0) {
|
||||
uptr->CPOS = cc_max;
|
||||
if (GET_FNC(uptr->CMD) == FNC_READREV &&
|
||||
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf) == 0) {
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o readrev %012llo\n",
|
||||
dptr->name, unit, tu_cbuf);
|
||||
tu_cbuf = 0;
|
||||
if ((tu_cs2 & CS2_UAI) == 0)
|
||||
tu_ba -= 4;
|
||||
tu_wc = (tu_wc + 2) & 0177777;
|
||||
if (tu_wc == 0) {
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (uptr->CPOS != cc_max)
|
||||
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf);
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case FNC_WCHK:
|
||||
case FNC_READ:
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
if ((r = sim_tape_rdrecf(uptr, &tu_buf[0], &reclen,
|
||||
TU_NUMFR)) != MTSE_OK) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error %d\n", dptr->name, unit, r);
|
||||
if (r == MTSE_TMK)
|
||||
uptr->STATUS |= ER1_FCE << 16;
|
||||
tu_error(uptr, r);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read %d %d\n", dptr->name, unit, reclen, uptr->pos);
|
||||
uptr->hwmark = reclen;
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->CPOS = 0;
|
||||
tu_cbuf = 0;
|
||||
sim_activate(uptr, 120);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((uint32)uptr->DATAPTR < uptr->hwmark) {
|
||||
tu_frame++;
|
||||
cc = (8 * (3 - uptr->CPOS)) + 4;
|
||||
ch = tu_buf[uptr->DATAPTR];
|
||||
if (cc < 0)
|
||||
tu_cbuf |= (uint64)(ch & 0x0f);
|
||||
else
|
||||
tu_cbuf |= (uint64)(ch & 0xff) << cc;
|
||||
uptr->DATAPTR++;
|
||||
uptr->CPOS++;
|
||||
if (uptr->CPOS == cc_max) {
|
||||
uptr->CPOS = 0;
|
||||
if (GET_FNC(uptr->CMD) == FNC_READ &&
|
||||
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf) == 0) {
|
||||
if ((uint32)uptr->DATAPTR == uptr->hwmark)
|
||||
goto rd_end;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo %d\n",
|
||||
dptr->name, unit, tu_cbuf, uptr->DATAPTR);
|
||||
tu_cbuf = 0;
|
||||
tu_cbuf = 0;
|
||||
if ((tu_cs2 & CS2_UAI) == 0)
|
||||
tu_ba += 4;
|
||||
tu_wc = (tu_wc + 2) & 0177777;
|
||||
if (tu_wc == 0)
|
||||
goto rd_end;
|
||||
}
|
||||
} else {
|
||||
if (uptr->CPOS != 0) {
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o readf %012llo\n",
|
||||
dptr->name, unit, tu_cbuf);
|
||||
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf);
|
||||
}
|
||||
rd_end:
|
||||
if (tu_frame != 0)
|
||||
uptr->STATUS |= ER1_FCE << 16;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case FNC_WRITE:
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
if (tu_frame == 0) {
|
||||
uptr->STATUS |= ER1_NEF << 16;
|
||||
uptr->CMD |= DS_ATA;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_EXP, dptr, "%s%o Init write\n", dptr->name, unit);
|
||||
uptr->hwmark = 0;
|
||||
uptr->CPOS = 0;
|
||||
uptr->DATAPTR = 0;
|
||||
tu_cbuf = 0;
|
||||
}
|
||||
if (tu_frame != 0 && uptr->CPOS == 0) {
|
||||
if (uba_read_npr(tu_ba, tua_dib.uba_ctl, &tu_cbuf) == 0) {
|
||||
uptr->CPOS = 010;
|
||||
goto wr_end;
|
||||
} else {
|
||||
if ((tu_cs2 & CS2_UAI) == 0)
|
||||
tu_ba += 4;
|
||||
tu_wc = (tu_wc + 2) & 0177777;
|
||||
}
|
||||
}
|
||||
|
||||
if (uptr->CPOS == 0)
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o write %012llo\n",
|
||||
dptr->name, unit, tu_cbuf);
|
||||
/* Write next char out */
|
||||
cc = (8 * (3 - (uptr->CPOS & 07))) + 4;
|
||||
if (cc < 0)
|
||||
ch = tu_cbuf & 0x0f;
|
||||
else
|
||||
ch = (tu_cbuf >> cc) & 0xff;
|
||||
tu_buf[uptr->DATAPTR] = ch;
|
||||
uptr->DATAPTR++;
|
||||
uptr->hwmark = uptr->DATAPTR;
|
||||
uptr->CPOS = (uptr->CPOS & 010) | ((uptr->CPOS & 07) + 1);
|
||||
if ((uptr->CPOS & 7) == cc_max) {
|
||||
uptr->CPOS &= 010;
|
||||
}
|
||||
tu_frame = 0177777 & (tu_frame + 1);
|
||||
if (tu_wc == 0)
|
||||
uptr->CPOS = 010;
|
||||
else if (tu_frame == 0) {
|
||||
uptr->CPOS = 010;
|
||||
tu_tcr &= ~(TC_FCS);
|
||||
}
|
||||
wr_end:
|
||||
if (uptr->CPOS & 010) {
|
||||
/* Write out the block */
|
||||
reclen = uptr->hwmark;
|
||||
r = sim_tape_wrrecf(uptr, &tu_buf[0], reclen);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o Write %d %d\n",
|
||||
dptr->name, unit, reclen, uptr->CPOS);
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->hwmark = 0;
|
||||
tu_error(uptr, r); /* Record errors */
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case FNC_WTM:
|
||||
uptr->CMD |= DS_ATA;
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
} else {
|
||||
tu_error(uptr, sim_tape_wrtmk(uptr));
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o WTM\n", dptr->name, unit);
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_ERASE:
|
||||
uptr->STATUS |= DS_ATA;
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
} else {
|
||||
tu_error(uptr, sim_tape_wrgap(uptr, 35));
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o ERG\n", dptr->name, unit);
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_SPACEF:
|
||||
case FNC_SPACEB:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o space %o\n", dptr->name, unit, GET_FNC(uptr->CMD));
|
||||
/* Always skip at least one record */
|
||||
if (GET_FNC(uptr->CMD) == FNC_SPACEF)
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
else
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
switch (r) {
|
||||
case MTSE_OK: /* no error */
|
||||
tu_frame = 0177777 & (tu_frame + 1);
|
||||
break;
|
||||
|
||||
case MTSE_BOT: /* beginning of tape */
|
||||
uptr->STATUS |= ER1_NEF << 16;
|
||||
/* Fall Through */
|
||||
|
||||
case MTSE_TMK: /* tape mark */
|
||||
case MTSE_EOM: /* end of medium */
|
||||
if (tu_frame != 0)
|
||||
uptr->STATUS |= ER1_FCE << 16;
|
||||
else
|
||||
tu_tcr &= ~(TC_FCS);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
/* Stop motion if we recieve any of these */
|
||||
tu_error(uptr, r);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (tu_frame == 0) {
|
||||
uptr->STATUS |= DS_ATA;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
tu_tcr &= ~(TC_FCS);
|
||||
sim_activate(uptr, reclen * 100);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
t_stat
|
||||
tu_reset(DEVICE * dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
tu_attn = 0;
|
||||
tu_ba = tu_frame = tu_tcr = 0;
|
||||
tu_wc = 0177777;
|
||||
tu_cs2 = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
tua_unit[i].STATUS = 0;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void tu_read_word(UNIT *uptr) {
|
||||
int i, cc, ch;
|
||||
|
||||
tu_cbuf = 0;
|
||||
for(i = 0; i <= 4; i++) {
|
||||
cc = (8 * (3 - i)) + 4;
|
||||
ch = tu_buf[uptr->DATAPTR];
|
||||
if (cc < 0)
|
||||
tu_cbuf |= (uint64)(ch & 0x0f);
|
||||
else
|
||||
tu_cbuf |= (uint64)(ch & 0xff) << cc;
|
||||
uptr->DATAPTR++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat
|
||||
tu_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
t_mtrlnt reclen;
|
||||
t_stat r;
|
||||
uint32 addr;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
|
||||
tu_tcr = unit_num;
|
||||
r = sim_tape_rewind(uptr);
|
||||
if (r != MTSE_OK)
|
||||
return r;
|
||||
/* Skip first file, which is micro code */
|
||||
while (r == MTSE_OK)
|
||||
r = sim_tape_rdrecf(uptr, &tu_buf[0], &reclen, TU_NUMFR);
|
||||
|
||||
if (r != MTSE_TMK)
|
||||
return r;
|
||||
/* Next read in the boot block */
|
||||
r = sim_tape_rdrecf(uptr, &tu_buf[0], &reclen, TU_NUMFR);
|
||||
if (r != MTSE_OK)
|
||||
return r;
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->hwmark = reclen;
|
||||
|
||||
addr = 01000;
|
||||
while ((uint32)uptr->DATAPTR < uptr->hwmark) {
|
||||
tu_read_word(uptr);
|
||||
M[addr] = tu_cbuf;
|
||||
addr ++;
|
||||
}
|
||||
M[036] = tua_dib.uba_addr | (tua_dib.uba_ctl << 18);
|
||||
M[037] = unit_num;
|
||||
M[040] = tu_tcr;
|
||||
PC = 01000;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
t_stat
|
||||
tu_attach(UNIT * uptr, CONST char *file)
|
||||
{ t_stat r;
|
||||
|
||||
uptr->CMD = 0;
|
||||
uptr->STATUS = 0;
|
||||
r = sim_tape_attach_ex(uptr, file, 0, 0);
|
||||
if (r == SCPE_OK && (sim_switches & SIM_SW_REST) == 0) {
|
||||
uptr->STATUS = DS_ATA|DS_SSC;
|
||||
tu_attn = 1;
|
||||
if (tu_ie)
|
||||
uba_set_irq(&tua_dib);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
t_stat
|
||||
tu_detach(UNIT * uptr)
|
||||
{
|
||||
uptr->STATUS = DS_ATA|DS_SSC;
|
||||
tu_attn = 1;
|
||||
if (tu_ie)
|
||||
uba_set_irq(&tua_dib);
|
||||
return sim_tape_detach(uptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
t_stat tu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "TU Tape Drives with TM03 formatter. (TU)\n\n");
|
||||
fprintf (st, "The TU controller implements the Massbus tape formatter the TM03. TU\n");
|
||||
fprintf (st, "options include the ability to set units write enabled or write locked\n\n");
|
||||
fprint_set_help (st, dptr);
|
||||
fprint_show_help (st, dptr);
|
||||
fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n");
|
||||
fprintf (st, "The TU device supports the BOOT command.\n");
|
||||
sim_tape_attach_help (st, dptr, uptr, flag, cptr);
|
||||
fprint_reg_help (st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *tu_description (DEVICE *dptr)
|
||||
{
|
||||
return "TU04/05/06/07 Massbus disk controller";
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
452
PDP10/ks10_uba.c
Normal file
452
PDP10/ks10_uba.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/* ks10_uba.c: KS10 Unibus interface
|
||||
|
||||
Copyright (c) 2021, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
RICHARD CORNWELL 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.
|
||||
|
||||
*/
|
||||
|
||||
#include "kx10_defs.h"
|
||||
|
||||
/* UBA Map as stored */
|
||||
#define PAGE_MASK 000003777000 /* Page mask bits, bits 25-36 on load */
|
||||
#define MAP_RPV 000400000000 /* Ram parity valid bit */
|
||||
#define MAP_VALID 001000000000 /* Page valid */
|
||||
#define MAP_FME 002000000000 /* Fast Mode enable */
|
||||
#define MAP_EN16 004000000000 /* Disable upper 2 bits UBA */
|
||||
#define MAP_RPW 010000000000 /* For Read Pause Write */
|
||||
#define MAP_RAMP 020000000000 /* Parity error in RAM */
|
||||
|
||||
/* UBA Stats register */
|
||||
#define UBST_PIL 000000000007 /* Low level PIA */
|
||||
#define UBST_PIH 000000000070 /* High level PIA */
|
||||
#define UBST_INIT 000000000100 /* Initialize UBA */
|
||||
#define UBST_DXFR 000000000200 /* Disable transfer on uncorrectable */
|
||||
#define UBST_PWRL 000000001000 /* Power low */
|
||||
#define UBST_INTL 000000002000 /* Interrupt on Br5 or Br4 */
|
||||
#define UBST_INTH 000000004000 /* INterrupt on Br7 or Br6 */
|
||||
#define UBST_NED 000000040000 /* Non-existant device */
|
||||
#define UBST_PAR 000000100000 /* Parity error */
|
||||
#define UBST_BAD 000000200000 /* Bad mem transfer */
|
||||
#define UBST_TIM 000000400000 /* UBA Timout */
|
||||
|
||||
uint32 uba_map[2][64];
|
||||
uint32 uba_status[2];
|
||||
int uba_device[16] = { -1, 0, -1, 1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1 };
|
||||
|
||||
int
|
||||
uba_read(t_addr addr, int ctl, uint64 *data, int access)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
int i;
|
||||
int ubm = uba_device[ctl];
|
||||
|
||||
if (ubm == -1) {
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check if in UBA map */
|
||||
if ((addr & 0777600) == 0763000) {
|
||||
if ((addr & 0100) == 0) {
|
||||
*data = (uint64)uba_map[ubm][addr & 077];
|
||||
return 0;
|
||||
} else if ((addr & 077) == 0) {
|
||||
*data = (uint64)uba_status[ubm];
|
||||
return 0;
|
||||
} else if ((addr & 077) == 1) {
|
||||
return 0;
|
||||
}
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Look for device */
|
||||
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
if (ctl == dibp->uba_ctl && dibp->uba_addr == (addr & (~dibp->uba_mask))) {
|
||||
uint16 buf;
|
||||
int r = dibp->rd_io(addr, &buf, access);
|
||||
*data = (uint64)buf;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
uba_write(t_addr addr, int ctl, uint64 data, int access)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
int i;
|
||||
int ubm = uba_device[ctl];
|
||||
|
||||
if (ubm == -1) {
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Check if in UBA map */
|
||||
if ((addr & 0777400) == 0763000) {
|
||||
if ((addr & 0100) == 0) {
|
||||
uint32 map = (uint32)(data & 03777) << 9;
|
||||
map |= (uint32)(data & 0740000) << 13;
|
||||
uba_map[ubm][addr & 077] = map;
|
||||
//fprintf(stderr, "Wr MAP %02o %012llo %06o\n\r", addr & 077, data, map);
|
||||
return 0;
|
||||
} else if ((addr & 077) == 0) {
|
||||
uba_status[ubm] &= (uint32)(074000 ^ data) | 0746000;
|
||||
uba_status[ubm] |= (uint32)(0277 & data);
|
||||
if (data & 0100) {
|
||||
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
if (ctl == dibp->uba_ctl && dptr->reset != NULL)
|
||||
(void)(dptr->reset)(dptr);
|
||||
if (ctl == dibp->uba_ctl)
|
||||
dibp->uba_irq_pend = 0;
|
||||
}
|
||||
clr_interrupt(ctl);
|
||||
}
|
||||
return 0;
|
||||
} else if ((addr & 077) == 1) {
|
||||
return 0;
|
||||
}
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Look for device */
|
||||
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
if (ctl == dibp->uba_ctl && dibp->uba_addr == (addr & (~dibp->uba_mask))) {
|
||||
uint16 buf = (uint16)(data & 0177777);
|
||||
return dibp->wr_io(addr, buf, access);
|
||||
}
|
||||
}
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
uba_read_npr(t_addr addr, uint16 ctl, uint64 *data)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
uint32 map = uba_map[ubm][(077) & (addr >> 11)];
|
||||
if ((addr & 0400000) != 0)
|
||||
return 0;
|
||||
if ((map & MAP_VALID) == 0)
|
||||
return 0;
|
||||
map |= (addr >> 2) & 0777;
|
||||
addr = (map & (PAGE_MASK|0777));
|
||||
*data = M[addr];
|
||||
if (map & MAP_EN16)
|
||||
*data &= 0177777177777;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
uba_write_npr(t_addr addr, uint16 ctl, uint64 data)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
t_addr oaddr = addr;
|
||||
uint32 map = uba_map[ubm][(077) & (addr >> 11)];
|
||||
if ((addr & 0400000) != 0)
|
||||
return 0;
|
||||
if ((map & MAP_VALID) == 0)
|
||||
return 0;
|
||||
map |= (addr >> 2) & 0777;
|
||||
addr = (map & (PAGE_MASK|0777));
|
||||
if (map & MAP_EN16)
|
||||
data &= 0177777177777;
|
||||
//fprintf(stderr, "Wr NPR %08o %08o %012llo\n\r", oaddr, addr, data);
|
||||
M[addr] = data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
uba_read_npr_byte(t_addr addr, uint16 ctl, uint16 *data)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
}
|
||||
|
||||
int
|
||||
uba_write_npr_byte(t_addr addr, uint16 ctl, uint16 data)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
}
|
||||
|
||||
int
|
||||
uba_read_npr_word(t_addr addr, uint16 ctl, uint16 *data)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
}
|
||||
|
||||
int
|
||||
uba_write_npr_word(t_addr addr, uint16 ctl, uint16 data)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
}
|
||||
|
||||
void
|
||||
uba_set_irq(DIB *dibp)
|
||||
{
|
||||
int ubm = uba_device[dibp->uba_ctl];
|
||||
int pi;
|
||||
|
||||
if (ubm < 0)
|
||||
return;
|
||||
if (dibp->uba_br > 5) {
|
||||
pi = uba_status[ubm] >> 3;
|
||||
uba_status[ubm] |= UBST_INTH;
|
||||
} else {
|
||||
pi = uba_status[ubm];
|
||||
uba_status[ubm] |= UBST_INTL;
|
||||
}
|
||||
dibp->uba_irq_pend |= 0200 >> pi;
|
||||
set_interrupt(dibp->uba_ctl, pi);
|
||||
}
|
||||
|
||||
t_addr
|
||||
uba_get_vect(t_addr addr, int lvl)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *idev = NULL;
|
||||
uint64 buffer;
|
||||
int i;
|
||||
int ctl = 17;
|
||||
int msk[16] = {0};
|
||||
int pi;
|
||||
|
||||
/* Look for device */
|
||||
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
if ((dibp->uba_irq_pend & lvl) != 0) {
|
||||
if (dibp->uba_ctl < ctl)
|
||||
ctl = dibp->uba_ctl;
|
||||
idev = dibp;
|
||||
continue;
|
||||
}
|
||||
msk[dibp->uba_ctl] |= dibp->uba_irq_pend;
|
||||
}
|
||||
if (idev != NULL) {
|
||||
if (idev->uba_br > 5) {
|
||||
pi = uba_status[idev->uba_ctl] >> 3;
|
||||
uba_status[idev->uba_ctl] &= ~UBST_INTH;
|
||||
if (msk[idev->uba_ctl] & (0200 >> pi))
|
||||
uba_status[idev->uba_ctl] |= UBST_INTH;
|
||||
} else {
|
||||
pi = uba_status[idev->uba_ctl];
|
||||
uba_status[idev->uba_ctl] &= ~UBST_INTL;
|
||||
if (msk[idev->uba_ctl] & (0200 >> pi))
|
||||
uba_status[idev->uba_ctl] |= UBST_INTL;
|
||||
}
|
||||
idev->uba_irq_pend &= ~(0200 >> pi);
|
||||
if (msk[idev->uba_ctl] & (0200 >> pi))
|
||||
set_interrupt(idev->uba_ctl, pi);
|
||||
else
|
||||
clr_interrupt(idev->uba_ctl);
|
||||
if (Mem_read_word(0100 | idev->uba_ctl, &buffer, 1))
|
||||
return addr;
|
||||
addr = (buffer & RMASK) + (idev->uba_vect >> 2);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_set_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
t_value newaddr;
|
||||
t_stat r;
|
||||
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
newaddr = get_uint (cptr, 18, 0777777, &r);
|
||||
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
dibp->uba_addr = newaddr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_show_addr (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "addr=%07o", dibp->uba_addr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_set_br(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
t_value br;
|
||||
t_stat r;
|
||||
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
br = get_uint (cptr, 3, 07, &r);
|
||||
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
|
||||
if (br < 4 || br > 7)
|
||||
return SCPE_ARG;
|
||||
dibp->uba_br = br;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_show_br (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "br=%o", dibp->uba_br);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_set_vect(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
t_value vect;
|
||||
t_stat r;
|
||||
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
vect = get_uint (cptr, 8, 0377, &r);
|
||||
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
|
||||
dibp->uba_vect = vect;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_show_vect (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "vect=%03o", dibp->uba_vect);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_set_ctl(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
t_value ctl;
|
||||
t_stat r;
|
||||
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
ctl = get_uint (cptr, 4, 017, &r);
|
||||
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
|
||||
if (ctl != 1 || ctl != 3)
|
||||
return SCPE_ARG;
|
||||
dibp->uba_ctl = ctl;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_show_ctl (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "uba%o", dibp->uba_ctl);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
2501
PDP10/kx10_cpu.c
2501
PDP10/kx10_cpu.c
File diff suppressed because it is too large
Load Diff
@@ -50,11 +50,15 @@
|
||||
#define KL 0
|
||||
#endif
|
||||
|
||||
#ifndef KS
|
||||
#define KS 0
|
||||
#endif
|
||||
|
||||
#if KL
|
||||
#define EPT440 0 /* Force KL10 to use as 440 section address */
|
||||
#endif
|
||||
|
||||
#if (PDP6 + KA + KI + KL) != 1
|
||||
#if (PDP6 + KA + KI + KL + KS) != 1
|
||||
#error "Please define only one type of CPU"
|
||||
#endif
|
||||
|
||||
@@ -82,6 +86,11 @@
|
||||
#define KL_ITS KL
|
||||
#endif
|
||||
|
||||
/* Support for ITS on KS */
|
||||
#ifndef KS_ITS
|
||||
#define KS_ITS KS
|
||||
#endif
|
||||
|
||||
#ifndef PDP6_DEV /* Include PDP6 devices */
|
||||
#define PDP6_DEV PDP6|WAITS
|
||||
#endif
|
||||
@@ -196,6 +205,27 @@ extern DEBTAB crd_debug[];
|
||||
#define FPRBIT2 00000000000100000000000LL
|
||||
#define FPRBIT1 00000000000200000000000LL
|
||||
|
||||
/* IRQ Flags in APR */
|
||||
#if KL
|
||||
#define SWP_DONE 0000020 /* Cache sweep done */
|
||||
#define PWR_FAIL 0000040 /* Power failure */
|
||||
#define ADDR_PAR 0000100 /* Address Parity error */
|
||||
#define CACHE_DIR 0000200 /* Cache Parity error */
|
||||
#define MB_PAR 0000400 /* Memory parity error */
|
||||
#define INOUT_FAIL 0001000 /* Fault during IRQ */
|
||||
#define NXM_MEM 0002000 /* Non-existent memory */
|
||||
#define SBUS_ERR 0004000 /* SBus Error */
|
||||
#endif
|
||||
#if KS
|
||||
#define CON_IRQ 0000020 /* Interrupt from Console */
|
||||
#define INT_DONE 0000040 /* Interval timer complete */
|
||||
#define COR_MEM 0000100 /* Corrected memory error */
|
||||
#define MB_ERR 0000200 /* Uncorrectable memory error */
|
||||
#define NXM_MEM 0000400 /* No memory */
|
||||
#define PWR_FAIL 0001000 /* Power Failure */
|
||||
#define FLAG_24 0004000 /* Spare */
|
||||
#endif
|
||||
|
||||
#define CM(x) (FMASK ^ (x))
|
||||
#define CCM(x) ((CMASK ^ (x)) & CMASK)
|
||||
|
||||
@@ -231,12 +261,16 @@ extern DEBTAB crd_debug[];
|
||||
#define NODIV 000001 /* 000040 */
|
||||
#define FLTUND 000002 /* 000100 */
|
||||
#endif
|
||||
#if KI|KL
|
||||
#if KI|KL|KS
|
||||
#define TRP1 000004 /* 000200 */
|
||||
#define TRP2 000010 /* 000400 */
|
||||
#define ADRFLT 000020 /* 001000 */
|
||||
#if KI | KL
|
||||
#define PUBLIC 000040 /* 002000 */
|
||||
#else
|
||||
#define PUBLIC 000000 /* 000000 */
|
||||
#endif
|
||||
#else
|
||||
#define TRP1 000000
|
||||
#define TRP2 000000
|
||||
#define ADRFLT 000000
|
||||
@@ -284,9 +318,13 @@ extern DEBTAB crd_debug[];
|
||||
#if PDP6
|
||||
#define MAXMEMSIZE 256 * 1024
|
||||
#else
|
||||
#if KS
|
||||
#define MAXMEMSIZE 512 * 1024
|
||||
#else
|
||||
#define MAXMEMSIZE 1024 * 1024
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#define MEMSIZE (cpu_unit[0].capac)
|
||||
|
||||
#define ICWA 0000000000776
|
||||
@@ -323,6 +361,10 @@ extern DEBTAB crd_debug[];
|
||||
#define DEF_SERIAL 1025 /* Default DEC test machine */
|
||||
#endif
|
||||
|
||||
#if KS
|
||||
#define DEF_SERIAL 4097 /* Default DEC test machine */
|
||||
#endif
|
||||
|
||||
#if BBN
|
||||
#define BBN_PAGE 0000017777777LL
|
||||
#define BBN_TRPPG 0000017000000LL
|
||||
@@ -339,7 +381,7 @@ extern DEBTAB crd_debug[];
|
||||
#define BBN_MERGE 0161740000000LL
|
||||
#endif
|
||||
|
||||
#if KL
|
||||
#if KL|KS
|
||||
/* KL10 TLB paging bits */
|
||||
#define KL_PAG_A 0400000 /* Access */
|
||||
#define KL_PAG_P 0200000 /* Public */
|
||||
@@ -367,7 +409,11 @@ extern DEBTAB crd_debug[];
|
||||
#define UNIT_KL10B (1 << UNIT_V_PAGE)
|
||||
#define UNIT_TWOSEG (0)
|
||||
#else
|
||||
#if KA
|
||||
#define UNIT_TWOSEG (1 << UNIT_V_PAGE)
|
||||
#else
|
||||
#define UNIT_TWOSEG (0)
|
||||
#endif
|
||||
#endif
|
||||
#define UNIT_ITSPAGE (2 << UNIT_V_PAGE)
|
||||
#define UNIT_BBNPAGE (4 << UNIT_V_PAGE)
|
||||
@@ -471,6 +517,45 @@ extern DEVICE mtc_dev;
|
||||
extern DEVICE dsk_dev;
|
||||
extern DEVICE dcs_dev;
|
||||
|
||||
#if KS
|
||||
/* Device context block */
|
||||
struct pdp_dib {
|
||||
uint32 uba_addr; /* device address, includes adaptor */
|
||||
uint32 uba_mask; /* Compare mask */
|
||||
uint16 uba_vect; /* Floating IRQ vector */
|
||||
uint16 uba_br; /* Unibus IRQ level */
|
||||
uint16 uba_ctl; /* Unibus controller number */
|
||||
t_stat (*rd_io)(t_addr addr, uint16 *data, int32 access);
|
||||
t_stat (*wr_io)(t_addr addr, uint16 data, int32 access);
|
||||
uint8 uba_irq_pend; /* Device has pending */
|
||||
};
|
||||
typedef struct pdp_dib DIB;
|
||||
|
||||
void cty_wakeup();
|
||||
void cty_interrupt();
|
||||
|
||||
#define WORD 0
|
||||
#define BYTE 1
|
||||
int uba_read(t_addr addr, int ctl, uint64 *data, int access);
|
||||
int uba_write(t_addr addr, int ctl, uint64 data, int access);
|
||||
int uba_read_npr(t_addr addr, uint16 ctl, uint64 *data);
|
||||
int uba_write_npr(t_addr addr, uint16 ctl, uint64 data);
|
||||
int uba_read_npr_byte(t_addr addr, uint16 ctl, uint16 *data);
|
||||
int uba_write_npr_byte(t_addr addr, uint16 ctl, uint16 data);
|
||||
int uba_read_npr_word(t_addr addr, uint16 ctl, uint16 *data);
|
||||
int uba_write_npr_word(t_addr addr, uint16 ctl, uint16 data);
|
||||
void uba_set_irq(DIB *dibp);
|
||||
t_addr uba_get_vect(t_addr addr, int lvl);
|
||||
|
||||
t_stat uba_set_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat uba_show_addr (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat uba_set_br(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat uba_show_br (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat uba_set_vect(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat uba_show_vect (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat uba_set_ctl(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat uba_show_ctl (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
#else
|
||||
extern t_stat (*dev_tab[128])(uint32 dev, t_uint64 *data);
|
||||
|
||||
#define VEC_DEVMAX 8 /* max device vec */
|
||||
@@ -573,15 +658,13 @@ extern void ka10_lights_init (void);
|
||||
extern void ka10_lights_main (t_uint64);
|
||||
extern void ka10_lights_set_aux (int);
|
||||
extern void ka10_lights_clear_aux (int);
|
||||
|
||||
#endif
|
||||
|
||||
/* I/O system parameters */
|
||||
#if !(PDP6 | KS)
|
||||
#define NUM_DEVS_LP 1
|
||||
#if KL
|
||||
#define NUM_DEVS_PT 0
|
||||
#define NUM_DEVS_CR 0
|
||||
#define NUM_DEVS_CP 0
|
||||
#else
|
||||
#endif
|
||||
#if !(KL | KS)
|
||||
#define NUM_DEVS_PT 1
|
||||
#define NUM_DEVS_CR 1
|
||||
#define NUM_DEVS_CP 1
|
||||
@@ -597,34 +680,40 @@ extern void ka10_lights_clear_aux (int);
|
||||
#define NUM_DEVS_DCS 1
|
||||
#define NUM_DEVS_SLAVE PDP6
|
||||
#endif
|
||||
#if !PDP6
|
||||
#if !(PDP6 | KS)
|
||||
#define NUM_DEVS_DC 1
|
||||
#define NUM_DEVS_MT 1
|
||||
#endif
|
||||
#if KL
|
||||
#define NUM_DEVS_RC 0
|
||||
#define NUM_DEVS_DT 0
|
||||
#define NUM_DEVS_DK 0
|
||||
#define NUM_DEVS_DP 0
|
||||
#define NUM_DEVS_LP20 1
|
||||
#define NUM_DEVS_TTY 1
|
||||
#define NUM_LINES_TTY 64
|
||||
#define NUM_DEVS_NIA 1
|
||||
#else
|
||||
#elif KS
|
||||
#define NUM_DEVS_LP20 0
|
||||
#define NUM_DEVS_DZ 0
|
||||
#define NUM_LINES_DZ 8 * NUM_DEVS_DZ
|
||||
#endif
|
||||
#if KA | KI
|
||||
#define NUM_DEVS_RC 1
|
||||
#define NUM_DEVS_DT 1
|
||||
#define NUM_DEVS_DK 1
|
||||
#define NUM_DEVS_DP 2
|
||||
#define NUM_DEVS_LP20 0
|
||||
#define NUM_DEVS_TTY 0
|
||||
#define NUM_DEVS_NIA 0
|
||||
#endif
|
||||
#if KS
|
||||
#define NUM_DEVS_RP 1
|
||||
#elif KA | KI | KL
|
||||
#define NUM_DEVS_RP 4
|
||||
#define NUM_DEVS_RS 1
|
||||
#endif
|
||||
#if !(PDP6)
|
||||
#define NUM_DEVS_TU 1
|
||||
#endif
|
||||
#if KA
|
||||
#define NUM_DEVS_PMP WAITS
|
||||
#define NUM_DEVS_DKB (WAITS * USE_DISPLAY)
|
||||
#define NUM_DEVS_III (WAITS * USE_DISPLAY)
|
||||
#define NUM_DEVS_PD ITS | KL_ITS
|
||||
#define NUM_DEVS_PD ITS
|
||||
#define NUM_DEVS_PCLK WAITS
|
||||
#define NUM_DEVS_IMX ITS
|
||||
#define NUM_DEVS_STK ITS
|
||||
@@ -632,11 +721,16 @@ extern void ka10_lights_clear_aux (int);
|
||||
#define NUM_DEVS_MTY ITS
|
||||
#define NUM_DEVS_TEN11 ITS
|
||||
#define NUM_DEVS_AUXCPU ITS
|
||||
#define NUM_DEVS_IMP 1
|
||||
#define NUM_DEVS_CH10 ITS | KL_ITS
|
||||
#define NUM_DEVS_IMP ITS
|
||||
#define NUM_DEVS_CH10 ITS
|
||||
#define NUM_DEVS_DPK ITS
|
||||
#define NUM_DEVS_AI ITS
|
||||
#endif
|
||||
#if KL_ITS
|
||||
#define NUM_DEVS_PD KL_ITS
|
||||
#define NUM_DEVS_IMP KL_ITS
|
||||
#define NUM_DEVS_CH10 KL_ITS
|
||||
#endif
|
||||
#if MAGIC_SWITCH && !KA && !ITS
|
||||
#error "Magic switch only valid on KA10 with ITS mods"
|
||||
#endif
|
||||
@@ -645,7 +739,9 @@ extern void ka10_lights_clear_aux (int);
|
||||
|
||||
|
||||
extern t_bool sim_idle_enab;
|
||||
#if !KS
|
||||
extern struct rh_dev rh[];
|
||||
#endif
|
||||
extern t_uint64 M[MAXMEMSIZE];
|
||||
extern t_uint64 FM[];
|
||||
extern uint32 PC;
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
||||
#if KS
|
||||
char sim_name[] = "KS-10";
|
||||
#endif
|
||||
#if KL
|
||||
char sim_name[] = "KL-10";
|
||||
#endif
|
||||
@@ -62,7 +65,7 @@ int32 sim_emax = 1;
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
#if PDP6 | KA | KI
|
||||
#if PDP6 | KA | KI | KS
|
||||
&cty_dev,
|
||||
#endif
|
||||
#if KL
|
||||
@@ -902,7 +905,7 @@ static const char *opcode[] = {
|
||||
"SETSTS", "STATO", "STATUS", "GETSTS", "INBUF", "OUTBUF", "INPUT", "OUTPUT",
|
||||
"CLOSE", "RELEAS", "MTAPE", "UGETF", "USETI", "USETO", "LOOKUP", "ENTER",
|
||||
|
||||
#if KL
|
||||
#if KL | KS
|
||||
"UJEN", "GFAD", "GFSB", "JSYS", "ADJSP", "GFMP", "GFDV ",
|
||||
"DFAD", "DFSB", "DFMP", "DFDV", "DADD", "DSUB", "DMUL", "DDIV",
|
||||
#else
|
||||
@@ -961,6 +964,19 @@ static const char *opcode[] = {
|
||||
"TRO", "TLO", "TROE", "TLOE", "TROA", "TLOA", "TRON", "TLON",
|
||||
"TDO", "TSO", "TDOE", "TSOE", "TDOA", "TSOA", "TDON", "TSON",
|
||||
|
||||
#if KS
|
||||
"APRID", "CLRSCH", "RDUBR", "CLRPT",
|
||||
"WRUBR", "WREBR", "RDEBR",
|
||||
"RDSPB", "RDCSB", "RDPUR", "RDCSTM",
|
||||
"RDTIME", "RDINT", "RDHSB", "SPM",
|
||||
"WRSPB", "WRCSB", "WRPUR", "WRCSTM",
|
||||
"WRINT", "WRTIME", "WRHSB", "LPMR",
|
||||
"UMOVE", "UMOVEM",
|
||||
"TIOE", "TION", "RDIO", "WRIO",
|
||||
"BSIO", "BCIO",
|
||||
"TIOEB", "TIONB", "RDIOB", "WRIOB",
|
||||
"BSIOB", "BCIOB",
|
||||
#endif
|
||||
|
||||
"BLKI", "DATAI", "BLKO", "DATAO", /* classic I/O */
|
||||
"CONO", "CONI", "CONSZ", "CONSO",
|
||||
@@ -1095,9 +1111,21 @@ static const t_int64 opc_val[] = {
|
||||
0670000000000+I_AC, 0671000000000+I_AC, 0672000000000+I_AC, 0673000000000+I_AC,
|
||||
0674000000000+I_AC, 0675000000000+I_AC, 0676000000000+I_AC, 0677000000000+I_AC,
|
||||
|
||||
#if KS
|
||||
0700000000000+I_OP, 0701000000000+I_OP, 0701040000000+I_OP, 0701100000000+I_OP,
|
||||
0701140000000+I_OP, 0701200000000+I_OP, 0701240000000+I_OP,
|
||||
0702000000000+I_OP, 0702040000000+I_OP, 0702100000000+I_OP, 0702140000000+I_OP,
|
||||
0702200000000+I_OP, 0702240000000+I_OP, 0702300000000+I_OP, 0702340000000+I_OP,
|
||||
0702400000000+I_OP, 0702440000000+I_OP, 0702500000000+I_OP, 0702540000000+I_OP,
|
||||
0702600000000+I_OP, 0702640000000+I_OP, 0702700000000+I_OP, 0702740000000+I_OP,
|
||||
0704000000000+I_AC, 0705000000000+I_AC,
|
||||
0710000000000+I_AC, 0711000000000+I_AC, 0712000000000+I_AC, 0713000000000+I_AC,
|
||||
0714000000000+I_AC, 0715000000000+I_AC,
|
||||
0720000000000+I_AC, 0721000000000+I_AC, 0722000000000+I_AC, 0723000000000+I_AC,
|
||||
0724000000000+I_AC, 0725000000000+I_AC,
|
||||
#endif
|
||||
0700000000000+I_IO, 0700040000000+I_IO, 0700100000000+I_IO, 0700140000000+I_IO,
|
||||
0700200000000+I_IO, 0700240000000+I_IO, 0700300000000+I_IO, 0700340000000+I_IO,
|
||||
|
||||
-1
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
[](https://scan.coverity.com/projects/rcornwell-sims)
|
||||
|
||||
This is a working copy of my Burroughs B5500, Dec PDP6, KA10, KI10, KL10, SEL32, IBM 360
|
||||
This is a working copy of my Burroughs B5500, Dec PDP6, KA10, KI10, KL10, KS10, SEL32, IBM 360
|
||||
and IBM7000 series simulators for SimH.
|
||||
|
||||
# Stable released simulators.
|
||||
@@ -95,11 +95,12 @@ The PDP6 runs TOPS 10 4.5 off Dectape.
|
||||
|
||||
Type 340 graphics display.
|
||||
|
||||
# Dec KA10 & KI10 & KL10
|
||||
# Dec KA10 & KI10 & KL10 & KS10
|
||||
|
||||
The KA10 sim has successfully run Tops 10 4.5, 5.03 and 6.03, ITS and WAITS.
|
||||
The KI10 sim has successfully run Tops 10 6.03 with VMSER.
|
||||
The KL10 sim has successfully run Tops 10 6.03-7.03, ITS and Tops 20 V2-V7.
|
||||
The KS10 is still in testing.
|
||||
|
||||
Disk
|
||||
* RC10 RD10/RM10
|
||||
@@ -138,6 +139,8 @@ The KL10 sim has successfully run Tops 10 6.03-7.03, ITS and Tops 20 V2-V7.
|
||||
The RP10 supports boot (actual hardware did not), by reading in Blocks 4-7
|
||||
and transfering to the loaded value. RC10, RH10, TM10 support readin mode.
|
||||
|
||||
The KS10 supports RH11/RP and RH11/TM03 drives.
|
||||
|
||||
# ICL 1900 simulator.
|
||||
|
||||
This is a new simulator. Will pass 1904E/1905E CPU diagnostics (FLIT). Will boot paper
|
||||
|
||||
22
makefile
22
makefile
@@ -277,7 +277,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
|
||||
OS_CCDEFS += -Wno-deprecated
|
||||
endif
|
||||
endif
|
||||
ifeq (git-repo,$(shell if ${TEST} -d ./.git; then echo git-repo; fi))
|
||||
ifeq (git-repo,$(shell if ${TEST} -e ./.git; then echo git-repo; fi))
|
||||
GIT_PATH=$(strip $(shell which git))
|
||||
ifeq (,$(GIT_PATH))
|
||||
$(error building using a git repository, but git is not available)
|
||||
@@ -1196,6 +1196,7 @@ else
|
||||
ifeq (Darwin,$(OSTYPE))
|
||||
CFLAGS_O += -O4 -flto -fwhole-program
|
||||
else
|
||||
# CFLAGS_O := -O2 -fprofile-arcs -ftest-coverage
|
||||
CFLAGS_O := -O2
|
||||
endif
|
||||
endif
|
||||
@@ -2138,7 +2139,13 @@ KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \
|
||||
${KL10D}/kx10_imp.c ${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c \
|
||||
${KL10D}/ka10_ch10.c ${KL10D}/kx10_lp.c ${KL10D}/kl10_nia.c \
|
||||
${KL10D}/kx10_disk.c
|
||||
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT}
|
||||
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) ${NETWORK_OPT}
|
||||
|
||||
KS10D = ${SIMHD}/PDP10
|
||||
KS10 = ${KS10D}/kx10_cpu.c ${KS10D}/kx10_sys.c ${KS10D}/kx10_disk.c \
|
||||
${KS10D}/ks10_cty.c ${KS10D}/ks10_uba.c ${KS10D}/ks10_rp.c \
|
||||
${KS10D}/ks10_tu.c
|
||||
KS10_OPT = -DKS=1 -DUSE_INT64 -I $(KS10D) ${NETWORK_OPT}
|
||||
|
||||
ATT3B2D = ${SIMHD}/3B2
|
||||
ATT3B2 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_mmu.c \
|
||||
@@ -2214,7 +2221,7 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
|
||||
scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \
|
||||
sigma uc15 pdp10-ka pdp10-ki pdp6
|
||||
|
||||
ALL = b5500 i701 i704 i7010 i7070 i7080 i7090 pdp10-ka pdp10-ki pdp10-kl pdp6 ibm360 ibm360_32 icl1900 sel32
|
||||
ALL = b5500 i701 i704 i7010 i7070 i7080 i7090 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp6 ibm360 ibm360_32 icl1900 sel32
|
||||
|
||||
all : ${ALL}
|
||||
|
||||
@@ -3057,6 +3064,15 @@ ifneq (,$(call find_test,${PDP10D},kl10))
|
||||
$@ $(call find_test,${PDP10D},kl10) ${TEST_ARG}
|
||||
endif
|
||||
|
||||
pdp10-ks : ${BIN}pdp10-ks${EXE}
|
||||
|
||||
${BIN}pdp10-ks${EXE} : ${KS10} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${KS10} ${SIM} ${KS10_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||
ifneq (,$(call find_test,${PDP10D},ks10))
|
||||
$@ $(call find_test,${PDP10D},ks10) ${TEST_ARG}
|
||||
endif
|
||||
|
||||
# Front Panel API Demo/Test program
|
||||
|
||||
frontpaneltest : ${BIN}frontpaneltest${EXE}
|
||||
|
||||
Reference in New Issue
Block a user