1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-04-04 21:07:31 +00:00

KA10: Added support for KS10 processor.

This commit is contained in:
Richard Cornwell
2021-01-23 16:51:51 -05:00
parent fdf17b80a1
commit e4882ce3bc
9 changed files with 5001 additions and 499 deletions

268
PDP10/ks10_cty.c Normal file
View 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

File diff suppressed because it is too large Load Diff

975
PDP10/ks10_tu.c Normal file
View 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
View 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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -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
};

View File

@@ -1,7 +1,7 @@
[![Coverity Scan Build Status](https://scan.coverity.com/projects/12020/badge.svg)](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

View File

@@ -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}