mirror of
https://github.com/rcornwell/sims.git
synced 2026-03-27 10:20:52 +00:00
KA10: Merged in support for KL10A/B
This commit is contained in:
@@ -246,7 +246,7 @@ static int transaction (unsigned char *request, unsigned char *response)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auxcpu_read (int addr, t_uint64 *data)
|
||||
int auxcpu_read (t_addr addr, t_uint64 *data)
|
||||
{
|
||||
unsigned char request[12];
|
||||
unsigned char response[12];
|
||||
@@ -292,7 +292,7 @@ int auxcpu_read (int addr, t_uint64 *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int auxcpu_write (int addr, t_uint64 data)
|
||||
int auxcpu_write (t_addr addr, t_uint64 data)
|
||||
{
|
||||
unsigned char request[12];
|
||||
unsigned char response[12];
|
||||
|
||||
@@ -335,8 +335,6 @@ void ch10_command (uint32 data)
|
||||
|
||||
t_stat ch10_devio(uint32 dev, uint64 *data)
|
||||
{
|
||||
DEVICE *dptr = &imx_dev;
|
||||
|
||||
switch(dev & 07) {
|
||||
case CONO:
|
||||
sim_debug (DBG_REG, &ch10_dev, "CONO %012llo %012llo \n", *data, ch10_status);
|
||||
|
||||
623
PDP10/ka10_iii.c
Normal file
623
PDP10/ka10_iii.c
Normal file
@@ -0,0 +1,623 @@
|
||||
/* ka10_iii.c: Triple III display processor.
|
||||
|
||||
Copyright (c) 2013-2019, 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"
|
||||
#ifndef NUM_DEVS_III
|
||||
#define NUM_DEVS_III 0
|
||||
#endif
|
||||
|
||||
#if NUM_DEVS_III > 0
|
||||
#include "display/display.h"
|
||||
|
||||
|
||||
#define III_DEVNUM 0430
|
||||
|
||||
#define STATUS u3
|
||||
#define MAR u4
|
||||
#define PIA u5
|
||||
#define POS u6
|
||||
|
||||
/* CONO Bits */
|
||||
#define SET_PIA 000000010 /* Set if this bit is zero */
|
||||
#define STOP 000000020 /* Stop processor after instruction */
|
||||
#define CONT 000000040 /* Start execution at address */
|
||||
#define F 000000100 /* Clear flags */
|
||||
#define SET_MSK 000360000 /* Set mask */
|
||||
#define RST_MSK 007400000 /* Reset mask */
|
||||
|
||||
/* CONI Bits */
|
||||
#define PIA_MSK 000000007
|
||||
#define INST_HLT 000000010 /* Halt instruction */
|
||||
#define WRAP_ENB 000000020 /* Wrap around mask */
|
||||
#define EDGE_ENB 000000040 /* Edge interrupt mask */
|
||||
#define LIGH_ENB 000000100 /* Light pen enable mask */
|
||||
#define CLK_STOP 000000200 /* Clock stop */
|
||||
#define CLK_BIT 000001000 /* Clock */
|
||||
#define NXM_BIT 000002000 /* Non-existent memory */
|
||||
#define IRQ_BIT 000004000 /* Interrupt pending */
|
||||
#define DATAO_LK 000010000 /* PDP10 gave DATAO when running */
|
||||
#define LIGHT_FLG 000020000 /* Light pen flag */
|
||||
#define WRAP_FLG 000040000 /* Wrap around flag */
|
||||
#define EDGE_FLG 000100000 /* Edge overflow */
|
||||
#define HLT_FLG 000200000 /* Not running */
|
||||
|
||||
#define WRAP_MSK 00001
|
||||
#define EDGE_MSK 00002
|
||||
#define LIGH_MSK 00004
|
||||
#define HLT_MSK 00010
|
||||
#define WRP_FBIT 00020
|
||||
#define EDG_FBIT 00040
|
||||
#define LIT_FBIT 00100
|
||||
#define CTL_FBIT 00200
|
||||
#define HLT_FBIT 00400
|
||||
#define NXM_FLG 01000
|
||||
#define DATA_FLG 02000
|
||||
#define RUN_FLG 04000
|
||||
|
||||
#define TSS_INST 012 /* Test */
|
||||
#define LVW_INST 006 /* Long Vector */
|
||||
#define SVW_INST 002 /* Short vector */
|
||||
#define JMP_INST 000 /* Jump or Halt */
|
||||
#define JSR_INST 004 /* JSR(1) or JMS(0), SAVE(3) */
|
||||
#define RES_INST 014 /* Restore */
|
||||
#define SEL_INST 010 /* Select instruction */
|
||||
|
||||
#define CSIZE 00000000007 /* Current char size */
|
||||
#define CBRT 00000000070 /* Current brightness */
|
||||
#define POS_Y 00000377700
|
||||
#define POS_X 01777400000
|
||||
#define CSIZE_V 0
|
||||
#define CBRT_V 3
|
||||
#define POS_X_V 6
|
||||
#define POS_Y_V 16
|
||||
|
||||
/*
|
||||
* Character map.
|
||||
* M(x,y) moves pointer to x,y.
|
||||
* V(x,y) draws a vector between current pointer and x,y.
|
||||
* All characters start at 0,6 and end at 8,6.
|
||||
* In the map there are up to 18 points per character. For a character a M(0,0) indicates
|
||||
* that drawing is done and a move to 8,6 should be done.
|
||||
*/
|
||||
#define M(x,y) (x << 4)|y|0000
|
||||
#define V(x,y) (x << 4)|y|0200
|
||||
|
||||
uint8 map[128][18] = {
|
||||
{ 0 },
|
||||
{ M(0,9), V(3,6), V(3,14), M(3,6), V(6,9) },
|
||||
{ M(6,6), V(3,9), V(1,9), V(0,8), V(0,7), V(1,6), V(3,6), V(6,9) },
|
||||
{ V(2,8), V(2,13), V(3,14), V(5,14), V(6,13), V(6,12), V(5,11), V(2,11), M(5,11),
|
||||
V(6,10), V(6,9), V(5,8), V(3,8), V(2,9) },
|
||||
{ M(0,8), V(3,11), V(6,8) },
|
||||
{ M(0,10), V(6,10), V(6,7) },
|
||||
{ M(3,9), V(2,10), V(1,10), V(0,9), V(0,7), V(1,6), V(2,6), V(3,7), M(2,8), V(0,8) },
|
||||
{ M(0,10), V(6,10), M(4,10), V(4,6), M(2,6), V(2,10) },
|
||||
{ V(3,9), M(0,11), V(1,11), V(6,6) },
|
||||
{ M(0,11), V(1,12), V(2,12), V(5,9), V(5,7), V(4,6), V(3,6), V(2,7), V(2,8), V(6,12) },
|
||||
{ M(2,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7), V(4,9), V(3,10), V(2,10),
|
||||
V(2,12), V(4,12) },
|
||||
{ M(0,7), V(1,6), V(2,6), V(3,7), V(3,12), V(4,13), V(5,13), V(6,12) },
|
||||
{ M(0,9), V(4,9), M(2,11), V(2,7), M(0,7), V(4,7) },
|
||||
{ M(0,8), V(0,7), V(1,6), V(3,6), V(4,7), V(4,9), V(3,10), V(1,10), V(0,9), V(0,8),
|
||||
V(4,8), M(2,10), V(2,6) },
|
||||
{ M(0,10), V(1,9), V(2,9), V(4,11), V(5,11), V(6,10), V(5,9), V(4,9), V(2,11), V(1,11),
|
||||
V(0,10) },
|
||||
{ M(4,8), V(3,9), V(1,9), V(0,8), V(0,7), V(1,6), V(3,6), V(4,7), V(4,10), V(2,12),
|
||||
V(1,12) },
|
||||
{ M(3,11), V(1,11), V(0,10), V(0,8), V(1,7), V(3,7) },
|
||||
{ M(0,11), V(2,11), V(3,10), V(3,8), V(2,7), V(0,7) },
|
||||
{ M(0,7), V(0,9), V(1,10), V(3,10), V(4,9), V(4,7) },
|
||||
{ M(0,10), V(0,8), V(1,7), V(3,7), V(4,8), V(4,10) },
|
||||
{ M(0,13), V(0,8), V(2,6), V(4,6), V(6,8), V(6,13), M(0,10), V(6,10) },
|
||||
{ V(6,6), V(6,14), V(0,14), M(2,10), V(6,10) },
|
||||
{ V(4,10), M(0,10), V(4,6), M(3,6), V(1,6), V(0,7), V(0,9), V(1,10), V(3,10), V(4,9),
|
||||
V(4,7), V(3,6) },
|
||||
{ M(2,8), V(0,10), V(2,12), M(0,10), V(6,10), M(4,12), V(6,10), V(4,8) },
|
||||
{ M(0,5), V(6,5) },
|
||||
{ M(0,10), V(6,10), M(3,13), V(6,10), V(3,7) },
|
||||
{ M(0,12), V(2,14), V(4,12), V(6,14) },
|
||||
{ V(6,12), M(0,10), V(6,10), M(0,8), V(6,8) },
|
||||
{ V(3,6), M(3,7), V(0,10), V(3,13) },
|
||||
{ V(3,6), M(0,7), V(3,10), V(0,13) },
|
||||
{ M(0,7), V(6,7), M(6,9), V(0,9), M(0,11), V(6,11) },
|
||||
{ M(0,11), V(3,8), V(6,11) },
|
||||
{ 0, },
|
||||
{ M(2,6), V(2,7), M(2,8), V(2,13) },
|
||||
{ M(2,12), V(2,14), M(4,14), V(4,12) },
|
||||
{ M(2,7), V(2,13), M(4,13), V(4,7), M(6,9), V(0,9), M(0,11), V(6,11) },
|
||||
{ M(0,8), V(2,6), V(4,6), V(6,8), V(4,10), V(2,10), V(0,12), V(2,14), V(4,14), V(6,12),
|
||||
M(4,14), V(4,6), M(2,6), V(2,14) },
|
||||
{ V(6,12), V(1,12), V(0,11), V(0,10), V(1,9), V(2,9), V(3,10), V(3,11), V(2,12), M(4,9),
|
||||
V(3,8), V(3,7), V(4,6), V(5,6), V(6,7), V(6,8), V(5,9), V(4,9) },
|
||||
{ M(6,6), V(1,11), V(1,13), V(2,14), V(3,14), V(4,13), V(0,9), V(0,7), V(1,6), V(3,6),
|
||||
V(5,8) },
|
||||
{ M(2,12), V(4,14) },
|
||||
{ M(2,6), V(0,8), V(0,12), V(2,14) },
|
||||
{ V(2,8), V(2,12), V(0,14) },
|
||||
{ M(1,8), V(5,12), M(3,13), V(3,7), M(5,8), V(1,12), M(0,10), V(6,10) },
|
||||
{ M(2,7), V(2,11), M(0,9), V(4,9) },
|
||||
{ M(0,7), V(1,6), V(1,5), V(0,4) },
|
||||
{ M(0,9), V(4,9) },
|
||||
{ M(2,6), V(3,6), V(3,7), V(2,7), V(2,6) },
|
||||
{ V(6,12) },
|
||||
{ M(0,7), V(6,13), M(6,12), V(4,14), V(2,14), V(0,12), V(0,8), V(2,6), V(4,6), V(6,8),
|
||||
V(6,12) },
|
||||
{ M(1,12), V(3,14), V(3,6) },
|
||||
{ M(0,13), V(1,14), V(4,14), V(6,12), V(6,11), V(5,10), V(2,10), V(0,8), V(0,6), V(6,6) },
|
||||
{ M(0,14), V(6,14), V(6,12), V(4,10), V(5,10), V(6,9), V(6,7), V(5,6), V(0,6) },
|
||||
{ M(5,6), V(5,14), V(0,9), V(6,9) },
|
||||
{ M(0,7), V(1,6), V(4,6), V(6,8), V(6,9), V(5,10), V(1,10), V(0,9), V(0,14), V(6,14) },
|
||||
{ M(0,9), V(1,10), V(5,10), V(6,9), V(6,7), V(5,6), V(1,6), V(0,7), V(0,10), V(4,14) },
|
||||
{ V(6,12), V(6,14), V(0,14) },
|
||||
{ M(1,10), V(0,9), V(0,7), V(1,6), V(5,6), V(6,7), V(6,9), V(5,10), V(6,11), V(6,13),
|
||||
V(5,14), V(1,14), V(0,13), V(0,11), V(1,10), V(5,10) },
|
||||
{ M(2,6), V(6,10), V(6,13), V(5,14), V(1,14), V(0,13), V(0,11), V(1,10), V(5,10),
|
||||
V(6,11) },
|
||||
{ M(2,6), V(3,6), V(3,7), V(2,7), V(2,6), M(2,10), V(3,10), V(3,11), V(2,11), V(2,10) },
|
||||
{ M(2,7), V(3,6), V(3,5), V(2,4), M(2,10), V(3,10), V(3,11), V(2,11), V(2,10) },
|
||||
{ M(3,7), V(0,10), V(3,13) },
|
||||
{ M(0,8), V(6,8), M(6,10), V(0,10) },
|
||||
{ M(0,7), V(3,10), V(0,13) },
|
||||
{ M(0,13), V(1,14), V(2,13), V(2,12), V(1,11), V(1,8), M(1,7), V(1,6) },
|
||||
{ M(1,6), V(0,7), V(0,11), V(1,12), V(5,12), V(6,11), V(6,8), V(5,7), V(4,8), V(4,11),
|
||||
M(4,10), V(3,11), V(2,11), V(1,10), V(1,9), V(2,8), V(3,8), V(4,9) },
|
||||
{ V(0,12), V(2,14), V(4,14), V(6,12), V(6,9), V(0,9), V(6,9), V(6,6) },
|
||||
{ V(0,14), V(5,14), V(6,13), V(6,11), V(5,10), V(0,10), V(5,10), V(6,9), V(6,7), V(5,6),
|
||||
V(0,6) },
|
||||
{ M(6,13), V(5,14), V(2,14), V(0,12), V(0,8), V(2,6), V(5,6), V(6,7) },
|
||||
{ V(0,14), V(4,14), V(6,12), V(6,8), V(4,6), V(0,6) },
|
||||
{ M(6,6), V(0,6), V(0,10), V(4,10), V(0,10), V(0,14), V(6,14) },
|
||||
{ V(0,10), V(4,10), V(0,10), V(0,14), V(6,14) },
|
||||
{ M(6,13), V(5,14), V(2,14), V(0,12), V(0,8), V(2,6), V(4,6), V(6,8), V(6,10), V(4,10) },
|
||||
{ V(0,14), V(0,10), V(6,10), V(6,14), V(6,6) },
|
||||
{ M(1,6), V(5,6), V(3,6), V(3,14), V(1,14), V(5,14) },
|
||||
{ M(1,9), V(1,7), V(2,6), V(3,6), V(4,7), V(4,14), V(2,14), V(6,14) },
|
||||
{ V(0,14), V(0,8), V(6,14), V(2,10), V(6,6) },
|
||||
{ M(0,14), V(0,6), V(6,6) },
|
||||
{ V(0,14), V(3,11), V(6,14), V(6,6) },
|
||||
{ V(0,14), V(0,13), V(6,7), V(6,6), V(6,14) },
|
||||
{ M(0,8), V(0,12), V(2,14), V(4,14), V(6,12), V(6,8), V(4,6), V(2,6), V(0,8) },
|
||||
{ V(0,14), V(5,14), V(6,13), V(6,11), V(5,10), V(0,10) },
|
||||
{ M(0,8), V(0,12), V(2,14), V(4,14), V(6,12), V(6,8), V(4,6), V(2,6), V(0,8), M(3,9),
|
||||
V(6,6) },
|
||||
{ V(0,14), V(5,14), V(6,13), V(6,11), V(5,10), V(0,10), V(2,10), V(6,6) },
|
||||
{ M(0,8), V(2,6), V(4,6), V(6,8), V(4,10), V(2,10), V(0,12), V(2,14), V(4,14), V(6,12) },
|
||||
{ M(3,6), V(3,14), V(0,14), V(6,14) },
|
||||
{ M(0,14), V(0,7), V(1,6), V(5,6), V(6,7), V(6,14) },
|
||||
{ M(0,14), V(0,9), V(3,6), V(6,9), V(6,14) },
|
||||
{ M(0,14), V(0,6), V(3,9), V(6,6), V(6,14) },
|
||||
{ V(0,7), V(6,13), V(6,14), M(0,14), V(0,13), V(6,7), V(6,6) },
|
||||
{ M(0,14), V(3,11), V(6,14), V(3,11), V(3,6) },
|
||||
{ M(0,14), V(6,14), V(6,13), V(0,7), V(0,6), V(6,6) },
|
||||
{ M(3,5), V(0,5), V(0,15), V(3,15) },
|
||||
{ M(0,12), V(6,6) },
|
||||
{ M(0,5), V(3,5), V(3,15), V(0,15) },
|
||||
{ M(0,11), V(3,14), V(6,11), M(3,14), V(3,6) },
|
||||
{ M(3,7), V(0,10), V(3,13), M(0,10), V(6,10) },
|
||||
{ M(2,14), V(4,12) },
|
||||
{ M(0,9), V(1,10), V(3,10), V(4,9), V(4,6), M(4,8), V(3,9), V(1,9), V(0,8), V(0,7),
|
||||
V(1,6), V(3,6), V(4,7) },
|
||||
{ V(0,13), M(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6), V(1,6), V(0,7) },
|
||||
{ M(4,9), V(3,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7) },
|
||||
{ M(0,7), V(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6), V(1,6), V(0,7), M(4,6),
|
||||
V(4,13) },
|
||||
{ M(4,7), V(3,6), V(1,6), V(0,7), V(0,9), V(1,10), V(3,10), V(4,9), V(4,8), V(0,8) },
|
||||
{ M(2,6), V(2,12), V(3,13), V(4,13), V(5,12), M(0,11), V(4,11) },
|
||||
{ M(4,9), V(3,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7), M(4,10), V(4,5),
|
||||
V(3,4), V(1,4), V(0,5) },
|
||||
{ V(0,13), M(0,9), V(1,10), V(3,10), V(4,9), V(4,6) },
|
||||
{ M(3,12), V(3,11), M(3,10), V(3,7), V(4,6), V(5,6) },
|
||||
{ M(3,12), V(3,11), M(3,10), V(3,5), V(2,4), V(1,3) },
|
||||
{ V(0,13), M(0,8), V(2,10), M(0,8), V(2,6) },
|
||||
{ M(2,6), V(2,13) },
|
||||
{ V(0,10), M(0,9), V(1,10), V(2,10), V(3,9), V(3,6), M(3,9), V(4,10), V(5,10), V(6,9),
|
||||
V(6,6) },
|
||||
{ V(0,10), M(0,9), V(1,10), V(2,10), V(3,9), V(3,6) },
|
||||
{ M(0,7), V(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6), V(1,6), V(0,7) },
|
||||
{ M(0,4), V(0,10), M(0,9), V(1,10), V(3,10), V(4,9), V(4,7), V(3,6), V(1,6), V(0,7) },
|
||||
{ M(4,9), V(3,10), V(1,10), V(0,9), V(0,7), V(1,6), V(3,6), V(4,7), M(4,10), V(4,4) },
|
||||
{ V(0,10), M(0,9), V(1,10), V(3,10), V(4,9) },
|
||||
{ M(0,7), V(1,6), V(3,6), V(4,7), V(3,8), V(1,8), V(0,9), V(1,10), V(3,10), V(4,9) },
|
||||
{ M(2,13), V(2,7), V(3,6), V(4,6), V(5,7), M(1,11), V(3,11) },
|
||||
{ M(0,10), V(0,7), V(1,6), V(3,6), V(4,7), V(4,10), V(4,6) },
|
||||
{ M(0,9), V(3,6), V(6,9) },
|
||||
{ M(0,10), V(0,6), V(2,8), V(4,6), V(4,10) },
|
||||
{ V(4,10), M(0,10), V(4,6) },
|
||||
{ M(0,9), V(3,6), M(6,9), V(1,4), V(0,4) },
|
||||
{ M(0,10), V(4,10), V(0,6), V(4,6) },
|
||||
{ M(3,15), V(2,14), V(2,12), V(0,10), V(2,8), V(2,6), V(3,5) },
|
||||
{ M(2,4), V(2,14) },
|
||||
{ M(3,6), V(0,9), V(3,12), V(6,9), V(3,6) },
|
||||
{ M(0,15), V(1,14), V(1,12), V(3,10), V(1,8), V(1,6), V(0,5) },
|
||||
{ M(0,12), V(6,6) },
|
||||
};
|
||||
|
||||
uint64 iii_instr; /* Currently executing instruction */
|
||||
int iii_sel; /* Select mask */
|
||||
|
||||
t_stat iii_devio(uint32 dev, uint64 *data);
|
||||
t_stat iii_svc(UNIT *uptr);
|
||||
static void draw_point(int x, int y, int b);
|
||||
static void draw_line(int x1, int y1, int x2, int y2, int b);
|
||||
t_stat iii_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
const char *iii_description (DEVICE *dptr);
|
||||
|
||||
DIB iii_dib = { III_DEVNUM, 1, iii_devio, NULL};
|
||||
|
||||
UNIT iii_unit[] = {
|
||||
{UDATA (&iii_svc, UNIT_IDLE, 0) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
MTAB iii_mod[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE iii_dev = {
|
||||
"III", iii_unit, NULL, iii_mod,
|
||||
2, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, &iii_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS, 0, dev_debug,
|
||||
NULL, NULL, &iii_help, NULL, NULL, &iii_description
|
||||
};
|
||||
|
||||
int status;
|
||||
t_stat iii_devio(uint32 dev, uint64 *data) {
|
||||
UNIT *uptr = &iii_unit[0];
|
||||
switch(dev & 3) {
|
||||
case CONI:
|
||||
*data = (((uint64)iii_sel) << 18) | (uint64)(uptr->PIA);
|
||||
if ((iii_instr & 037) == 0)
|
||||
*data |= INST_HLT;
|
||||
*data |= (uptr->STATUS & 07) << 4;
|
||||
if (uptr->STATUS & NXM_FLG)
|
||||
*data |= NXM_BIT;
|
||||
if (uptr->STATUS & DATA_FLG)
|
||||
*data |= DATAO_LK;
|
||||
if ((uptr->STATUS & RUN_FLG) == 0)
|
||||
*data |= HLT_FLG;
|
||||
if (uptr->STATUS & WRP_FBIT)
|
||||
*data |= WRAP_FLG;
|
||||
if (uptr->STATUS & EDG_FBIT)
|
||||
*data |= EDGE_FLG;
|
||||
if (uptr->STATUS & LIT_FBIT)
|
||||
*data |= LIGHT_FLG;
|
||||
sim_debug(DEBUG_CONI, &iii_dev, "III %03o CONI %06o\n", dev, (uint32)*data);
|
||||
break;
|
||||
case CONO:
|
||||
if (*data & SET_PIA)
|
||||
uptr->PIA = (int)(*data&PIA_MSK);
|
||||
if (*data & F)
|
||||
uptr->STATUS &= ~(WRP_FBIT|EDG_FBIT|LIT_FBIT|DATA_FLG|NXM_FLG);
|
||||
uptr->STATUS &= ~(017 & ((*data >> 14) ^ (*data >> 10)));
|
||||
uptr->STATUS ^= (017 & (*data >> 10));
|
||||
if (*data & STOP)
|
||||
uptr->STATUS |= RUN_FLG;
|
||||
if (*data & CONT) {
|
||||
uptr->STATUS &= ~RUN_FLG;
|
||||
iii_instr = M[uptr->MAR];
|
||||
sim_activate(uptr, 10);
|
||||
}
|
||||
sim_debug(DEBUG_CONO, &iii_dev, "III %03o CONO %06o\n", dev, (uint32)*data);
|
||||
break;
|
||||
case DATAI:
|
||||
sim_debug(DEBUG_DATAIO, &iii_dev, "III %03o DATAI %06o\n", dev, (uint32)*data);
|
||||
break;
|
||||
case DATAO:
|
||||
if (uptr->STATUS & RUN_FLG)
|
||||
uptr->STATUS |= DATA_FLG;
|
||||
else {
|
||||
iii_instr = *data;
|
||||
sim_activate(uptr, 10);
|
||||
}
|
||||
sim_debug(DEBUG_DATAIO, &iii_dev, "III %03o DATAO %06o\n", dev, (uint32)*data);
|
||||
break;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
iii_svc (UNIT *uptr)
|
||||
{
|
||||
uint64 temp;
|
||||
int A;
|
||||
int ox, oy, nx, ny, br, sz;
|
||||
int i, j, ch;
|
||||
switch(iii_instr & 017) {
|
||||
case 000: /* JMP and HLT */
|
||||
if (iii_instr & 020) {
|
||||
uptr->MAR = (iii_instr >> 18) & RMASK;
|
||||
} else {
|
||||
uptr->STATUS &= ~RUN_FLG;
|
||||
}
|
||||
break;
|
||||
case 001:
|
||||
case 003:
|
||||
case 005:
|
||||
case 007:
|
||||
case 011:
|
||||
case 013:
|
||||
case 015:
|
||||
case 017: /* Draw 4 characters */
|
||||
/* Extract X,Y,Bright and Size */
|
||||
sz = (uptr->POS & CSIZE) >> CSIZE_V;
|
||||
br = (uptr->POS & CBRT) >> CBRT_V;
|
||||
ox = (uptr->POS & POS_X) >> POS_X_V;
|
||||
oy = (uptr->POS & POS_Y) >> POS_Y_V;
|
||||
for (i = 29; i >= 1; i -= 7) {
|
||||
/* Extract character and compute initial point */
|
||||
int cx, cy;
|
||||
uint8 v;
|
||||
ch = (iii_instr >> i) & 0177;
|
||||
cx = ox;
|
||||
cy = oy + (6 * sz);
|
||||
/* Scan map and draw lines as needed */
|
||||
for(j = 0; j < 18; j++) {
|
||||
v = map[i][j];
|
||||
if (v == 0)
|
||||
break;
|
||||
nx = cx + (((v >> 4) & 07) * sz);
|
||||
ny = cy + ((v & 017) * sz);
|
||||
if (v & 0200)
|
||||
draw_line(cx, cy, nx, ny, br);
|
||||
cx = nx;
|
||||
cy = ny;
|
||||
}
|
||||
ox += 8 * sz;
|
||||
}
|
||||
/* Repack to new position. */
|
||||
uptr->POS = (POS_X & (nx << POS_X_V)) |
|
||||
(POS_Y & (ny << POS_Y_V)) |
|
||||
(uptr->POS & (CBRT|CSIZE));
|
||||
break;
|
||||
|
||||
case 002: /* Short Vector */
|
||||
/* Extract X,Y,Bright and Size */
|
||||
sz = (uptr->POS & CSIZE) >> CSIZE_V;
|
||||
br = (uptr->POS & CBRT) >> CBRT_V;
|
||||
ox = (uptr->POS & POS_X) >> POS_X_V;
|
||||
oy = (uptr->POS & POS_Y) >> POS_Y_V;
|
||||
/* Do first point */
|
||||
nx = (iii_instr >> 29) & 077;
|
||||
ny = (iii_instr >> 22) & 077;
|
||||
/* Sign extend */
|
||||
if (nx & 0100)
|
||||
nx |= 03700;
|
||||
if (ny & 0100)
|
||||
ny |= 03700;
|
||||
/* Compute relative position. */
|
||||
nx += ox;
|
||||
ny += oy;
|
||||
if ((iii_instr & 010000000LL) == 0) { /* Check if visible */
|
||||
if ((iii_instr & 004000000LL) == 0) { /* Draw a line */
|
||||
draw_line(ox, oy, nx, ny, br);
|
||||
} else {
|
||||
draw_point(nx, ny, br);
|
||||
}
|
||||
}
|
||||
/* Do second point */
|
||||
nx = (iii_instr >> 13) & 0177;
|
||||
ny = (iii_instr >> 6) & 0177;
|
||||
/* Sign extend */
|
||||
if (nx & 0100)
|
||||
nx |= 03700;
|
||||
if (ny & 0100)
|
||||
ny |= 03700;
|
||||
/* Compute relative position. */
|
||||
nx += ox;
|
||||
ny += oy;
|
||||
if ((iii_instr & 040) == 0) { /* Check if visible */
|
||||
if ((iii_instr & 020) == 0) { /* Draw a line */
|
||||
draw_line(ox, oy, nx, ny, br);
|
||||
} else {
|
||||
draw_point(nx, ny, br);
|
||||
}
|
||||
}
|
||||
/* Repack to new position. */
|
||||
uptr->POS = (POS_X & (nx << POS_X_V)) |
|
||||
(POS_Y & (ny << POS_Y_V)) |
|
||||
(uptr->POS & (CBRT|CSIZE));
|
||||
break;
|
||||
|
||||
case 004: /* JSR, JMS, SAVE */
|
||||
temp = (((uint64)uptr->MAR) << 18) | 020 /* | CPC */;
|
||||
A = (iii_instr >> 18) & RMASK;
|
||||
if ((iii_instr & 030) != 030) {
|
||||
M[A] = temp;
|
||||
A++;
|
||||
}
|
||||
if ((iii_instr & 020) != 020) {
|
||||
temp = uptr->STATUS & 0377;
|
||||
temp |= ((uint64)uptr->POS) << 8;
|
||||
M[A] = temp;
|
||||
A++;
|
||||
}
|
||||
if ((iii_instr & 030) != 030) {
|
||||
uptr->MAR = A;
|
||||
}
|
||||
break;
|
||||
|
||||
case 006: /* Long Vector */
|
||||
/* Extract X,Y,Bright and Size */
|
||||
sz = (uptr->POS & CSIZE) >> CSIZE_V;
|
||||
br = (uptr->POS & CBRT) >> CBRT_V;
|
||||
ox = (uptr->POS & POS_X) >> POS_X_V;
|
||||
oy = (uptr->POS & POS_Y) >> POS_Y_V;
|
||||
/* Update sizes if needed */
|
||||
if (((iii_instr >> 9) & CSIZE) != 0)
|
||||
sz = (iii_instr >> 9) & CSIZE;
|
||||
if (((iii_instr >> 12) & 7) != 0)
|
||||
br = (iii_instr > 12) & 7;
|
||||
nx = (iii_instr >> 25) & 03777;
|
||||
ny = (iii_instr >> 15) & 03777;
|
||||
if ((iii_instr & 0100) == 0) { /* Relative mode */
|
||||
nx += ox;
|
||||
ny += oy;
|
||||
}
|
||||
if ((iii_instr & 040) == 0) { /* Check if visible */
|
||||
if ((iii_instr & 020) == 0) /* Draw a line */
|
||||
draw_line(ox, oy, nx, ny, br);
|
||||
else
|
||||
draw_point(nx, ny, br);
|
||||
}
|
||||
/* Repack to new position. */
|
||||
uptr->POS = (POS_X & (nx << POS_X_V)) |
|
||||
(POS_Y & (ny << POS_Y_V)) |
|
||||
(CBRT & (br << CBRT_V)) |
|
||||
(CSIZE & (sz << CSIZE_V));
|
||||
break;
|
||||
|
||||
case 010: /* Select instruction */
|
||||
break;
|
||||
|
||||
case 012: /* Test instruction */
|
||||
A = (uptr->STATUS & (int32)(iii_instr >> 12) & 0377) != 0;
|
||||
uptr->STATUS &= ~(0377 & ((iii_instr >> 28) ^ (iii_instr >> 20)));
|
||||
uptr->STATUS ^= (0377 & (iii_instr >> 20));
|
||||
if (A ^ ((iii_instr & 020) != 0))
|
||||
uptr->MAR++;
|
||||
break;
|
||||
|
||||
case 014: /* Restore */
|
||||
A = (iii_instr >> 18) & RMASK;
|
||||
temp = M[A];
|
||||
if ((iii_instr & 020) != 0) {
|
||||
uptr->STATUS &= ~0377;
|
||||
uptr->STATUS |= temp & 0377;
|
||||
}
|
||||
if ((iii_instr & 040) != 0) {
|
||||
uptr->POS = (temp >> 8) & (POS_X|POS_Y|CBRT|CSIZE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 016: /* Nop */
|
||||
break;
|
||||
}
|
||||
if (uptr->STATUS & RUN_FLG) {
|
||||
iii_instr = M[uptr->MAR];
|
||||
uptr->MAR++;
|
||||
uptr->MAR &= RMASK;
|
||||
sim_activate(uptr, 10);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Draw a point at x,y with intensity b. */
|
||||
/* X and Y runs from -512 to 512. */
|
||||
static void
|
||||
draw_point(int x, int y, int b)
|
||||
{
|
||||
display_point(x, y, b, 0);
|
||||
}
|
||||
|
||||
/* Draw a line between two points */
|
||||
static void
|
||||
draw_line(int x1, int y1, int x2, int y2, int b)
|
||||
{
|
||||
int dx, px;
|
||||
int dy, py;
|
||||
int i, p;
|
||||
int minx, miny;
|
||||
int maxx, maxy;
|
||||
|
||||
dx = x1 - x2;
|
||||
dy = y1 - y2;
|
||||
if (x1 < 0) {
|
||||
dx = -1;
|
||||
px = -x1;
|
||||
} else if (x1 > 0) {
|
||||
dx = 1;
|
||||
px = x1;
|
||||
} else {
|
||||
dx = 0;
|
||||
px = 0;
|
||||
}
|
||||
|
||||
if (y1 < 0) {
|
||||
dy = -1;
|
||||
py = -y1;
|
||||
} else if (y1 > 0) {
|
||||
dy = 1;
|
||||
py = y1;
|
||||
} else {
|
||||
dy = 0;
|
||||
py = 0;
|
||||
}
|
||||
|
||||
if (dx == 0) {
|
||||
/* Vertical line */
|
||||
for (i = 1; i < py; i++) {
|
||||
dy += dy;
|
||||
draw_point(dx, dy, b);
|
||||
}
|
||||
} else if (dy == 0) {
|
||||
/* Horizontal line */
|
||||
for (i = 1; i < px; i++) {
|
||||
dx += dx;
|
||||
draw_point(dx, dy, b);
|
||||
}
|
||||
} else if (py > px) {
|
||||
/* More horizontal */
|
||||
p = 2 * px - py;
|
||||
for (i = 1; i < py; i++) {
|
||||
if (p > 0) {
|
||||
dx += dx;
|
||||
p += (2 * px) - (2 * py);
|
||||
} else {
|
||||
p += 2 * px;
|
||||
}
|
||||
dy += dy;
|
||||
draw_point(dx, dy, b);
|
||||
}
|
||||
} else {
|
||||
/* More vertical */
|
||||
p = 2 * py - px;
|
||||
for (i = 1; i < px; i++) {
|
||||
if (p > 0) {
|
||||
dy += dy;
|
||||
p += (2 * py) - (2 * px);
|
||||
} else {
|
||||
p += 2 * py;
|
||||
}
|
||||
dx += dx;
|
||||
draw_point(dx, dy, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t_stat iii_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *iii_description (DEVICE *dptr)
|
||||
{
|
||||
return "Triple III Display";
|
||||
}
|
||||
#endif
|
||||
@@ -142,7 +142,7 @@
|
||||
#define DK_MSK_SKNONE 0x18 /* Allow no seeks */
|
||||
#define DK_MSK_SK 0x18 /* Seek mask */
|
||||
|
||||
#define POS u4
|
||||
#define POS u4
|
||||
/* u4 */
|
||||
/* Holds the current track and head */
|
||||
#define DK_V_TRACK 8
|
||||
@@ -348,9 +348,9 @@ uint64 pmp_status; /* CONI status for device 500 */
|
||||
int pmp_statusb;
|
||||
uint32 pmp_cmd_hold; /* Command hold register */
|
||||
uint32 pmp_wc_hold; /* Word count hold */
|
||||
uint32 pmp_addr_hold; /* Address register hold */
|
||||
t_addr pmp_addr_hold; /* Address register hold */
|
||||
uint32 pmp_wc; /* Current word count register */
|
||||
uint32 pmp_addr; /* Current address register */
|
||||
t_addr pmp_addr; /* Current address register */
|
||||
uint64 pmp_data; /* Data assembly register */
|
||||
int pmp_cnt; /* Character count in asm register */
|
||||
int pmp_cmd; /* Current command */
|
||||
@@ -382,7 +382,7 @@ t_stat pmp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *pmp_description (DEVICE *dptr);
|
||||
|
||||
DIB pmp_dib[] = {
|
||||
DIB pmp_dib[] = {
|
||||
{PMP_DEV, 2, &pmp_devio, NULL}};
|
||||
|
||||
|
||||
@@ -433,13 +433,13 @@ pmp_devio(uint32 dev, uint64 *data) {
|
||||
if ((pmp_statusb & (WCMA_LD|CMD_LD)) != (WCMA_LD|CMD_LD))
|
||||
*data |= HOLD_EMPTY;
|
||||
if (pmp_cur_unit != NULL)
|
||||
*data |= ((uint64)GET_UADDR(pmp_cur_unit->flags)) << 24;
|
||||
*data |= ((uint64)GET_UADDR(pmp_cur_unit->flags)) << 24;
|
||||
if ((pmp_status & (NXM_ERR|CHA_ERR|SEL_ERR)) != 0)
|
||||
*data |= UNU_END;
|
||||
sim_debug(DEBUG_CONI, &pmp_dev, "PMP %03o CONI %012llo PC=%o\n",
|
||||
dev, *data, PC);
|
||||
break;
|
||||
|
||||
|
||||
case CONO:
|
||||
sim_debug(DEBUG_CONO, &pmp_dev, "PMP %03o CONO %012llo PC=%06o\n",
|
||||
dev, *data, PC);
|
||||
@@ -597,9 +597,8 @@ chan_read_byte(uint8 *data) {
|
||||
pmp_statusb |= TRANS_CH; /* Tranfer in progress */
|
||||
/* Read in next work if buffer is in empty status */
|
||||
if (pmp_cnt & BUFF_EMPTY) {
|
||||
if (pmp_addr >= (int)MEMSIZE)
|
||||
if (Mem_read_word(pmp_addr, &pmp_data, 0))
|
||||
return pmp_posterror(NXM_ERR);
|
||||
pmp_data = M[pmp_addr];
|
||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read %06o %012llo\n", pmp_addr, pmp_data);
|
||||
pmp_addr++;
|
||||
pmp_cnt = 0;
|
||||
@@ -616,10 +615,9 @@ chan_read_byte(uint8 *data) {
|
||||
if ((pmp_cnt & 0xf) > 0x3) {
|
||||
if ((pmp_cnt & 0xf) == 0x4) { /* Split byte */
|
||||
byte = (pmp_data << 4) & 0xf0;
|
||||
if (pmp_addr >= (int)MEMSIZE)
|
||||
if (Mem_read_word(pmp_addr, &pmp_data, 0))
|
||||
return pmp_posterror(NXM_ERR);
|
||||
pmp_data = M[pmp_addr];
|
||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read %06o %012llo\n", pmp_addr, pmp_data);
|
||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_read %06o %012llo\n", pmp_addr, pmp_data);
|
||||
pmp_addr++;
|
||||
xfer = 1; /* Read in a word */
|
||||
byte |= pmp_data & 0xf;
|
||||
@@ -639,7 +637,7 @@ chan_read_byte(uint8 *data) {
|
||||
} else if (xfer) {
|
||||
pmp_wc ++;
|
||||
}
|
||||
if (pmp_wc & 07000000)
|
||||
if (pmp_wc & 07000000)
|
||||
pmp_cnt |= BUFF_CHNEND;
|
||||
return 0;
|
||||
#if 0
|
||||
@@ -693,11 +691,10 @@ chan_write_byte(uint8 *data) {
|
||||
pmp_cnt |= BUFF_DIRTY;
|
||||
if ((pmp_cnt & 03) == 0) {
|
||||
pmp_cnt &= ~(BUFF_DIRTY|7);
|
||||
if (pmp_addr >= (int)MEMSIZE)
|
||||
if (Mem_write_word(pmp_addr, &pmp_data, 0))
|
||||
return pmp_posterror(NXM_ERR);
|
||||
M[pmp_addr] = pmp_data;
|
||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo\n", pmp_addr, pmp_data);
|
||||
pmp_addr++;
|
||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo\n", pmp_addr, pmp_data);
|
||||
pmp_addr++;
|
||||
xfer = 1;
|
||||
}
|
||||
} else {
|
||||
@@ -705,9 +702,8 @@ chan_write_byte(uint8 *data) {
|
||||
if ((pmp_cnt & 0xf) == 0x4) { /* Split byte */
|
||||
pmp_data &= ~0xf;
|
||||
pmp_data |= (uint64)((*data >> 4) & 0xf);
|
||||
if (pmp_addr >= (int)MEMSIZE)
|
||||
if (Mem_write_word(pmp_addr, &pmp_data, 0))
|
||||
return pmp_posterror(NXM_ERR);
|
||||
M[pmp_addr] = pmp_data;
|
||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo %2x\n", pmp_addr, pmp_data, pmp_cnt);
|
||||
pmp_addr++;
|
||||
xfer = 1; /* Read in a word */
|
||||
@@ -726,9 +722,8 @@ chan_write_byte(uint8 *data) {
|
||||
pmp_cnt++;
|
||||
if ((pmp_cnt & 0xf) == 9) {
|
||||
pmp_cnt = BUFF_EMPTY;
|
||||
if (pmp_addr >= (int)MEMSIZE)
|
||||
if (Mem_write_word(pmp_addr, &pmp_data, 0))
|
||||
return pmp_posterror(NXM_ERR);
|
||||
M[pmp_addr] = pmp_data;
|
||||
sim_debug(DEBUG_DETAIL, &pmp_dev, "chan_write %06o %012llo %2x\n", pmp_addr, pmp_data, pmp_cnt);
|
||||
pmp_addr++;
|
||||
xfer = 1; /* Read in a word */
|
||||
@@ -774,16 +769,15 @@ chan_end(uint8 flags) {
|
||||
/* Flush buffer if there was any change */
|
||||
if (pmp_cnt & BUFF_DIRTY) {
|
||||
pmp_cnt = BUFF_EMPTY;
|
||||
if (pmp_addr >= (int)MEMSIZE) {
|
||||
if (Mem_write_word(pmp_addr, &pmp_data, 0)) {
|
||||
(void) pmp_posterror(NXM_ERR);
|
||||
return;
|
||||
}
|
||||
M[pmp_addr] = pmp_data;
|
||||
sim_debug(DEBUG_DATA, &pmp_dev, "chan_write %012llo\n", pmp_data);
|
||||
pmp_addr++;
|
||||
}
|
||||
pmp_statusb &= ~TRANS_CH; /* Clear transfer in progress */
|
||||
pmp_statusb |= IDLE_CH;
|
||||
pmp_statusb |= IDLE_CH;
|
||||
pmp_status |= NEW_STS | CHN_END | ((uint64)flags) << 5;
|
||||
|
||||
if (pmp_status & (BSY|UNIT_CHK))
|
||||
@@ -798,7 +792,7 @@ chan_end(uint8 flags) {
|
||||
if (pmp_cmd & DATCH_ON) {
|
||||
(void) pmp_posterror(CHA_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pmp_cmd & CMDCH_ON) {
|
||||
pmp_startcmd();
|
||||
|
||||
@@ -239,7 +239,7 @@ static int transaction (unsigned char *request, unsigned char *response)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_word (int addr, int *data)
|
||||
static int read_word (t_addr addr, int *data)
|
||||
{
|
||||
unsigned char request[8];
|
||||
unsigned char response[8];
|
||||
@@ -285,7 +285,7 @@ static int read_word (int addr, int *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ten11_read (int addr, uint64 *data)
|
||||
int ten11_read (t_addr addr, uint64 *data)
|
||||
{
|
||||
int offset = addr & 01777;
|
||||
int word1, word2;
|
||||
@@ -328,7 +328,7 @@ int ten11_read (int addr, uint64 *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_word (int addr, uint16 data)
|
||||
static int write_word (t_addr addr, uint16 data)
|
||||
{
|
||||
unsigned char request[8];
|
||||
unsigned char response[8];
|
||||
@@ -366,7 +366,7 @@ static int write_word (int addr, uint16 data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ten11_write (int addr, uint64 data)
|
||||
int ten11_write (t_addr addr, uint64 data)
|
||||
{
|
||||
int offset = addr & 01777;
|
||||
|
||||
|
||||
2463
PDP10/kl10_fe.c
Normal file
2463
PDP10/kl10_fe.c
Normal file
File diff suppressed because it is too large
Load Diff
1672
PDP10/kl10_nia.c
Normal file
1672
PDP10/kl10_nia.c
Normal file
File diff suppressed because it is too large
Load Diff
4824
PDP10/kx10_cpu.c
4824
PDP10/kx10_cpu.c
File diff suppressed because it is too large
Load Diff
@@ -46,16 +46,12 @@
|
||||
#define KI 0
|
||||
#endif
|
||||
|
||||
#ifndef KLA
|
||||
#define KLA 0
|
||||
#ifndef KL
|
||||
#define KL 0
|
||||
#endif
|
||||
|
||||
#ifndef KLB
|
||||
#define KLB 0
|
||||
#endif
|
||||
|
||||
#ifndef KL /* Either KL10A or KL10B */
|
||||
#define KL (KLA+KLB)
|
||||
#if KL
|
||||
#define EPT440 0 /* Force KL10 to use as 440 section address */
|
||||
#endif
|
||||
|
||||
#if (PDP6 + KA + KI + KL) != 1
|
||||
@@ -81,6 +77,11 @@
|
||||
#define WAITS KA
|
||||
#endif
|
||||
|
||||
/* Support for ITS on KL */
|
||||
#ifndef KL_ITS
|
||||
#define KL_ITS KL
|
||||
#endif
|
||||
|
||||
#ifndef PDP6_DEV /* Include PDP6 devices */
|
||||
#define PDP6_DEV PDP6|WAITS
|
||||
#endif
|
||||
@@ -161,12 +162,19 @@ extern DEBTAB crd_debug[];
|
||||
#define XMASK 03777777777777LL
|
||||
#define EMASK 00777000000000LL
|
||||
#define MMASK 00000777777777LL
|
||||
#define SECTM 00007777000000LL
|
||||
#define BIT1 00200000000000LL
|
||||
#define BIT2 00100000000000LL
|
||||
#define BIT3 00040000000000LL
|
||||
#define BIT4 00020000000000LL
|
||||
#define BIT5 00010000000000LL
|
||||
#define BIT6 00004000000000LL
|
||||
#define BIT7 00002000000000LL
|
||||
#define BIT8 00001000000000LL
|
||||
#define BIT9 00000400000000LL
|
||||
#define BIT10 00000200000000LL
|
||||
#define BIT10_35 00000377777777LL
|
||||
#define BIT12 00000040000000LL
|
||||
#define BIT17 00000001000000LL
|
||||
#define MANT 00000777777777LL
|
||||
#define EXPO 00377000000000LL
|
||||
@@ -181,6 +189,7 @@ extern DEBTAB crd_debug[];
|
||||
#define FPRBIT1 00000000000200000000000LL
|
||||
|
||||
#define CM(x) (FMASK ^ (x))
|
||||
#define CCM(x) ((CMASK ^ (x)) & CMASK)
|
||||
|
||||
#define INST_V_OP 27 /* opcode */
|
||||
#define INST_M_OP 0777
|
||||
@@ -205,6 +214,8 @@ extern DEBTAB crd_debug[];
|
||||
#define LRZ(x) (((x) >> 18) & RMASK)
|
||||
#define JRST1 (((uint64)OP_JRST << 27) + 1)
|
||||
|
||||
#define OP_PORTAL(x) (((x) & 00777740000000LL) == 0254040000000LL)
|
||||
|
||||
#if PDP6
|
||||
#define NODIV 000000
|
||||
#define FLTUND 000000
|
||||
@@ -275,6 +286,12 @@ extern DEBTAB crd_debug[];
|
||||
#define AMASK 00000017777777LL
|
||||
#define WMASK 0037777LL
|
||||
#define CSHIFT 22
|
||||
#if KL
|
||||
#define RH20_WMASK 003777LL
|
||||
#define RH20_XFER SMASK
|
||||
#define RH20_HALT BIT1
|
||||
#define RH20_REV BIT2
|
||||
#endif
|
||||
#else
|
||||
#define AMASK RMASK
|
||||
#define WMASK RMASK
|
||||
@@ -285,11 +302,19 @@ extern DEBTAB crd_debug[];
|
||||
#define PI_ENABLE 0000000010 /* Clear DONE */
|
||||
#define BUSY 0000000020 /* STOP */
|
||||
#define CCW_COMP 0000000040 /* Write Final CCW */
|
||||
/* RH10 / RH20 interrupt */
|
||||
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */
|
||||
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */
|
||||
#define CCW_COMP_1 0000000040000LL /* Control word written. */
|
||||
|
||||
#if KI
|
||||
#define DEF_SERIAL 514 /* Default DEC test machine */
|
||||
#endif
|
||||
|
||||
#if KL
|
||||
#define DEF_SERIAL 1025 /* Default DEC test machine */
|
||||
#endif
|
||||
|
||||
#if BBN
|
||||
#define BBN_PAGE 0000017777777LL
|
||||
#define BBN_TRPPG 0000017000000LL
|
||||
@@ -306,13 +331,36 @@ extern DEBTAB crd_debug[];
|
||||
#define BBN_MERGE 0161740000000LL
|
||||
#endif
|
||||
|
||||
#if KL
|
||||
/* KL10 TLB paging bits */
|
||||
#define KL_PAG_A 0400000 /* Access */
|
||||
#define KL_PAG_P 0200000 /* Public */
|
||||
#define KL_PAG_W 0100000 /* Writable (M Tops 20) */
|
||||
#define KL_PAG_S 0040000 /* Software (W Writable Tops 20) */
|
||||
#define KL_PAG_C 0020000 /* Cacheable */
|
||||
#endif
|
||||
|
||||
#if KI
|
||||
/* KI10 TLB paging bits */
|
||||
#define KI_PAG_A 0400000 /* Access */
|
||||
#define KI_PAG_P 0200000 /* Public */
|
||||
#define KI_PAG_W 0100000 /* Writable */
|
||||
#define KI_PAG_S 0040000 /* Software */
|
||||
#define KI_PAG_X 0020000 /* Reserved */
|
||||
#endif
|
||||
|
||||
/* Flags for CPU unit */
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF + 0)
|
||||
#define UNIT_MSIZE (0177 << UNIT_V_MSIZE)
|
||||
#define UNIT_V_MAOFF (UNIT_V_MSIZE + 8)
|
||||
#define UNIT_V_PAGE (UNIT_V_MAOFF + 1)
|
||||
#define UNIT_MAOFF (1 << UNIT_V_MAOFF)
|
||||
#if KL
|
||||
#define UNIT_KL10B (1 << UNIT_V_PAGE)
|
||||
#define UNIT_TWOSEG (0)
|
||||
#else
|
||||
#define UNIT_TWOSEG (1 << UNIT_V_PAGE)
|
||||
#endif
|
||||
#define UNIT_ITSPAGE (2 << UNIT_V_PAGE)
|
||||
#define UNIT_BBNPAGE (4 << UNIT_V_PAGE)
|
||||
#define UNIT_M_PAGE (007 << UNIT_V_PAGE)
|
||||
@@ -322,7 +370,29 @@ extern DEBTAB crd_debug[];
|
||||
#define UNIT_V_MPX (UNIT_V_WAITS + 1)
|
||||
#define UNIT_M_MPX (1 << UNIT_V_MPX)
|
||||
#define UNIT_MPX (UNIT_M_MPX) /* MPX Device for ITS */
|
||||
#define CNTRL_V_RH (UNIT_V_UF + 4)
|
||||
#define CNTRL_M_RH 7
|
||||
#define GET_CNTRL_RH(x) (((x) >> CNTRL_V_RH) & CNTRL_M_RH)
|
||||
#define CNTRL_RH(x) (((x) & CNTRL_M_RH) << CNTRL_V_RH)
|
||||
#define DEV_V_RH (DEV_V_UF + 1) /* Type RH20 */
|
||||
#define DEV_M_RH (1 << DEV_V_RH)
|
||||
#define TYPE_RH10 (0 << DEV_V_RH)
|
||||
#define TYPE_RH20 (1 << DEV_V_RH)
|
||||
|
||||
#if KL
|
||||
/* DTE memory access functions, n = DTE# */
|
||||
extern int Mem_examine_word(int n, int wrd, uint64 *data);
|
||||
extern int Mem_deposit_word(int n, int wrd, uint64 *data);
|
||||
extern int Mem_read_byte(int n, uint16 *data, int byte);
|
||||
extern int Mem_write_byte(int n, uint16 *data);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Access main memory. Returns 0 if access ok, 1 if out of memory range.
|
||||
* On KI10 and KL10, optional EPT flag indicates address relative to ept.
|
||||
*/
|
||||
extern int Mem_read_word(t_addr addr, uint64 *data, int ept);
|
||||
extern int Mem_write_word(t_addr addr, uint64 *data, int ept);
|
||||
|
||||
#if MPX_DEV
|
||||
extern void set_interrupt_mpx(int dev, int lvl, int mpx);
|
||||
@@ -338,8 +408,15 @@ extern void set_pi_hold();
|
||||
extern UNIT cpu_unit[];
|
||||
extern UNIT ten11_unit[];
|
||||
extern UNIT auxcpu_unit[];
|
||||
extern DEVICE cpu_dev;
|
||||
#if KL
|
||||
extern DEVICE dte_dev;
|
||||
extern DEVICE lp20_dev;
|
||||
extern DEVICE tty_dev;
|
||||
extern DEVICE nia_dev;
|
||||
#else
|
||||
extern DEVICE cty_dev;
|
||||
#endif
|
||||
extern DEVICE cpu_dev;
|
||||
extern DEVICE mt_dev;
|
||||
extern DEVICE dpa_dev;
|
||||
extern DEVICE dpb_dev;
|
||||
@@ -365,6 +442,7 @@ extern DEVICE pmp_dev;
|
||||
extern DEVICE dk_dev;
|
||||
extern DEVICE pd_dev;
|
||||
extern DEVICE dpy_dev;
|
||||
extern DEVICE iii_dev;
|
||||
extern DEVICE imx_dev;
|
||||
extern DEVICE imp_dev;
|
||||
extern DEVICE ch10_dev;
|
||||
@@ -387,41 +465,67 @@ extern t_stat (*dev_tab[128])(uint32 dev, t_uint64 *data);
|
||||
|
||||
#define VEC_DEVMAX 8 /* max device vec */
|
||||
|
||||
/* DF10 Interface */
|
||||
struct df10 {
|
||||
uint32 status; /* DF10 status word */
|
||||
uint32 cia; /* Initial transfer address */
|
||||
uint32 ccw; /* Next control word address */
|
||||
uint32 wcr; /* CUrrent word count */
|
||||
uint32 cda; /* Current transfer address */
|
||||
uint32 devnum; /* Device number */
|
||||
t_uint64 buf; /* Data buffer */
|
||||
uint8 nxmerr; /* Bit to set for NXM */
|
||||
uint8 ccw_comp; /* Have we written out CCW */
|
||||
} ;
|
||||
|
||||
/* RH10/RH20 Interface */
|
||||
struct rh_if {
|
||||
void (*dev_write)(DEVICE *dptr, struct rh_if *rh, int reg, uint32 data);
|
||||
uint32 (*dev_read)(DEVICE *dptr, struct rh_if *rh, int reg);
|
||||
void (*dev_reset)(DEVICE *dptr);
|
||||
t_uint64 buf; /* Data buffer */
|
||||
uint32 status; /* DF10 status word */
|
||||
uint32 cia; /* Initial transfer address */
|
||||
uint32 ccw; /* Current word count */
|
||||
uint32 wcr;
|
||||
uint32 cda; /* Current transfer address */
|
||||
uint32 devnum; /* Device number */
|
||||
int ivect; /* Interrupt vector */
|
||||
uint8 imode; /* Mode of vector */
|
||||
int cop; /* RH20 Channel operator */
|
||||
uint32 sbar; /* RH20 Starting address */
|
||||
uint32 stcr; /* RH20 Count */
|
||||
uint32 pbar;
|
||||
uint32 ptcr;
|
||||
int reg; /* Last register selected */
|
||||
int drive; /* Last drive selected */
|
||||
int rae; /* Access register error */
|
||||
int attn; /* Attention bits */
|
||||
int xfer_drive; /* Current transfering drive */
|
||||
};
|
||||
|
||||
/* Device context block */
|
||||
struct pdp_dib {
|
||||
uint32 dev_num; /* device address */
|
||||
uint32 num_devs; /* length */
|
||||
t_stat (*io)(uint32 dev, t_uint64 *data);
|
||||
int (*irq)(uint32 dev, int addr);
|
||||
t_addr (*irq)(uint32 dev, t_addr addr);
|
||||
struct rh_if *rh;
|
||||
};
|
||||
|
||||
|
||||
#define RH10_DEV 01000
|
||||
#define RH20_DEV 02000
|
||||
struct rh_dev {
|
||||
uint32 dev_num;
|
||||
DEVICE *dev;
|
||||
struct rh_if *rh;
|
||||
};
|
||||
|
||||
|
||||
typedef struct pdp_dib DIB;
|
||||
|
||||
|
||||
/* DF10 Interface */
|
||||
struct df10 {
|
||||
uint32 status;
|
||||
uint32 cia;
|
||||
uint32 ccw;
|
||||
uint32 wcr;
|
||||
uint32 cda;
|
||||
uint32 devnum;
|
||||
t_uint64 buf;
|
||||
uint8 nxmerr;
|
||||
uint8 ccw_comp;
|
||||
} ;
|
||||
|
||||
|
||||
void df10_setirq(struct df10 *df) ;
|
||||
void df10_writecw(struct df10 *df) ;
|
||||
void df10_finish_op(struct df10 *df, int flags) ;
|
||||
void df10_setirq(struct df10 *df);
|
||||
void df10_writecw(struct df10 *df);
|
||||
void df10_finish_op(struct df10 *df, int flags);
|
||||
void df10_setup(struct df10 *df, uint32 addr);
|
||||
int df10_fetch(struct df10 *df);
|
||||
int df10_read(struct df10 *df);
|
||||
@@ -432,8 +536,27 @@ int dct_write(int u, t_uint64 *data, int c);
|
||||
int dct_is_connect(int u);
|
||||
#endif
|
||||
|
||||
int ten11_read (int addr, t_uint64 *data);
|
||||
int ten11_write (int addr, t_uint64 data);
|
||||
/* Define RH10/RH20 functions */
|
||||
t_stat rh_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat rh_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat rh_devio(uint32 dev, t_uint64 *data);
|
||||
t_addr rh_devirq(uint32 dev, t_addr addr);
|
||||
#if KL
|
||||
void rh20_setup(struct rh_if *rhc);
|
||||
#endif
|
||||
void rh_setup(struct rh_if *rh, uint32 addr);
|
||||
void rh_setattn(struct rh_if *rh, int unit);
|
||||
void rh_error(struct rh_if *rh);
|
||||
int rh_blkend(struct rh_if *rh);
|
||||
void rh_setirq(struct rh_if *rh);
|
||||
void rh_writecw(struct rh_if *rh, int nxm);
|
||||
void rh_finish_op(struct rh_if *rh, int flags);
|
||||
int rh_read(struct rh_if *rh);
|
||||
int rh_write(struct rh_if *rh);
|
||||
|
||||
|
||||
int ten11_read (t_addr addr, t_uint64 *data);
|
||||
int ten11_write (t_addr addr, t_uint64 data);
|
||||
|
||||
/* Console lights. */
|
||||
extern void ka10_lights_init (void);
|
||||
@@ -441,14 +564,20 @@ extern void ka10_lights_main (t_uint64);
|
||||
extern void ka10_lights_set_aux (int);
|
||||
extern void ka10_lights_clear_aux (int);
|
||||
|
||||
int auxcpu_read (int addr, t_uint64 *);
|
||||
int auxcpu_write (int addr, t_uint64);
|
||||
int auxcpu_read (t_addr addr, t_uint64 *);
|
||||
int auxcpu_write (t_addr addr, t_uint64);
|
||||
|
||||
/* I/O system parameters */
|
||||
#define NUM_DEVS_LP 1
|
||||
#if KL
|
||||
#define NUM_DEVS_PT 0
|
||||
#define NUM_DEVS_CR 0
|
||||
#define NUM_DEVS_CP 0
|
||||
#else
|
||||
#define NUM_DEVS_PT 1
|
||||
#define NUM_DEVS_CR 1
|
||||
#define NUM_DEVS_CP 1
|
||||
#endif
|
||||
#define NUM_DEVS_DPY USE_DISPLAY
|
||||
#define NUM_DEVS_WCNSLS USE_DISPLAY
|
||||
#if PDP6_DEV
|
||||
@@ -461,16 +590,31 @@ int auxcpu_write (int addr, t_uint64);
|
||||
#if !PDP6
|
||||
#define NUM_DEVS_DC 1
|
||||
#define NUM_DEVS_MT 1
|
||||
#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 40
|
||||
#define NUM_DEVS_NIA 1
|
||||
#else
|
||||
#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
|
||||
#define NUM_DEVS_RP 4
|
||||
#define NUM_DEVS_RS 1
|
||||
#define NUM_DEVS_TU 1
|
||||
#define NUM_DEVS_PMP WAITS
|
||||
#define NUM_DEVS_DKB WAITS
|
||||
#define NUM_DEVS_PD ITS
|
||||
#define NUM_DEVS_III 0 /* (WAITS * USE_DISPLAY) *//* Disabled until working */
|
||||
#define NUM_DEVS_PD ITS | KL_ITS
|
||||
#define NUM_DEVS_IMX ITS
|
||||
#define NUM_DEVS_STK ITS
|
||||
#define NUM_DEVS_TK10 ITS
|
||||
@@ -478,7 +622,7 @@ int auxcpu_write (int addr, t_uint64);
|
||||
#define NUM_DEVS_TEN11 ITS
|
||||
#define NUM_DEVS_AUXCPU ITS
|
||||
#define NUM_DEVS_IMP 1
|
||||
#define NUM_DEVS_CH10 ITS
|
||||
#define NUM_DEVS_CH10 ITS | KL_ITS
|
||||
#define NUM_DEVS_DPK ITS
|
||||
#define NUM_DEVS_AI ITS
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* ka10_df.c: DF10 common routines.
|
||||
/* kx10_df.c: DF10 common routines.
|
||||
|
||||
Copyright (c) 2015-2017, Richard Cornwell
|
||||
Copyright (c) 2015-2019, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -23,18 +23,24 @@
|
||||
|
||||
#include "kx10_defs.h"
|
||||
|
||||
|
||||
/* Set an IRQ for a DF10 device */
|
||||
void df10_setirq(struct df10 *df) {
|
||||
df->status |= PI_ENABLE;
|
||||
set_interrupt(df->devnum, df->status);
|
||||
}
|
||||
|
||||
/* Generate the DF10 complete word */
|
||||
void df10_writecw(struct df10 *df) {
|
||||
uint64 wrd;
|
||||
df->status |= 1 << df->ccw_comp;
|
||||
if (df->wcr != 0)
|
||||
df->cda++;
|
||||
M[df->cia|1] = ((uint64)(df->ccw & WMASK) << CSHIFT) | ((uint64)(df->cda) & AMASK);
|
||||
wrd = ((uint64)(df->ccw & WMASK) << CSHIFT) | ((uint64)(df->cda) & AMASK);
|
||||
(void)Mem_write_word(df->cia|1, &wrd, 0);
|
||||
}
|
||||
|
||||
/* Finish off a DF10 transfer */
|
||||
void df10_finish_op(struct df10 *df, int flags) {
|
||||
df->status &= ~BUSY;
|
||||
df->status |= flags;
|
||||
@@ -42,6 +48,7 @@ void df10_finish_op(struct df10 *df, int flags) {
|
||||
df10_setirq(df);
|
||||
}
|
||||
|
||||
/* Setup for a DF10 transfer */
|
||||
void df10_setup(struct df10 *df, uint32 addr) {
|
||||
df->cia = addr & ICWA;
|
||||
df->ccw = df->cia;
|
||||
@@ -50,24 +57,23 @@ void df10_setup(struct df10 *df, uint32 addr) {
|
||||
df->status &= ~(1 << df->ccw_comp);
|
||||
}
|
||||
|
||||
/* Fetch the next IO control word */
|
||||
int df10_fetch(struct df10 *df) {
|
||||
uint64 data;
|
||||
if (df->ccw > MEMSIZE) {
|
||||
if (Mem_read_word(df->ccw, &data, 0)) {
|
||||
df10_finish_op(df, df->nxmerr);
|
||||
return 0;
|
||||
}
|
||||
data = M[df->ccw];
|
||||
while((data & (WMASK << CSHIFT)) == 0) {
|
||||
if ((data & AMASK) == 0 || (uint32)(data & AMASK) == df->ccw) {
|
||||
df10_finish_op(df,0);
|
||||
return 0;
|
||||
}
|
||||
df->ccw = (uint32)(data & AMASK);
|
||||
if (df->ccw > MEMSIZE) {
|
||||
if (Mem_read_word(df->ccw, &data, 0)) {
|
||||
df10_finish_op(df, 1<<df->nxmerr);
|
||||
return 0;
|
||||
}
|
||||
data = M[df->ccw];
|
||||
}
|
||||
#if KA & ITS
|
||||
if (cpu_unit[0].flags & UNIT_ITSPAGE) {
|
||||
@@ -84,6 +90,7 @@ int df10_fetch(struct df10 *df) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read next word */
|
||||
int df10_read(struct df10 *df) {
|
||||
uint64 data;
|
||||
if (df->wcr == 0) {
|
||||
@@ -102,7 +109,10 @@ int df10_read(struct df10 *df) {
|
||||
else
|
||||
#endif
|
||||
df->cda = (uint32)((df->cda + 1) & AMASK);
|
||||
data = M[df->cda];
|
||||
if (Mem_read_word(df->cda, &data, 0)) {
|
||||
df10_finish_op(df, 1<<df->nxmerr);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
data = 0;
|
||||
}
|
||||
@@ -113,6 +123,7 @@ int df10_read(struct df10 *df) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Write next word */
|
||||
int df10_write(struct df10 *df) {
|
||||
if (df->wcr == 0) {
|
||||
if (!df10_fetch(df))
|
||||
@@ -130,7 +141,10 @@ int df10_write(struct df10 *df) {
|
||||
else
|
||||
#endif
|
||||
df->cda = (uint32)((df->cda + 1) & AMASK);
|
||||
M[df->cda] = df->buf;
|
||||
if (Mem_write_word(df->cda, &df->buf, 0)) {
|
||||
df10_finish_op(df, 1<<df->nxmerr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (df->wcr == 0) {
|
||||
return df10_fetch(df);
|
||||
|
||||
@@ -423,7 +423,6 @@ t_stat dp_devio(uint32 dev, uint64 *data) {
|
||||
if (*data & BUSY) {
|
||||
/* Stop controller */
|
||||
sim_cancel(uptr);
|
||||
uptr->STATUS &= ~BUSY;
|
||||
df10_finish_op(df10, 0);
|
||||
}
|
||||
/* Clear flags */
|
||||
@@ -722,7 +721,7 @@ t_stat dp_svc (UNIT *uptr)
|
||||
CLR_BUF(uptr);
|
||||
}
|
||||
if (r)
|
||||
sim_activate(uptr, 25);
|
||||
sim_activate(uptr, 40);
|
||||
else {
|
||||
uptr->STATUS &= ~(SRC_DONE|END_CYL|BUSY);
|
||||
uptr->UFLAGS |= DONE;
|
||||
|
||||
@@ -1061,6 +1061,7 @@ dt_boot(int32 unit_num, DEVICE * dptr)
|
||||
addr = (addr + 1) & RMASK;
|
||||
word = ((uint64)fbuf[off++]) << 18;
|
||||
word |= (uint64)fbuf[off++];
|
||||
fprintf(stderr, "%06o %012llo %06o\n\r", addr, word, wc);
|
||||
if (addr < 020)
|
||||
FM[addr] = word;
|
||||
else
|
||||
@@ -1073,6 +1074,7 @@ dt_boot(int32 unit_num, DEVICE * dptr)
|
||||
uptr->DSTATE = (1 << DTC_V_BLK) | DTC_BLOCK | DTC_MOT;
|
||||
sim_activate(uptr,30000);
|
||||
PC = word & RMASK;
|
||||
fprintf(stderr, "%06o\n\r", PC);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -451,6 +451,7 @@ static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
static CONST in_addr_T broadcast_ipaddr = {0xffffffff};
|
||||
|
||||
t_stat imp_devio(uint32 dev, uint64 *data);
|
||||
t_addr imp_devirq(uint32 dev, t_addr addr);
|
||||
t_stat imp_srv(UNIT *);
|
||||
t_stat imp_eth_srv(UNIT *);
|
||||
t_stat imp_tim_srv(UNIT *);
|
||||
@@ -503,7 +504,13 @@ UNIT imp_unit[] = {
|
||||
{UDATA(imp_eth_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
|
||||
{UDATA(imp_tim_srv, UNIT_IDLE+UNIT_DIS, 0)}, /* 0 */
|
||||
};
|
||||
DIB imp_dib = {IMP_DEVNUM, 1, &imp_devio, NULL};
|
||||
DIB imp_dib = {IMP_DEVNUM, 1, &imp_devio,
|
||||
#if KL
|
||||
&imp_devirq,
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
MTAB imp_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MAC", "MAC=xx:xx:xx:xx:xx:xx",
|
||||
@@ -562,10 +569,13 @@ DEBTAB imp_debug[] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
REG imp_reg[] = {
|
||||
{BRDATA(DATA, &imp_data, 16, 8, sizeof(struct imp_device)), REG_HRO},
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE imp_dev = {
|
||||
"IMP", imp_unit, NULL, imp_mod,
|
||||
"IMP", imp_unit, imp_reg, imp_mod,
|
||||
3, 8, 0, 1, 8, 36,
|
||||
NULL, NULL, &imp_reset, NULL, &imp_attach, &imp_detach,
|
||||
&imp_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, imp_debug,
|
||||
@@ -635,6 +645,7 @@ t_stat imp_devio(uint32 dev, uint64 *data)
|
||||
uptr->STATUS |= IMPIHE;
|
||||
if (*data & IMPLHW) /* Last host word. */
|
||||
uptr->STATUS |= IMPLHW;
|
||||
check_interrupts(uptr);
|
||||
break;
|
||||
case TYPE_BBN:
|
||||
break;
|
||||
@@ -731,6 +742,20 @@ t_stat imp_devio(uint32 dev, uint64 *data)
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
#if KL
|
||||
/* Handle KL style interrupt vectors for ITS */
|
||||
t_addr
|
||||
imp_devirq(uint32 dev, t_addr addr) {
|
||||
if ((cpu_unit[0].flags & UNIT_ITSPAGE) != 0 && (imp_data.pia & 7) == 1) {
|
||||
if (imp_unit[0].STATUS & IMPID && (imp_unit[0].STATUS & IMPLW) == 0)
|
||||
return 070|RSIGN;
|
||||
if (imp_unit[0].STATUS & IMPOD)
|
||||
return 072|RSIGN;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
t_stat imp_srv(UNIT * uptr)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
|
||||
801
PDP10/kx10_rh.c
Normal file
801
PDP10/kx10_rh.c
Normal file
@@ -0,0 +1,801 @@
|
||||
/* kx10_rh.c: RH10/RH20 interace routines.
|
||||
|
||||
Copyright (c) 2015-2019, 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"
|
||||
|
||||
|
||||
/* CONI Flags */
|
||||
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */
|
||||
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */
|
||||
#define DIB_CBOV 0000000000200LL /* Control bus overrun */
|
||||
#define CXR_PS_FAIL 0000000002000LL /* Power supply fail (not implemented) */
|
||||
#define CXR_ILC 0000000004000LL /* Illegal function code */
|
||||
#define CR_DRE 0000000010000LL /* Or Data and Control Timeout */
|
||||
#define DTC_OVER 0000000020000LL /* DF10 did not supply word on time (not implemented) */
|
||||
#define CCW_COMP_1 0000000040000LL /* Control word written. */
|
||||
#define CXR_CHAN_ER 0000000100000LL /* Channel Error */
|
||||
#define CXR_EXC 0000000200000LL /* Error in drive transfer */
|
||||
#define CXR_DBPE 0000000400000LL /* Device Parity error (not implemented) */
|
||||
#define CXR_NXM 0000001000000LL /* Channel non-existent memory (not implemented) */
|
||||
#define CXR_CWPE 0000002000000LL /* Channel Control word parity error (not implemented) */
|
||||
#define CXR_CDPE 0000004000000LL /* Channel Data Parity Error (not implemented) */
|
||||
#define CXR_SD_RAE 0000200000000LL /* Register access error */
|
||||
#define CXR_ILFC 0000400000000LL /* Illegal CXR function code */
|
||||
#define B22_FLAG 0004000000000LL /* 22 bit channel */
|
||||
#define CC_CHAN_PLS 0010000000000LL /* Channel transfer pulse (not implemented) */
|
||||
#define CC_CHAN_ACT 0020000000000LL /* Channel in use */
|
||||
#define CC_INH 0040000000000LL /* Disconnect channel */
|
||||
#define CB_FULL 0200000000000LL /* Set when channel buffer is full (not implemented) */
|
||||
#define AR_FULL 0400000000000LL /* Set when AR is full (not implemented) */
|
||||
|
||||
/* RH20 CONI Flags */
|
||||
#define RH20_PCR_FULL 0000000000020LL /* Primary command file full */
|
||||
#define RH20_ATTN_ENA 0000000000040LL /* Attention enable */
|
||||
#define RH20_SCR_FULL 0000000000100LL /* Secondary command full */
|
||||
#define RH20_ATTN 0000000000200LL /* Attention */
|
||||
#define RH20_MASS_ENA 0000000000400LL /* Mass bus enable */
|
||||
#define RH20_DATA_OVR 0000000001000LL /* Data overrun */
|
||||
#define RH20_CHAN_RDY 0000000002000LL /* Channel ready to start */
|
||||
#define RH20_RAE 0000000004000LL /* Register access error */
|
||||
#define RH20_DR_RESP 0000000010000LL /* Drive no response */
|
||||
#define RH20_CHAN_ERR 0000000020000LL /* Channel error */
|
||||
#define RH20_SHRT_WC 0000000040000LL /* Short word count */
|
||||
#define RH20_LONG_WC 0000000100000LL /* Long word count */
|
||||
#define RH20_DR_EXC 0000000200000LL /* Exception */
|
||||
#define RH20_DATA_PRI 0000000400000LL /* Data parity error */
|
||||
#define RH20_SBAR 0000001000000LL /* SBAR set */
|
||||
#define RH20_XEND 0000002000000LL /* Transfer ended */
|
||||
|
||||
/* CONO Flags */
|
||||
#define ATTN_EN 0000000000040LL /* enable attention interrupt. */
|
||||
#define REA_EN 0000000000100LL /* enable register error interrupt */
|
||||
#define CBOV_CLR 0000000000200LL /* Clear CBOV */
|
||||
#define CONT_RESET 0000000002000LL /* Clear All error bits */
|
||||
#define ILC_CLR 0000000004000LL /* Clear ILC and SD RAE */
|
||||
#define DRE_CLR 0000000010000LL /* Clear CR_CBTO and CR_DBTO */
|
||||
#define OVER_CLR 0000000020000LL /* Clear DTC overrun */
|
||||
#define WRT_CW 0000000040000LL /* Write control word */
|
||||
#define CHN_CLR 0000000100000LL /* Clear Channel Error */
|
||||
#define DR_EXC_CLR 0000000200000LL /* Clear DR_EXC */
|
||||
#define DBPE_CLR 0000000400000LL /* Clear CXR_DBPE */
|
||||
|
||||
/* RH20 CONO Flags */
|
||||
#define RH20_DELETE_SCR 0000000000100LL /* Clear SCR */
|
||||
#define RH20_RCLP 0000000000200LL /* Reset command list */
|
||||
#define RH20_MASS_EN 0000000000400LL /* Mass bus enable */
|
||||
#define RH20_XFER_CLR 0000000001000LL /* Clear XFER error */
|
||||
#define RH20_CLR_MBC 0000000002000LL /* Clear MBC */
|
||||
#define RH20_CLR_RAE 0000000004000LL /* Clear RAE error */
|
||||
|
||||
/* DATAO/DATAI */
|
||||
#define CR_REG 0770000000000LL /* Register number */
|
||||
#define LOAD_REG 0004000000000LL /* Load register */
|
||||
#define CR_MAINT_MODE 0000100000000LL /* Maint mode... not implemented */
|
||||
#define CR_DRIVE 0000007000000LL
|
||||
#define CR_GEN_EVD 0000000400000LL /* Enable Parity */
|
||||
#define CR_DXES 0000000200000LL /* Disable DXES errors */
|
||||
#define CR_INAD 0000000077600LL
|
||||
#define CR_WTEVM 0000000000100LL /* Verify Parity */
|
||||
#define CR_FUNC 0000000000076LL
|
||||
#define CR_GO 0000000000001LL
|
||||
|
||||
#define IRQ_VECT 0000000000777LL /* Interupt vector */
|
||||
#define IRQ_KI10 0000002000000LL
|
||||
#define IRQ_KA10 0000001000000LL
|
||||
#define FNC_XFER 024 /* >=? data xfr */
|
||||
|
||||
/* Status register settings */
|
||||
#define DS_OFF 0000001 /* offset mode */
|
||||
#define DS_VV 0000100 /* volume valid */
|
||||
#define DS_DRY 0000200 /* drive ready */
|
||||
#define DS_DPR 0000400 /* drive present */
|
||||
#define DS_PGM 0001000 /* programable NI */
|
||||
#define DS_LST 0002000 /* last sector */
|
||||
#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 */
|
||||
|
||||
/* RH20 channel status flags */
|
||||
#define RH20_MEM_PAR 00200000000000LL /* Memory parity error */
|
||||
#define RH20_NADR_PAR 00100000000000LL /* Address parity error */
|
||||
#define RH20_NOT_WC0 00040000000000LL /* Word count not zero */
|
||||
#define RH20_NXM_ERR 00020000000000LL /* Non existent memory */
|
||||
#define RH20_LAST_ERR 00000400000000LL /* Last transfer error */
|
||||
#define RH20_ERROR 00000200000000LL /* RH20 error */
|
||||
#define RH20_LONG_STS 00000100000000LL /* Did not reach wc */
|
||||
#define RH20_SHRT_STS 00000040000000LL /* WC reached zero */
|
||||
#define RH20_OVER 00000020000000LL /* Overrun error */
|
||||
|
||||
/* 0-37 mass bus register.
|
||||
70 SBAR, block address.
|
||||
71 STCR, neg block count, func
|
||||
72 PBAR
|
||||
73 PTCR
|
||||
74 IVIR Interrupt vector address.
|
||||
75 Diags read.
|
||||
76 Diags write.
|
||||
77 Status (tra,cb test, bar test, ev par, r/w, exc,ebl, 0, attn, sclk
|
||||
*/
|
||||
|
||||
/*
|
||||
* CCW 000..... New channel comand list pointer HALT.
|
||||
010..... Next CCW Address JUMP
|
||||
1xycount-address. x=halt last xfer, y=reverse
|
||||
*/
|
||||
|
||||
extern uint32 eb_ptr;
|
||||
|
||||
t_stat
|
||||
rh_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
dptr->flags &= ~DEV_M_RH;
|
||||
dptr->flags |= val;
|
||||
dibp->dev_num &= ~(RH10_DEV|RH20_DEV);
|
||||
dibp->dev_num |= (val) ? RH20_DEV: RH10_DEV;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat rh_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf (st, "%s", (dptr->flags & TYPE_RH20) ? "RH20" : "RH10");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
t_stat rh_devio(uint32 dev, uint64 *data) {
|
||||
DEVICE *dptr = NULL;
|
||||
struct rh_if *rhc = NULL;
|
||||
int drive;
|
||||
|
||||
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
||||
if (rh[drive].dev_num == (dev & 0774)) {
|
||||
rhc = rh[drive].rh;
|
||||
dptr = rh[drive].dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rhc == NULL)
|
||||
return SCPE_OK;
|
||||
#if KL
|
||||
if (dptr->flags & TYPE_RH20) {
|
||||
switch(dev & 3) {
|
||||
case CONI:
|
||||
*data = rhc->status & RMASK;
|
||||
if (rhc->attn != 0)
|
||||
*data |= RH20_ATTN;
|
||||
if (rhc->rae != 0)
|
||||
*data |= RH20_RAE;
|
||||
sim_debug(DEBUG_CONI, dptr, "%s %03o CONI %06o PC=%o %o\n",
|
||||
dptr->name, dev, (uint32)*data, PC, rhc->attn);
|
||||
return SCPE_OK;
|
||||
|
||||
case CONO:
|
||||
clr_interrupt(dev);
|
||||
/* Clear flags */
|
||||
if (*data & RH20_CLR_MBC) {
|
||||
if (rhc->dev_reset != NULL)
|
||||
rhc->dev_reset(dptr);
|
||||
rhc->attn = 0;
|
||||
rhc->imode = 2;
|
||||
}
|
||||
rhc->status &= ~(07LL|IADR_ATTN|RH20_MASS_EN);
|
||||
rhc->status |= *data & (07LL|IADR_ATTN|RH20_MASS_EN);
|
||||
if (*data & RH20_DELETE_SCR)
|
||||
rhc->status &= ~(RH20_SBAR|RH20_SCR_FULL);
|
||||
if (*data & (RH20_RCLP|RH20_CLR_MBC))
|
||||
rhc->cia = eb_ptr | (rhc->devnum - 0540);
|
||||
if (*data & (RH20_CLR_RAE|RH20_CLR_MBC))
|
||||
rhc->rae = 0;
|
||||
if (*data & PI_ENABLE)
|
||||
rhc->status &= ~PI_ENABLE;
|
||||
if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|
||||
|| (rhc->status & PI_ENABLE))
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
sim_debug(DEBUG_CONO, dptr, "%s %03o CONO %06o PC=%06o %06o\n",
|
||||
dptr->name, dev, (uint32)*data, PC, rhc->status);
|
||||
return SCPE_OK;
|
||||
|
||||
case DATAI:
|
||||
*data = 0;
|
||||
if (rhc->status & BUSY && rhc->reg != 04) {
|
||||
rhc->status |= CC_CHAN_ACT;
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (rhc->reg < 040) {
|
||||
int parity;
|
||||
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777);
|
||||
parity = (int)((*data >> 8) ^ *data);
|
||||
parity = (parity >> 4) ^ parity;
|
||||
parity = (parity >> 2) ^ parity;
|
||||
parity = ((parity >> 1) ^ parity) & 1;
|
||||
*data |= ((uint64)(!parity)) << 16;
|
||||
*data |= ((uint64)(rhc->drive)) << 18;
|
||||
*data |= BIT10;
|
||||
} else if ((rhc->reg & 070) != 070) {
|
||||
rhc->rae = 1;
|
||||
break;
|
||||
} else {
|
||||
switch(rhc->reg & 07) {
|
||||
case 0: *data = rhc->sbar; break;
|
||||
case 1: *data = rhc->stcr; break;
|
||||
case 2: *data = rhc->pbar; break;
|
||||
case 3: *data = rhc->ptcr; break;
|
||||
case 4: *data = rhc->ivect; break;
|
||||
case 5:
|
||||
case 6: break;
|
||||
case 7: *data = 0; break;
|
||||
}
|
||||
}
|
||||
*data |= ((uint64)(rhc->reg)) << 30;
|
||||
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATI %012llo %d PC=%06o\n",
|
||||
dptr->name, dev, *data, rhc->drive, PC);
|
||||
return SCPE_OK;
|
||||
|
||||
case DATAO:
|
||||
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATO %012llo PC=%06o %06o\n",
|
||||
dptr->name, dev, *data, PC, rhc->status);
|
||||
rhc->reg = ((int)(*data >> 30)) & 077;
|
||||
rhc->imode |= 2;
|
||||
if (rhc->reg < 040)
|
||||
rhc->drive = (int)(*data >> 18) & 07;
|
||||
if (*data & LOAD_REG) {
|
||||
if (rhc->reg < 040) {
|
||||
clr_interrupt(dev);
|
||||
/* Check if access error */
|
||||
if (rhc->rae & (1 << rhc->drive) && (*data & BIT9) == 0) {
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
return SCPE_OK;
|
||||
}
|
||||
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||
if (((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|
||||
|| (rhc->status & PI_ENABLE))
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
/* Check if access error */
|
||||
if (rhc->rae & (1 << rhc->drive) && (*data & BIT9) == 0)
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
else
|
||||
rhc->rae &= ~(1 << rhc->drive);
|
||||
} else if ((rhc->reg & 070) != 070) {
|
||||
if ((*data & BIT9) == 0) {
|
||||
rhc->rae = (1 << rhc->drive);
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
}
|
||||
} else {
|
||||
switch(rhc->reg & 07) {
|
||||
case 0:
|
||||
rhc->sbar = (*data) & (CR_DRIVE|RMASK);
|
||||
rhc->status |= RH20_SBAR;
|
||||
break;
|
||||
case 1:
|
||||
rhc->stcr = (*data) & (BIT10|BIT7|CR_DRIVE|RMASK);
|
||||
rhc->status |= RH20_SCR_FULL;
|
||||
break;
|
||||
case 4:
|
||||
rhc->ivect = (*data & IRQ_VECT);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((rhc->status & (RH20_SCR_FULL|RH20_PCR_FULL)) == (RH20_SCR_FULL))
|
||||
rh20_setup(rhc);
|
||||
return SCPE_OK;
|
||||
}
|
||||
#endif
|
||||
switch(dev & 3) {
|
||||
case CONI:
|
||||
*data = rhc->status & ~(IADR_ATTN|IARD_RAE);
|
||||
if (rhc->attn != 0 && (rhc->status & IADR_ATTN))
|
||||
*data |= IADR_ATTN;
|
||||
if (rhc->rae != 0 && (rhc->status & IARD_RAE))
|
||||
*data |= IARD_RAE;
|
||||
#if KI_22BIT
|
||||
*data |= B22_FLAG;
|
||||
#endif
|
||||
sim_debug(DEBUG_CONI, dptr, "%s %03o CONI %06o PC=%o %o\n",
|
||||
dptr->name, dev, (uint32)*data, PC, rhc->attn);
|
||||
return SCPE_OK;
|
||||
|
||||
case CONO:
|
||||
clr_interrupt(dev);
|
||||
rhc->status &= ~(07LL|IADR_ATTN|IARD_RAE);
|
||||
rhc->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
|
||||
/* Clear flags */
|
||||
if (*data & CONT_RESET && rhc->dev_reset != NULL)
|
||||
rhc->dev_reset(dptr);
|
||||
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
|
||||
rhc->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
|
||||
if (*data & OVER_CLR)
|
||||
rhc->status &= ~(DTC_OVER);
|
||||
if (*data & CBOV_CLR)
|
||||
rhc->status &= ~(DIB_CBOV);
|
||||
if (*data & CXR_ILC)
|
||||
rhc->status &= ~(CXR_ILFC|CXR_SD_RAE);
|
||||
if (*data & WRT_CW)
|
||||
rh_writecw(rhc, 0);
|
||||
if (*data & PI_ENABLE)
|
||||
rhc->status &= ~PI_ENABLE;
|
||||
if (rhc->status & PI_ENABLE)
|
||||
set_interrupt(dev, rhc->status);
|
||||
if ((rhc->status & IADR_ATTN) != 0 && rhc->attn != 0)
|
||||
set_interrupt(dev, rhc->status);
|
||||
sim_debug(DEBUG_CONO, dptr, "%s %03o CONO %06o PC=%06o %06o\n",
|
||||
dptr->name, dev, (uint32)*data, PC, rhc->status);
|
||||
return SCPE_OK;
|
||||
|
||||
case DATAI:
|
||||
*data = 0;
|
||||
if (rhc->status & BUSY && rhc->reg != 04) {
|
||||
rhc->status |= CC_CHAN_ACT;
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (rhc->reg == 040) {
|
||||
*data = (uint64)(rhc->dev_read(dptr, rhc, 0) & 077);
|
||||
*data |= ((uint64)(rhc->cia)) << 6;
|
||||
*data |= ((uint64)(rhc->xfer_drive)) << 18;
|
||||
} else if (rhc->reg == 044) {
|
||||
*data = (uint64)rhc->ivect;
|
||||
if (rhc->imode)
|
||||
*data |= IRQ_KI10;
|
||||
else
|
||||
*data |= IRQ_KA10;
|
||||
} else if (rhc->reg == 054) {
|
||||
*data = (uint64)(rhc->rae);
|
||||
} else if ((rhc->reg & 040) == 0) {
|
||||
int parity;
|
||||
*data = (uint64)(rhc->dev_read(dptr, rhc, rhc->reg) & 0177777);
|
||||
parity = (int)((*data >> 8) ^ *data);
|
||||
parity = (parity >> 4) ^ parity;
|
||||
parity = (parity >> 2) ^ parity;
|
||||
parity = ((parity >> 1) ^ parity) & 1;
|
||||
*data |= ((uint64)(parity ^ 1)) << 17;
|
||||
*data |= ((uint64)(rhc->drive)) << 18;
|
||||
}
|
||||
*data |= ((uint64)(rhc->reg)) << 30;
|
||||
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATI %012llo %d PC=%06o\n",
|
||||
dptr->name, dev, *data, rhc->drive, PC);
|
||||
return SCPE_OK;
|
||||
|
||||
case DATAO:
|
||||
sim_debug(DEBUG_DATAIO, dptr, "%s %03o DATO %012llo PC=%06o %06o\n",
|
||||
dptr->name, dev, *data, PC, rhc->status);
|
||||
rhc->reg = ((int)(*data >> 30)) & 077;
|
||||
rhc->imode &= ~2;
|
||||
if (rhc->reg < 040 && rhc->reg != 04) {
|
||||
rhc->drive = (int)(*data >> 18) & 07;
|
||||
}
|
||||
if (*data & LOAD_REG) {
|
||||
if (rhc->reg == 040) {
|
||||
if ((*data & 1) == 0) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (rhc->status & BUSY) {
|
||||
rhc->status |= CC_CHAN_ACT;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
rhc->status &= ~(CCW_COMP_1|PI_ENABLE);
|
||||
if (((*data >> 1) & 037) < FNC_XFER) {
|
||||
rhc->status |= CXR_ILC;
|
||||
rh_setirq(rhc);
|
||||
sim_debug(DEBUG_DATAIO, dptr,
|
||||
"%s %03o command abort %012llo, %d PC=%06o %06o\n",
|
||||
dptr->name, dev, *data, rhc->drive, PC, rhc->status);
|
||||
return SCPE_OK;
|
||||
}
|
||||
/* Check if access error */
|
||||
if (rhc->rae & (1 << rhc->drive))
|
||||
return SCPE_OK;
|
||||
/* Start command */
|
||||
rh_setup(rhc, (uint32)(*data >> 6));
|
||||
rhc->xfer_drive = (int)(*data >> 18) & 07;
|
||||
rhc->dev_write(dptr, rhc, 0, (uint32)(*data & 077));
|
||||
sim_debug(DEBUG_DATAIO, dptr,
|
||||
"%s %03o command %012llo, %d PC=%06o %06o\n",
|
||||
dptr->name, dev, *data, rhc->drive, PC, rhc->status);
|
||||
} else if (rhc->reg == 044) {
|
||||
/* Set KI10 Irq vector */
|
||||
rhc->ivect = (int)(*data & IRQ_VECT);
|
||||
rhc->imode = (*data & IRQ_KI10) != 0;
|
||||
} else if (rhc->reg == 050) {
|
||||
; /* Diagnostic access to mass bus. */
|
||||
} else if (rhc->reg == 054) {
|
||||
/* clear flags */
|
||||
rhc->rae &= ~(*data & 0377);
|
||||
if (rhc->rae == 0)
|
||||
clr_interrupt(dev);
|
||||
} else if ((rhc->reg & 040) == 0) {
|
||||
rhc->drive = (int)(*data >> 18) & 07;
|
||||
/* Check if access error */
|
||||
if (rhc->rae & (1 << rhc->drive)) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
rhc->dev_write(dptr, rhc, rhc->reg & 037, (int)(*data & 0777777));
|
||||
}
|
||||
}
|
||||
clr_interrupt(dev);
|
||||
if (((rhc->status & (IADR_ATTN|BUSY)) == IADR_ATTN && rhc->attn != 0)
|
||||
|| (rhc->status & PI_ENABLE))
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK; /* Unreached */
|
||||
}
|
||||
|
||||
/* Handle KI and KL style interrupt vectors */
|
||||
t_addr
|
||||
rh_devirq(uint32 dev, t_addr addr) {
|
||||
DEVICE *dptr = NULL;
|
||||
struct rh_if *rhc = NULL;
|
||||
int drive;
|
||||
|
||||
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
||||
if (rh[drive].dev_num == (dev & 0774)) {
|
||||
rhc = rh[drive].rh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rhc != NULL) {
|
||||
if (rhc->imode == 1) /* KI10 Style */
|
||||
addr = RSIGN | rhc->ivect;
|
||||
else if (rhc->imode == 2) /* RH20 style */
|
||||
addr = rhc->ivect;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* Set the attention flag for a unit */
|
||||
void rh_setattn(struct rh_if *rhc, int unit)
|
||||
{
|
||||
rhc->attn |= 1<<unit;
|
||||
if ((rhc->status & BUSY) == 0 && (rhc->status & IADR_ATTN) != 0)
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
}
|
||||
|
||||
void rh_error(struct rh_if *rhc)
|
||||
{
|
||||
if (rhc->imode == 2)
|
||||
rhc->status |= RH20_DR_EXC;
|
||||
}
|
||||
|
||||
/* Decrement block count for RH20, nop for RH10 */
|
||||
int rh_blkend(struct rh_if *rhc)
|
||||
{
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
//fprintf(stderr, "RH blkend %o\n\r", rhc->cia);
|
||||
rhc->cia = (rhc->cia + 1) & 01777;
|
||||
if (rhc->cia == 0) {
|
||||
rhc->status |= RH20_XEND;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set an IRQ for a DF10 device */
|
||||
void rh_setirq(struct rh_if *rhc) {
|
||||
rhc->status |= PI_ENABLE;
|
||||
set_interrupt(rhc->devnum, rhc->status);
|
||||
}
|
||||
|
||||
/* Generate the DF10 complete word */
|
||||
void rh_writecw(struct rh_if *rhc, int nxm) {
|
||||
uint64 wrd1;
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
uint32 chan = (rhc->devnum - 0540);
|
||||
int wc = ((rhc->wcr ^ RH20_WMASK) + 1) & RH20_WMASK;
|
||||
rhc->status |= RH20_CHAN_RDY;
|
||||
rhc->status &= ~(RH20_PCR_FULL);
|
||||
if (wc != 0 || (rhc->status & RH20_XEND) == 0 ||
|
||||
(rhc->ptcr & BIT10) != 0 || nxm) {
|
||||
uint64 wrd2;
|
||||
wrd1 = SMASK|(uint64)(rhc->ccw);
|
||||
if ((rhc->ptcr & BIT10) == 0 || (rhc->status & RH20_DR_EXC) != 0)
|
||||
return;
|
||||
if (nxm) {
|
||||
wrd1 |= RH20_NXM_ERR;
|
||||
rhc->status |= RH20_CHAN_ERR;
|
||||
}
|
||||
if (wc != 0) {
|
||||
wrd1 |= RH20_NOT_WC0;
|
||||
if (rhc->status & RH20_XEND) {
|
||||
wrd1 |= RH20_LONG_STS;
|
||||
if ((rhc->ptcr & 070) == 060) { /* Write command */
|
||||
rhc->status |= RH20_LONG_WC|RH20_CHAN_ERR;
|
||||
}
|
||||
}
|
||||
} else if ((rhc->status & RH20_XEND) == 0) {
|
||||
wrd1 |= RH20_SHRT_STS;
|
||||
if ((rhc->ptcr & 070) == 060) { /* Write command */
|
||||
rhc->status |= RH20_SHRT_WC|RH20_CHAN_ERR;
|
||||
}
|
||||
}
|
||||
/* No error and not storing */
|
||||
if ((rhc->status & RH20_CHAN_ERR) == 0 && (rhc->ptcr & BIT10) == 0)
|
||||
return;
|
||||
wrd1 |= RH20_NADR_PAR;
|
||||
wrd2 = ((uint64)rhc->cop << 33) | (((uint64)wc) << CSHIFT) |
|
||||
((uint64)(rhc->cda) & AMASK);
|
||||
(void)Mem_write_word(chan+1, &wrd1, 1);
|
||||
(void)Mem_write_word(chan+2, &wrd2, 1);
|
||||
//fprintf(stderr, "RH20 final %012llo %012llo %06o\n\r", wrd1, wrd2, wc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (nxm)
|
||||
rhc->status |= CXR_NXM;
|
||||
rhc->status |= CCW_COMP_1;
|
||||
if (rhc->wcr != 0)
|
||||
rhc->cda++;
|
||||
wrd1 = ((uint64)(rhc->ccw & WMASK) << CSHIFT) | ((uint64)(rhc->cda) & AMASK);
|
||||
(void)Mem_write_word(rhc->cia|1, &wrd1, 0);
|
||||
}
|
||||
|
||||
/* Finish off a DF10 transfer */
|
||||
void rh_finish_op(struct rh_if *rhc, int nxm) {
|
||||
#if KL
|
||||
if (rhc->imode != 2)
|
||||
#endif
|
||||
rhc->status &= ~BUSY;
|
||||
rh_writecw(rhc, nxm);
|
||||
rh_setirq(rhc);
|
||||
#if KL
|
||||
if (rhc->imode == 2 &&
|
||||
(rhc->status & (RH20_SCR_FULL|RH20_PCR_FULL)) == (RH20_SCR_FULL) &&
|
||||
(rhc->status & (RH20_DR_EXC|RH20_CHAN_ERR)) == 0)
|
||||
rh20_setup(rhc);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if KL
|
||||
/* Set up for a RH20 transfer */
|
||||
void rh20_setup(struct rh_if *rhc)
|
||||
{
|
||||
DEVICE *dptr = NULL;
|
||||
int reg;
|
||||
|
||||
for (reg = 0; rh[reg].dev_num != 0; reg++) {
|
||||
if (rh[reg].rh == rhc) {
|
||||
dptr = rh[reg].dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dptr == 0)
|
||||
return;
|
||||
rhc->pbar = rhc->sbar;
|
||||
rhc->ptcr = rhc->stcr;
|
||||
/* Read drive status */
|
||||
rhc->drive = (rhc->ptcr >> 18) & 07;
|
||||
rhc->status &= ~(RH20_DATA_OVR|RH20_CHAN_RDY|RH20_DR_RESP|RH20_CHAN_ERR|RH20_SHRT_WC|\
|
||||
RH20_LONG_WC|RH20_DR_EXC|RH20_SCR_FULL|PI_ENABLE|RH20_XEND);
|
||||
rhc->status |= RH20_PCR_FULL;
|
||||
if (rhc->status & RH20_SBAR) {
|
||||
rhc->drive = (rhc->pbar >> 18) & 07;
|
||||
if (rhc->dev_write != NULL)
|
||||
rhc->dev_write(dptr, rhc, 5, (rhc->pbar & 0177777));
|
||||
rhc->status &= ~RH20_SBAR;
|
||||
}
|
||||
if (rhc->ptcr & BIT7) { /* If RCPL reset I/O pointers */
|
||||
rhc->ccw = eb_ptr + (rhc->devnum - 0540);
|
||||
rhc->wcr = 0;
|
||||
}
|
||||
/* Hold block count in cia */
|
||||
rhc->drive = (rhc->ptcr >> 18) & 07;
|
||||
rhc->cia = (rhc->ptcr >> 6) & 01777;
|
||||
if (rhc->dev_write != NULL)
|
||||
rhc->dev_write(dptr, rhc, 0, (rhc->ptcr & 077));
|
||||
rhc->cop = 0;
|
||||
rhc->wcr = 0;
|
||||
rhc->status &= ~RH20_CHAN_RDY;
|
||||
//fprintf(stderr, "RH setup %06o %06o %o\n\r", rhc->ptcr, rhc->ccw, rhc->cia);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Setup for a DF10 transfer */
|
||||
void rh_setup(struct rh_if *rhc, uint32 addr)
|
||||
{
|
||||
rhc->cia = addr & ICWA;
|
||||
rhc->ccw = rhc->cia;
|
||||
rhc->wcr = 0;
|
||||
rhc->status |= BUSY;
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the next IO control word */
|
||||
int rh_fetch(struct rh_if *rhc) {
|
||||
uint64 data;
|
||||
int reg;
|
||||
DEVICE *dptr = NULL;
|
||||
|
||||
for (reg = 0; rh[reg].dev_num != 0; reg++) {
|
||||
if (rh[reg].rh == rhc) {
|
||||
dptr = rh[reg].dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if KL
|
||||
if (rhc->imode == 2 && (rhc->cop & 2) != 0) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (Mem_read_word(rhc->ccw, &data, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
sim_debug(DEBUG_EXP, dptr, "%s fetch %06o %012llo\n\r", dptr->name, rhc->ccw, data);
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
while((data & RH20_XFER) == 0) {
|
||||
rhc->ccw = (uint32)(data & AMASK);
|
||||
if ((data & (BIT1|BIT2)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (Mem_read_word(rhc->ccw, &data, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
sim_debug(DEBUG_EXP, dptr, "%s fetch2 %06o %012llo\n\r", dptr->name, rhc->ccw, data);
|
||||
//fprintf(stderr, "RH20 fetch2 %06o %012llo\n\r", rhc->ccw, data);
|
||||
}
|
||||
rhc->wcr = (((data >> CSHIFT) & RH20_WMASK) ^ WMASK) + 1;
|
||||
rhc->cda = (data & AMASK);
|
||||
rhc->cop = (data >> 33) & 07;
|
||||
rhc->ccw = (uint32)((rhc->ccw + 1) & AMASK);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
while((data & (WMASK << CSHIFT)) == 0) {
|
||||
if ((data & AMASK) == 0 || (uint32)(data & AMASK) == rhc->ccw) {
|
||||
rh_finish_op(rhc, 0);
|
||||
return 0;
|
||||
}
|
||||
rhc->ccw = (uint32)(data & AMASK);
|
||||
if (Mem_read_word(rhc->ccw, &data, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
sim_debug(DEBUG_EXP, dptr, "%s fetch2 %06o %012llo\n\r", dptr->name, rhc->ccw, data);
|
||||
}
|
||||
rhc->wcr = (uint32)((data >> CSHIFT) & WMASK);
|
||||
rhc->cda = (uint32)(data & AMASK);
|
||||
rhc->ccw = (uint32)((rhc->ccw + 1) & AMASK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read next word */
|
||||
int rh_read(struct rh_if *rhc) {
|
||||
uint64 data;
|
||||
if (rhc->wcr == 0) {
|
||||
if (!rh_fetch(rhc))
|
||||
return 0;
|
||||
}
|
||||
rhc->wcr = (uint32)((rhc->wcr + 1) & WMASK);
|
||||
if (rhc->cda != 0) {
|
||||
if (rhc->cda > MEMSIZE) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
if (Mem_read_word(rhc->cda, &data, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
if (rhc->cop & 01)
|
||||
rhc->cda = (uint32)((rhc->cda - 1) & AMASK);
|
||||
else
|
||||
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||
} else {
|
||||
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||
if (Mem_read_word(rhc->cda, &data, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||
if (Mem_read_word(rhc->cda, &data, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
data = 0;
|
||||
}
|
||||
rhc->buf = data;
|
||||
if (rhc->wcr == 0) {
|
||||
return rh_fetch(rhc);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Write next word */
|
||||
int rh_write(struct rh_if *rhc) {
|
||||
if (rhc->wcr == 0) {
|
||||
if (!rh_fetch(rhc))
|
||||
return 0;
|
||||
}
|
||||
rhc->wcr = (uint32)((rhc->wcr + 1) & WMASK);
|
||||
if (rhc->cda != 0) {
|
||||
if (rhc->cda > MEMSIZE) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
#if KL
|
||||
if (rhc->imode == 2) {
|
||||
if (Mem_write_word(rhc->cda, &rhc->buf, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
if (rhc->cop & 01)
|
||||
rhc->cda = (uint32)((rhc->cda - 1) & AMASK);
|
||||
else
|
||||
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||
} else {
|
||||
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||
if (Mem_write_word(rhc->cda, &rhc->buf, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
rhc->cda = (uint32)((rhc->cda + 1) & AMASK);
|
||||
if (Mem_write_word(rhc->cda, &rhc->buf, 0)) {
|
||||
rh_finish_op(rhc, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (rhc->wcr == 0) {
|
||||
return rh_fetch(rhc);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
742
PDP10/kx10_rp.c
742
PDP10/kx10_rp.c
File diff suppressed because it is too large
Load Diff
530
PDP10/kx10_rs.c
530
PDP10/kx10_rs.c
@@ -1,6 +1,6 @@
|
||||
/* ka10_rs.c: Dec RH10 RS04
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2019, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -28,6 +28,8 @@
|
||||
#endif
|
||||
|
||||
#if (NUM_DEVS_RS > 0)
|
||||
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
|
||||
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
|
||||
|
||||
#define RS_NUMWD 128 /* 36bit words/sec */
|
||||
#define NUM_UNITS_RS 8
|
||||
@@ -42,72 +44,14 @@
|
||||
#define DTYPE(x) (((x) & UNIT_M_DTYPE) << UNIT_V_DTYPE)
|
||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
||||
#define CNTRL_V_CTYPE (UNIT_V_UF + 4)
|
||||
#define CNTRL_M_CTYPE 7
|
||||
#define GET_CNTRL(x) (((x) >> CNTRL_V_CTYPE) & CNTRL_M_CTYPE)
|
||||
#define CNTRL(x) (((x) & CNTRL_M_CTYPE) << CNTRL_V_CTYPE)
|
||||
|
||||
/* Parameters in the unit descriptor */
|
||||
|
||||
|
||||
/* CONI Flags */
|
||||
#define IADR_ATTN 0000000000040LL /* Interrupt on attention */
|
||||
#define IARD_RAE 0000000000100LL /* Interrupt on register access error */
|
||||
#define DIB_CBOV 0000000000200LL /* Control bus overrun */
|
||||
#define CXR_PS_FAIL 0000000002000LL /* Power supply fail (not implemented) */
|
||||
#define CXR_ILC 0000000004000LL /* Illegal function code */
|
||||
#define CR_DRE 0000000010000LL /* Or Data and Control Timeout */
|
||||
#define DTC_OVER 0000000020000LL /* DF10 did not supply word on time (not implemented) */
|
||||
#define CCW_COMP_1 0000000040000LL /* Control word written. */
|
||||
#define CXR_CHAN_ER 0000000100000LL /* Channel Error */
|
||||
#define CXR_EXC 0000000200000LL /* Error in drive transfer */
|
||||
#define CXR_DBPE 0000000400000LL /* Device Parity error (not implemented) */
|
||||
#define CXR_NXM 0000001000000LL /* Channel non-existent memory (not implemented) */
|
||||
#define CXR_CWPE 0000002000000LL /* Channel Control word parity error (not implemented) */
|
||||
#define CXR_CDPE 0000004000000LL /* Channel Data Parity Error (not implemented) */
|
||||
#define CXR_SD_RAE 0000200000000LL /* Register access error */
|
||||
#define CXR_ILFC 0000400000000LL /* Illegal CXR function code */
|
||||
#define B22_FLAG 0004000000000LL /* 22 bit channel */
|
||||
#define CC_CHAN_PLS 0010000000000LL /* Channel transfer pulse (not implemented) */
|
||||
#define CC_CHAN_ACT 0020000000000LL /* Channel in use */
|
||||
#define CC_INH 0040000000000LL /* Disconnect channel */
|
||||
#define CB_FULL 0200000000000LL /* Set when channel buffer is full (not implemented) */
|
||||
#define AR_FULL 0400000000000LL /* Set when AR is full (not implemented) */
|
||||
|
||||
/* CONO Flags */
|
||||
#define ATTN_EN 0000000000040LL /* enable attention interrupt. */
|
||||
#define REA_EN 0000000000100LL /* enable register error interrupt */
|
||||
#define CBOV_CLR 0000000000200LL /* Clear CBOV */
|
||||
#define CONT_RESET 0000000002000LL /* Clear All error bits */
|
||||
#define ILC_CLR 0000000004000LL /* Clear ILC and SD RAE */
|
||||
#define DRE_CLR 0000000010000LL /* Clear CR_CBTO and CR_DBTO */
|
||||
#define OVER_CLR 0000000020000LL /* Clear DTC overrun */
|
||||
#define WRT_CW 0000000040000LL /* Write control word */
|
||||
#define CHN_CLR 0000000100000LL /* Clear Channel Error */
|
||||
#define DR_EXC_CLR 0000000200000LL /* Clear DR_EXC */
|
||||
#define DBPE_CLR 0000000400000LL /* Clear CXR_DBPE */
|
||||
|
||||
/* DATAO/DATAI */
|
||||
#define CR_REG 0770000000000LL /* Register number */
|
||||
#define LOAD_REG 0004000000000LL /* Load register */
|
||||
#define CR_MAINT_MODE 0000100000000LL /* Maint mode... not implemented */
|
||||
#define CR_DRIVE 0000007000000LL
|
||||
#define CR_GEN_EVD 0000000400000LL /* Enable Parity */
|
||||
#define CR_DXES 0000000200000LL /* Disable DXES errors */
|
||||
#define CR_INAD 0000000077600LL
|
||||
#define CR_WTEVM 0000000000100LL /* Verify Parity */
|
||||
#define CR_FUNC 0000000000076LL
|
||||
#define CR_GO 0000000000001LL
|
||||
|
||||
#define IRQ_VECT 0000000000177LL /* Interupt vector */
|
||||
#define IRQ_KI10 0000002000000LL
|
||||
#define IRQ_KA10 0000001000000LL
|
||||
|
||||
#define CMD u3
|
||||
/* u3 low */
|
||||
/* RSC - 00 - control */
|
||||
|
||||
#define CS1_GO CR_GO /* go */
|
||||
#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)
|
||||
@@ -228,21 +172,10 @@ struct drvtyp rs_drv_tab[] = {
|
||||
};
|
||||
|
||||
|
||||
struct df10 rs_df10[NUM_DEVS_RS];
|
||||
uint32 rs_xfer_drive[NUM_DEVS_RS];
|
||||
uint64 rs_buf[NUM_DEVS_RS][RS_NUMWD];
|
||||
int rs_reg[NUM_DEVS_RS];
|
||||
int rs_ivect[NUM_DEVS_RS];
|
||||
int rs_imode[NUM_DEVS_RS];
|
||||
int rs_drive[NUM_DEVS_RS];
|
||||
int rs_rae[NUM_DEVS_RS];
|
||||
int rs_attn[NUM_DEVS_RS];
|
||||
extern int readin_flag;
|
||||
|
||||
t_stat rs_devio(uint32 dev, uint64 *data);
|
||||
int rs_devirq(uint32 dev, int addr);
|
||||
void rs_write(int ctlr, int unit, int reg, uint32 data);
|
||||
uint32 rs_read(int ctlr, int unit, int reg);
|
||||
void rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data);
|
||||
uint32 rs_read(DEVICE *dptr, struct rh_if *rhc, int reg);
|
||||
void rs_rst(DEVICE *dptr);
|
||||
t_stat rs_svc(UNIT *);
|
||||
t_stat rs_boot(int32, DEVICE *);
|
||||
void rs_ini(UNIT *, t_bool);
|
||||
@@ -258,28 +191,38 @@ const char *rs_description (DEVICE *dptr);
|
||||
UNIT rs_unit[] = {
|
||||
/* Controller 1 */
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
{ UDATA (&rs_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL(0), RS04_SIZE) },
|
||||
UNIT_ROABLE+DTYPE(RS04_DTYPE)+CNTRL_RH(0), RS04_SIZE) },
|
||||
};
|
||||
|
||||
struct rh_if rs_rh[] = {
|
||||
{ &rs_write, &rs_read, &rs_rst},
|
||||
};
|
||||
|
||||
DIB rs_dib[] = {
|
||||
{RH10_DEV, 1, &rs_devio, &rs_devirq}
|
||||
{RH10_DEV, 1, &rh_devio, &rh_devirq, &rs_rh[0]}
|
||||
};
|
||||
|
||||
MTAB rs_mod[] = {
|
||||
#if KL
|
||||
{MTAB_XTD|MTAB_VDV, TYPE_RH10, NULL, "RH10", &rh_set_type, NULL,
|
||||
NULL, "Sets controller to RH10" },
|
||||
{MTAB_XTD|MTAB_VDV, TYPE_RH20, "RH20", "RH20", &rh_set_type, &rh_show_type,
|
||||
NULL, "Sets controller to RH20"},
|
||||
#endif
|
||||
{UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL},
|
||||
{UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL},
|
||||
{UNIT_DTYPE, (RS03_DTYPE << UNIT_V_DTYPE), "RS03", "RS03", &rs_set_type },
|
||||
@@ -288,23 +231,20 @@ MTAB rs_mod[] = {
|
||||
};
|
||||
|
||||
REG rsa_reg[] = {
|
||||
{ORDATA(IVECT, rs_ivect[0], 18)},
|
||||
{FLDATA(IMODE, rs_imode[0], 0)},
|
||||
{ORDATA(XFER, rs_xfer_drive[0], 3), REG_HRO},
|
||||
{ORDATA(DRIVE, rs_drive[0], 3), REG_HRO},
|
||||
{ORDATA(REG, rs_reg[0], 6), REG_RO},
|
||||
{ORDATA(RAE, rs_rae[0], 8), REG_RO},
|
||||
{ORDATA(ATTN, rs_attn[0], 8), REG_RO},
|
||||
{FLDATA(READIN, readin_flag, 0), REG_HRO},
|
||||
{ORDATA(STATUS, rs_df10[0].status, 18), REG_RO},
|
||||
{ORDATA(CIA, rs_df10[0].cia, 18)},
|
||||
{ORDATA(CCW, rs_df10[0].ccw, 18)},
|
||||
{ORDATA(WCR, rs_df10[0].wcr, 18)},
|
||||
{ORDATA(CDA, rs_df10[0].cda, 18)},
|
||||
{ORDATA(DEVNUM, rs_df10[0].devnum, 9), REG_HRO},
|
||||
{ORDATA(BUF, rs_df10[0].buf, 36), REG_HRO},
|
||||
{ORDATA(NXM, rs_df10[0].nxmerr, 8), REG_HRO},
|
||||
{ORDATA(COMP, rs_df10[0].ccw_comp, 8), REG_HRO},
|
||||
{ORDATA(IVECT, rs_rh[0].ivect, 18)},
|
||||
{FLDATA(IMODE, rs_rh[0].imode, 0)},
|
||||
{ORDATA(XFER, rs_rh[0].xfer_drive, 3), REG_HRO},
|
||||
{ORDATA(DRIVE, rs_rh[0].drive, 3), REG_HRO},
|
||||
{ORDATA(REG, rs_rh[0].reg, 6), REG_RO},
|
||||
{ORDATA(RAE, rs_rh[0].rae, 8), REG_RO},
|
||||
{ORDATA(ATTN, rs_rh[0].attn, 8), REG_RO},
|
||||
{ORDATA(STATUS, rs_rh[0].status, 18), REG_RO},
|
||||
{ORDATA(CIA, rs_rh[0].cia, 18)},
|
||||
{ORDATA(CCW, rs_rh[0].ccw, 18)},
|
||||
{ORDATA(WCR, rs_rh[0].wcr, 18)},
|
||||
{ORDATA(CDA, rs_rh[0].cda, 18)},
|
||||
{ORDATA(DEVNUM, rs_rh[0].devnum, 9), REG_HRO},
|
||||
{ORDATA(BUF, rs_rh[0].buf, 36), REG_HRO},
|
||||
{BRDATA(BUFF, &rs_buf[0][0], 16, 64, RS_NUMWD), REG_HRO},
|
||||
{0}
|
||||
};
|
||||
@@ -322,213 +262,44 @@ DEVICE *rs_devs[] = {
|
||||
};
|
||||
|
||||
|
||||
t_stat rs_devio(uint32 dev, uint64 *data) {
|
||||
int ctlr = -1;
|
||||
DEVICE *dptr = NULL;
|
||||
struct df10 *df10;
|
||||
int drive;
|
||||
|
||||
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
||||
if (rh[drive].dev_num == (dev & 0774)) {
|
||||
dptr = rh[drive].dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dptr == NULL)
|
||||
return SCPE_OK;
|
||||
ctlr = GET_CNTRL(dptr->units[0].flags);
|
||||
df10 = &rs_df10[ctlr];
|
||||
df10->devnum = dev;
|
||||
switch(dev & 3) {
|
||||
case CONI:
|
||||
*data = df10->status & ~(IADR_ATTN|IARD_RAE);
|
||||
if (rs_attn[ctlr] != 0 && (df10->status & IADR_ATTN))
|
||||
*data |= IADR_ATTN;
|
||||
if (rs_rae[ctlr] != 0 && (df10->status & IARD_RAE))
|
||||
*data |= IARD_RAE;
|
||||
#if KI_22BIT
|
||||
*data |= B22_FLAG;
|
||||
#endif
|
||||
sim_debug(DEBUG_CONI, dptr, "RS %03o CONI %06o PC=%o %o\n",
|
||||
dev, (uint32)*data, PC, rs_attn[ctlr]);
|
||||
return SCPE_OK;
|
||||
|
||||
case CONO:
|
||||
clr_interrupt(dev);
|
||||
df10->status &= ~(07LL|IADR_ATTN|IARD_RAE);
|
||||
df10->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
|
||||
/* Clear flags */
|
||||
if (*data & CONT_RESET) {
|
||||
UNIT *uptr=dptr->units;
|
||||
for(drive = 0; drive < NUM_UNITS_RS; drive++, uptr++) {
|
||||
uptr->CMD &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076;
|
||||
uptr->DA &= 003400177777;
|
||||
}
|
||||
}
|
||||
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
|
||||
df10->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
|
||||
if (*data & OVER_CLR)
|
||||
df10->status &= ~(DTC_OVER);
|
||||
if (*data & CBOV_CLR)
|
||||
df10->status &= ~(DIB_CBOV);
|
||||
if (*data & CXR_ILC)
|
||||
df10->status &= ~(CXR_ILFC|CXR_SD_RAE);
|
||||
if (*data & WRT_CW)
|
||||
df10_writecw(df10);
|
||||
if (*data & PI_ENABLE)
|
||||
df10->status &= ~PI_ENABLE;
|
||||
if (df10->status & PI_ENABLE)
|
||||
set_interrupt(dev, df10->status);
|
||||
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
|
||||
set_interrupt(dev, df10->status);
|
||||
sim_debug(DEBUG_CONO, dptr, "RS %03o CONO %06o %d PC=%06o %06o\n",
|
||||
dev, (uint32)*data, ctlr, PC, df10->status);
|
||||
return SCPE_OK;
|
||||
|
||||
case DATAI:
|
||||
*data = 0;
|
||||
if (df10->status & BUSY && rs_reg[ctlr] != 04) {
|
||||
df10->status |= CC_CHAN_ACT;
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (rs_reg[ctlr] == 040) {
|
||||
*data = (uint64)(rs_read(ctlr, rs_drive[ctlr], 0) & 077);
|
||||
*data |= ((uint64)(df10->cia)) << 6;
|
||||
*data |= ((uint64)(rs_xfer_drive[ctlr])) << 18;
|
||||
} else if (rs_reg[ctlr] == 044) {
|
||||
*data = (uint64)rs_ivect[ctlr];
|
||||
if (rs_imode[ctlr])
|
||||
*data |= IRQ_KI10;
|
||||
else
|
||||
*data |= IRQ_KA10;
|
||||
} else if (rs_reg[ctlr] == 054) {
|
||||
*data = (uint64)(rs_rae[ctlr]);
|
||||
} else if ((rs_reg[ctlr] & 040) == 0) {
|
||||
int parity;
|
||||
|
||||
*data = (uint64)(rs_read(ctlr, rs_drive[ctlr], rs_reg[ctlr]) & 0177777);
|
||||
parity = (int)((*data >> 8) ^ *data);
|
||||
parity = (parity >> 4) ^ parity;
|
||||
parity = (parity >> 2) ^ parity;
|
||||
parity = ((parity >> 1) ^ parity) & 1;
|
||||
*data |= ((uint64)(parity ^ 1)) << 17;
|
||||
*data |= ((uint64)(rs_drive[ctlr])) << 18;
|
||||
}
|
||||
*data |= ((uint64)(rs_reg[ctlr])) << 30;
|
||||
sim_debug(DEBUG_DATAIO, dptr, "RS %03o DATI %012llo, %d %d PC=%06o\n",
|
||||
dev, *data, ctlr, rs_drive[ctlr], PC);
|
||||
return SCPE_OK;
|
||||
|
||||
case DATAO:
|
||||
sim_debug(DEBUG_DATAIO, dptr, "RS %03o DATO %012llo, %d PC=%06o %06o\n",
|
||||
dev, *data, ctlr, PC, df10->status);
|
||||
rs_reg[ctlr] = ((int)(*data >> 30)) & 077;
|
||||
if (rs_reg[ctlr] < 040 && rs_reg[ctlr] != 04) {
|
||||
rs_drive[ctlr] = (int)(*data >> 18) & 07;
|
||||
}
|
||||
if (*data & LOAD_REG) {
|
||||
if (rs_reg[ctlr] == 040) {
|
||||
if ((*data & 1) == 0) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (df10->status & BUSY) {
|
||||
df10->status |= CC_CHAN_ACT;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
df10->status &= ~(1 << df10->ccw_comp);
|
||||
df10->status &= ~PI_ENABLE;
|
||||
if (((*data >> 1) & 077) < FNC_XFER) {
|
||||
df10->status |= CXR_ILC;
|
||||
df10_setirq(df10);
|
||||
sim_debug(DEBUG_DATAIO, dptr,
|
||||
"RS %03o command abort %012llo, %d[%d] PC=%06o %06o\n",
|
||||
dev, *data, ctlr, rs_drive[ctlr], PC, df10->status);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Start command */
|
||||
df10_setup(df10, (uint32)(*data >> 6));
|
||||
rs_xfer_drive[ctlr] = (int)(*data >> 18) & 07;
|
||||
rs_write(ctlr, rs_drive[ctlr], 0, (uint32)(*data & 077));
|
||||
sim_debug(DEBUG_DATAIO, dptr,
|
||||
"RS %03o command %012llo, %d[%d] PC=%06o %06o\n",
|
||||
dev, *data, ctlr, rs_drive[ctlr], PC, df10->status);
|
||||
} else if (rs_reg[ctlr] == 044) {
|
||||
/* Set KI10 Irq vector */
|
||||
rs_ivect[ctlr] = (int)(*data & IRQ_VECT);
|
||||
rs_imode[ctlr] = (*data & IRQ_KI10) != 0;
|
||||
} else if (rs_reg[ctlr] == 050) {
|
||||
; /* Diagnostic access to mass bus. */
|
||||
} else if (rs_reg[ctlr] == 054) {
|
||||
/* clear flags */
|
||||
rs_rae[ctlr] &= ~(*data & 0377);
|
||||
if (rs_rae[ctlr] == 0)
|
||||
clr_interrupt(dev);
|
||||
} else if ((rs_reg[ctlr] & 040) == 0) {
|
||||
rs_drive[ctlr] = (int)(*data >> 18) & 07;
|
||||
/* Check if access error */
|
||||
if (rs_rae[ctlr] & (1 << rs_drive[ctlr])) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
rs_drive[ctlr] = (int)(*data >> 18) & 07;
|
||||
rs_write(ctlr, rs_drive[ctlr], rs_reg[ctlr] & 037,
|
||||
(int)(*data & 0777777));
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK; /* Unreached */
|
||||
}
|
||||
|
||||
/* Handle KI and KL style interrupt vectors */
|
||||
int
|
||||
rs_devirq(uint32 dev, int addr) {
|
||||
DEVICE *dptr = NULL;
|
||||
int drive;
|
||||
|
||||
for (drive = 0; rh[drive].dev_num != 0; drive++) {
|
||||
if (rh[drive].dev_num == (dev & 0774)) {
|
||||
dptr = rh[drive].dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dptr != NULL) {
|
||||
drive = GET_CNTRL(dptr->units[0].flags);
|
||||
return (rs_imode[drive] ? rs_ivect[drive] : addr);
|
||||
}
|
||||
return addr;
|
||||
void
|
||||
rs_rst(DEVICE *dptr)
|
||||
{
|
||||
UNIT *uptr=dptr->units;
|
||||
int drive;
|
||||
for(drive = 0; drive < NUM_UNITS_RS; drive++, uptr++) {
|
||||
uptr->CMD &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076;
|
||||
uptr->DA &= 003400177777;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||
rs_write(DEVICE *dptr, struct rh_if *rhc, int reg, uint32 data) {
|
||||
int i;
|
||||
DEVICE *dptr = rs_devs[ctlr];
|
||||
struct df10 *df10 = &rs_df10[ctlr];
|
||||
int unit = rhc->drive;
|
||||
UNIT *uptr = &dptr->units[unit];
|
||||
|
||||
if ((uptr->CMD & CR_GO) && reg != 04) {
|
||||
if ((uptr->CMD & CS1_GO) && reg != 04) {
|
||||
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
|
||||
return;
|
||||
}
|
||||
switch(reg) {
|
||||
case 000: /* control */
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d Status=%06o\n", unit, ctlr, uptr->CMD);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o Status=%06o\n", dptr->name, unit, uptr->CMD);
|
||||
/* Set if drive not writable */
|
||||
if (uptr->flags & UNIT_WLK)
|
||||
uptr->CMD |= DS_WRL;
|
||||
/* If drive not ready don't do anything */
|
||||
if ((uptr->CMD & DS_DRY) == 0) {
|
||||
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d busy\n", unit, ctlr);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o busy\n", dptr->name, unit);
|
||||
return;
|
||||
}
|
||||
/* Check if GO bit set */
|
||||
if ((data & 1) == 0) {
|
||||
uptr->CMD &= ~076;
|
||||
uptr->CMD |= data & 076;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d no go\n", unit, ctlr);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o no go\n", dptr->name, unit);
|
||||
return; /* No, nop */
|
||||
}
|
||||
uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
|
||||
@@ -542,7 +313,8 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||
case FNC_WCHK: /* write check */
|
||||
case FNC_WRITE: /* write */
|
||||
case FNC_READ: /* read */
|
||||
uptr->CMD |= DS_PIP|CR_GO;
|
||||
uptr->CMD |= DS_PIP|CS1_GO;
|
||||
CLR_BUF(uptr);
|
||||
uptr->DATAPTR = 0;
|
||||
break;
|
||||
|
||||
@@ -551,30 +323,26 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||
if ((uptr->flags & UNIT_ATT) != 0)
|
||||
uptr->CMD |= DS_VV;
|
||||
uptr->CMD |= DS_DRY;
|
||||
df10_setirq(df10);
|
||||
rh_setirq(rhc);
|
||||
break;
|
||||
|
||||
case FNC_DCLR: /* drive clear */
|
||||
uptr->CMD |= DS_DRY;
|
||||
uptr->CMD &= ~(DS_ATA|CR_GO);
|
||||
rs_attn[ctlr] = 0;
|
||||
clr_interrupt(df10->devnum);
|
||||
uptr->CMD &= ~(DS_ATA|CS1_GO);
|
||||
rhc->attn = 0;
|
||||
clr_interrupt(rhc->devnum);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (rs_unit[(ctlr * 8) + i].CMD & DS_ATA)
|
||||
rs_attn[ctlr] = 1;
|
||||
if (dptr->units[i].CMD & DS_ATA)
|
||||
rhc->attn |= 1 << i;
|
||||
}
|
||||
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
|
||||
df10_setirq(df10);
|
||||
break;
|
||||
default:
|
||||
uptr->CMD |= DS_DRY|DS_ERR|DS_ATA;
|
||||
uptr->CMD |= (ER1_ILF << 16);
|
||||
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
|
||||
df10_setirq(df10);
|
||||
}
|
||||
if (uptr->CMD & CR_GO)
|
||||
if (uptr->CMD & CS1_GO)
|
||||
sim_activate(uptr, 100);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o AStatus=%06o\n", unit, uptr->CMD);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o AStatus=%06o\n", dptr->name, unit, uptr->CMD);
|
||||
return;
|
||||
case 001: /* status */
|
||||
break;
|
||||
@@ -587,17 +355,13 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||
case 003: /* maintenance */
|
||||
break;
|
||||
case 004: /* atten summary */
|
||||
rs_attn[ctlr] = 0;
|
||||
rhc->attn = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (data & (1<<i))
|
||||
rs_unit[(ctlr * 8) + i].CMD &= ~DS_ATA;
|
||||
if (rs_unit[(ctlr * 8) + i].CMD & DS_ATA)
|
||||
rs_attn[ctlr] = 1;
|
||||
dptr->units[i].CMD &= ~DS_ATA;
|
||||
if (dptr->units[i].CMD & DS_ATA)
|
||||
rhc->attn |= 1 << i;
|
||||
}
|
||||
clr_interrupt(df10->devnum);
|
||||
if (((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0) ||
|
||||
(df10->status & PI_ENABLE))
|
||||
df10_setirq(df10);
|
||||
break;
|
||||
case 005: /* sector/track */
|
||||
uptr->DA = data & 0177777;
|
||||
@@ -607,14 +371,13 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
|
||||
break;
|
||||
default:
|
||||
uptr->CMD |= (ER1_ILR<<16)|DS_ERR;
|
||||
rs_rae[ctlr] &= ~(1<<unit);
|
||||
rhc->rae |= 1 << unit;
|
||||
}
|
||||
}
|
||||
|
||||
uint32
|
||||
rs_read(int ctlr, int unit, int reg) {
|
||||
DEVICE *dptr = rs_devs[ctlr];
|
||||
struct df10 *df10 = &rs_df10[ctlr];
|
||||
rs_read(DEVICE *dptr, struct rh_if *rhc, int reg) {
|
||||
int unit = rhc->drive;
|
||||
UNIT *uptr = &dptr->units[unit];
|
||||
uint32 temp = 0;
|
||||
int i;
|
||||
@@ -628,7 +391,7 @@ rs_read(int ctlr, int unit, int reg) {
|
||||
temp = uptr->CMD & 077;
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
temp |= CS1_DVA;
|
||||
if ((df10->status & BUSY) == 0 && (uptr->CMD & CR_GO) == 0)
|
||||
if ((uptr->CMD & CS1_GO) == 0)
|
||||
temp |= CS1_GO;
|
||||
break;
|
||||
case 001: /* status */
|
||||
@@ -639,7 +402,7 @@ rs_read(int ctlr, int unit, int reg) {
|
||||
break;
|
||||
case 004: /* atten summary */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (rs_unit[(ctlr * 8) + i].CMD & DS_ATA) {
|
||||
if (dptr->units[i].CMD & DS_ATA) {
|
||||
temp |= 1 << i;
|
||||
}
|
||||
}
|
||||
@@ -655,7 +418,7 @@ rs_read(int ctlr, int unit, int reg) {
|
||||
break;
|
||||
default:
|
||||
uptr->CMD |= (ER1_ILR<<16);
|
||||
rs_rae[ctlr] &= ~(1<<unit);
|
||||
rhc->rae |= 1 << unit;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
@@ -663,22 +426,21 @@ rs_read(int ctlr, int unit, int reg) {
|
||||
|
||||
t_stat rs_svc (UNIT *uptr)
|
||||
{
|
||||
int dtype = GET_DTYPE(uptr->flags);
|
||||
int ctlr = GET_CNTRL(uptr->flags);
|
||||
int unit;
|
||||
DEVICE *dptr;
|
||||
struct df10 *df;
|
||||
int da;
|
||||
t_stat r;
|
||||
int dtype = GET_DTYPE(uptr->flags);
|
||||
int ctlr = GET_CNTRL_RH(uptr->flags);
|
||||
int unit;
|
||||
DEVICE *dptr;
|
||||
struct rh_if *rhc;
|
||||
int da;
|
||||
int sts;
|
||||
|
||||
/* Find dptr, and df10 */
|
||||
dptr = rs_devs[ctlr];
|
||||
rhc = &rs_rh[ctlr];
|
||||
unit = uptr - dptr->units;
|
||||
df = &rs_df10[ctlr];
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
uptr->CMD |= (ER1_UNS << 16) | DS_ATA|DS_ERR; /* set drive error */
|
||||
df->status &= ~BUSY;
|
||||
df10_setirq(df);
|
||||
rh_setirq(rhc);
|
||||
return (SCPE_OK);
|
||||
}
|
||||
|
||||
@@ -693,42 +455,35 @@ t_stat rs_svc (UNIT *uptr)
|
||||
case FNC_DCLR: /* drive clear */
|
||||
break;
|
||||
case FNC_PRESET: /* read-in preset */
|
||||
rs_attn[ctlr] = 1;
|
||||
uptr->CMD |= DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~CR_GO;
|
||||
df->status &= ~BUSY;
|
||||
if (df->status & IADR_ATTN)
|
||||
df10_setirq(df);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o seekdone\n", unit);
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
rh_setattn(rhc, unit);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o seekdone\n", dptr->name, unit);
|
||||
break;
|
||||
|
||||
case FNC_SEARCH: /* search */
|
||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf)
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR;
|
||||
rs_attn[ctlr] = 1;
|
||||
uptr->CMD |= DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~CR_GO;
|
||||
df->status &= ~BUSY;
|
||||
if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN)
|
||||
df10_setirq(df);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o searchdone\n", unit);
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
rh_setattn(rhc, unit);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o searchdone\n", dptr->name, unit);
|
||||
break;
|
||||
|
||||
case FNC_READ: /* read */
|
||||
case FNC_WCHK: /* write check */
|
||||
if (uptr->DATAPTR == 0) {
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
int wc;
|
||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf) {
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||
df->status &= ~BUSY;
|
||||
uptr->CMD &= ~CR_GO;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o readx done\n", unit);
|
||||
df10_finish_op(df, 0);
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o readx done\n", dptr->name, unit);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o read (%d,%d)\n", unit,
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read (%d,%d)\n", dptr->name, unit,
|
||||
GET_SC(uptr->DA), GET_SF(uptr->DA));
|
||||
da = GET_DA(uptr->DA, dtype) * RS_NUMWD;
|
||||
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
||||
@@ -737,15 +492,17 @@ t_stat rs_svc (UNIT *uptr)
|
||||
while (wc < RS_NUMWD)
|
||||
rs_buf[ctlr][wc++] = 0;
|
||||
uptr->hwmark = RS_NUMWD;
|
||||
uptr->DATAPTR = 0;
|
||||
}
|
||||
|
||||
df->buf = rs_buf[ctlr][uptr->DATAPTR++];
|
||||
sim_debug(DEBUG_DATA, dptr, "RSA%o read word %d %012llo %09o %06o\n",
|
||||
unit, uptr->DATAPTR, df->buf, df->cda, df->wcr);
|
||||
if (df10_write(df)) {
|
||||
if (uptr->DATAPTR == uptr->hwmark) {
|
||||
rhc->buf = rs_buf[ctlr][uptr->DATAPTR++];
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read word %d %012llo %09o %06o\n",
|
||||
dptr->name, unit, uptr->DATAPTR, rhc->buf, rhc->cda, rhc->wcr);
|
||||
if (rh_write(rhc)) {
|
||||
if (uptr->DATAPTR == RS_NUMWD) {
|
||||
/* Increment to next sector. Set Last Sector */
|
||||
uptr->DATAPTR = 0;
|
||||
CLR_BUF(uptr);
|
||||
uptr->DA += 1 << DA_V_SC;
|
||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect) {
|
||||
uptr->DA &= (DA_M_SF << DA_V_SF);
|
||||
@@ -753,43 +510,53 @@ t_stat rs_svc (UNIT *uptr)
|
||||
if (GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf)
|
||||
uptr->CMD |= DS_LST;
|
||||
}
|
||||
if (rh_blkend(rhc))
|
||||
goto rd_end;
|
||||
}
|
||||
sim_activate(uptr, 20);
|
||||
sim_activate(uptr, 10);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o read done\n", unit);
|
||||
rd_end:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read done\n", dptr->name, unit);
|
||||
uptr->CMD |= DS_DRY;
|
||||
uptr->CMD &= ~CR_GO;
|
||||
df10_finish_op(df, 0);
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
if (uptr->DATAPTR == RS_NUMWD)
|
||||
(void)rh_blkend(rhc);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
if (uptr->DATAPTR == 0) {
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rs_drv_tab[dtype].surf) {
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~CR_GO;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o writex done\n", unit);
|
||||
df10_finish_op(df, 0);
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o writex done\n", dptr->name, unit);
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->hwmark = 0;
|
||||
}
|
||||
r = df10_read(df);
|
||||
rs_buf[ctlr][uptr->DATAPTR++] = df->buf;
|
||||
sim_debug(DEBUG_DATA, dptr, "RSA%o write word %d %012llo %09o %06o\n",
|
||||
unit, uptr->DATAPTR, df->buf, df->cda, df->wcr);
|
||||
if (r == 0 || uptr->DATAPTR == RS_NUMWD) {
|
||||
sts = rh_read(rhc);
|
||||
rs_buf[ctlr][uptr->DATAPTR++] = rhc->buf;
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o write word %d %012llo %09o %06o\n",
|
||||
dptr->name, unit, uptr->DATAPTR, rhc->buf, rhc->cda, rhc->wcr);
|
||||
if (sts == 0) {
|
||||
while (uptr->DATAPTR < RS_NUMWD)
|
||||
rs_buf[ctlr][uptr->DATAPTR++] = 0;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o write (%d,%d)\n", unit,
|
||||
}
|
||||
if (uptr->DATAPTR == RS_NUMWD) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o write (%d,%d)\n", dptr->name, unit,
|
||||
GET_SC(uptr->DA), GET_SF(uptr->DA));
|
||||
da = GET_DA(uptr->DA, dtype) * RS_NUMWD;
|
||||
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
|
||||
(void)sim_fwrite (&rs_buf[ctlr][0], sizeof(uint64), RS_NUMWD,
|
||||
uptr->fileref);
|
||||
uptr->DATAPTR = 0;
|
||||
if (r) {
|
||||
CLR_BUF(uptr);
|
||||
if (sts) {
|
||||
uptr->DA += 1 << DA_V_SC;
|
||||
if (GET_SC(uptr->DA) >= rs_drv_tab[dtype].sect) {
|
||||
uptr->DA &= (DA_M_SF << DA_V_SF);
|
||||
@@ -798,14 +565,17 @@ t_stat rs_svc (UNIT *uptr)
|
||||
uptr->CMD |= DS_LST;
|
||||
}
|
||||
}
|
||||
if (rh_blkend(rhc))
|
||||
goto wr_end;
|
||||
}
|
||||
if (r) {
|
||||
sim_activate(uptr, 20);
|
||||
if (sts) {
|
||||
sim_activate(uptr, 10);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RSA%o write done\n", unit);
|
||||
wr_end:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o write done\n", dptr->name, unit);
|
||||
uptr->CMD |= DS_DRY;
|
||||
uptr->CMD &= ~CR_GO;
|
||||
df10_finish_op(df, 0);
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
rh_finish_op(rhc, 0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
@@ -833,12 +603,9 @@ rs_reset(DEVICE * rstr)
|
||||
{
|
||||
int ctlr;
|
||||
for (ctlr = 0; ctlr < NUM_DEVS_RS; ctlr++) {
|
||||
rs_df10[ctlr].devnum = rs_dib[ctlr].dev_num;
|
||||
rs_df10[ctlr].nxmerr = 19;
|
||||
rs_df10[ctlr].ccw_comp = 14;
|
||||
rs_df10[ctlr].status = 0;
|
||||
rs_attn[ctlr] = 0;
|
||||
rs_rae[ctlr] = 0;
|
||||
rs_rh[ctlr].status = 0;
|
||||
rs_rh[ctlr].attn = 0;
|
||||
rs_rh[ctlr].rae = 0;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -848,16 +615,16 @@ t_stat
|
||||
rs_boot(int32 unit_num, DEVICE * rptr)
|
||||
{
|
||||
UNIT *uptr = &rptr->units[unit_num];
|
||||
int ctlr = GET_CNTRL(uptr->flags);
|
||||
int ctlr = GET_CNTRL_RH(uptr->flags);
|
||||
struct rh_if *rhc;
|
||||
DEVICE *dptr;
|
||||
struct df10 *df;
|
||||
uint32 addr;
|
||||
uint32 ptr = 0;
|
||||
uint64 word;
|
||||
int wc;
|
||||
|
||||
df = &rs_df10[ctlr];
|
||||
dptr = rs_devs[ctlr];
|
||||
rhc = &rs_rh[ctlr];
|
||||
(void)sim_fseek(uptr->fileref, 0, SEEK_SET);
|
||||
(void)sim_fread (&rs_buf[0][0], sizeof(uint64), RS_NUMWD, uptr->fileref);
|
||||
uptr->CMD |= DS_VV;
|
||||
@@ -875,9 +642,9 @@ rs_boot(int32 unit_num, DEVICE * rptr)
|
||||
addr = rs_buf[0][ptr] & RMASK;
|
||||
wc = (rs_buf[0][ptr++] >> 18) & RMASK;
|
||||
word = rs_buf[0][ptr++];
|
||||
rs_reg[ctlr] = 040;
|
||||
rs_drive[ctlr] = uptr - dptr->units;
|
||||
df->status |= CCW_COMP_1|PI_ENABLE;
|
||||
rhc->reg = 040;
|
||||
rhc->drive = uptr - dptr->units;
|
||||
rhc->status |= CCW_COMP_1|PI_ENABLE;
|
||||
PC = word & RMASK;
|
||||
return SCPE_OK;
|
||||
|
||||
@@ -901,14 +668,17 @@ t_stat rs_attach (UNIT *uptr, CONST char *cptr)
|
||||
if (rstr == 0)
|
||||
return SCPE_OK;
|
||||
dib = (DIB *) rstr->ctxt;
|
||||
ctlr = dib->dev_num & 014;
|
||||
for (ctlr = 0; rh[ctlr].dev_num != 0; ctlr++) {
|
||||
if (rh[ctlr].dev == rstr)
|
||||
break;
|
||||
}
|
||||
uptr->DA = 0;
|
||||
uptr->CMD &= ~DS_VV;
|
||||
uptr->CMD |= DS_DPR|DS_MOL|DS_DRY;
|
||||
if (uptr->flags & UNIT_WLK)
|
||||
uptr->CMD |= DS_WRL;
|
||||
rs_df10[ctlr].status |= PI_ENABLE;
|
||||
set_interrupt(dib->dev_num, rs_df10[ctlr].status);
|
||||
rs_rh[ctlr].status |= PI_ENABLE;
|
||||
set_interrupt(dib->dev_num, rs_rh[ctlr].status);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
210
PDP10/kx10_sys.c
210
PDP10/kx10_sys.c
@@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
Copyright (c) 2005-2009, Robert M Supnik
|
||||
Copyright (c) 2011-2018, Richard Cornwell
|
||||
Copyright (c) 2011-2019, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -42,11 +42,8 @@
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
||||
#if KLB
|
||||
char sim_name[] = "KL-10B";
|
||||
#endif
|
||||
#if KLA
|
||||
char sim_name[] = "KL-10A";
|
||||
#if KL
|
||||
char sim_name[] = "KL-10";
|
||||
#endif
|
||||
#if KI
|
||||
char sim_name[] = "KI-10";
|
||||
@@ -68,6 +65,9 @@ DEVICE *sim_devices[] = {
|
||||
#if PDP6 | KA | KI
|
||||
&cty_dev,
|
||||
#endif
|
||||
#if KL
|
||||
&dte_dev,
|
||||
#endif
|
||||
#if (NUM_DEVS_PT > 0)
|
||||
&ptp_dev,
|
||||
&ptr_dev,
|
||||
@@ -75,6 +75,9 @@ DEVICE *sim_devices[] = {
|
||||
#if (NUM_DEVS_LP > 0)
|
||||
&lpt_dev,
|
||||
#endif
|
||||
#if (NUM_DEVS_LP20 > 0)
|
||||
&lp20_dev,
|
||||
#endif
|
||||
#if (NUM_DEVS_CR > 0)
|
||||
&cr_dev,
|
||||
#endif
|
||||
@@ -141,6 +144,9 @@ DEVICE *sim_devices[] = {
|
||||
#if (NUM_DEVS_DC > 0)
|
||||
&dc_dev,
|
||||
#endif
|
||||
#if (NUM_DEVS_TTY > 0)
|
||||
&tty_dev,
|
||||
#endif
|
||||
#if (NUM_DEVS_DCS > 0)
|
||||
&dcs_dev,
|
||||
#endif
|
||||
@@ -156,9 +162,15 @@ DEVICE *sim_devices[] = {
|
||||
&wcnsls_dev,
|
||||
#endif
|
||||
#endif
|
||||
#if (NUM_DEVS_III > 0)
|
||||
&iii_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_IMP > 0
|
||||
&imp_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_NIA > 0
|
||||
&nia_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_CH10 > 0
|
||||
&ch10_dev,
|
||||
#endif
|
||||
@@ -197,7 +209,8 @@ DEVICE *sim_devices[] = {
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"HALT instruction",
|
||||
"Breakpoint"
|
||||
"Breakpoint",
|
||||
"Invalid access"
|
||||
};
|
||||
|
||||
/* Simulator debug controls */
|
||||
@@ -232,6 +245,7 @@ DEBTAB crd_debug[] = {
|
||||
#define FMT_E 3 /* EXE */
|
||||
#define FMT_D 4 /* WAITS DMP */
|
||||
#define FMT_I 5 /* ITS SBLK */
|
||||
#define FMT_B 6 /* EXB format */
|
||||
|
||||
#define EXE_DIR 01776 /* EXE directory */
|
||||
#define EXE_VEC 01775 /* EXE entry vec */
|
||||
@@ -510,19 +524,28 @@ return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
int get_word(FILE *fileref, uint64 *word)
|
||||
int get_word(FILE *fileref, uint64 *word, int ftype)
|
||||
{
|
||||
char cbuf[5];
|
||||
char cbuf[5];
|
||||
|
||||
if (sim_fread(cbuf, 1, 5, fileref) != 5)
|
||||
if (sim_fread(cbuf, 1, 5, fileref) != 5)
|
||||
return 1;
|
||||
*word = ((uint64)(cbuf[0]) << 29) |
|
||||
((uint64)(cbuf[1]) << 22) |
|
||||
((uint64)(cbuf[2]) << 15) |
|
||||
((uint64)(cbuf[3]) << 8) |
|
||||
((uint64)(cbuf[4] & 0177) << 1) |
|
||||
((uint64)(cbuf[4] & 0200) >> 7);
|
||||
return 0;
|
||||
if (ftype) {
|
||||
*word = ((uint64)(cbuf[0] & 0177) << 29) |
|
||||
((uint64)(cbuf[1] & 0177) << 22) |
|
||||
((uint64)(cbuf[2] & 0177) << 15) |
|
||||
((uint64)(cbuf[3] & 0177) << 8) |
|
||||
((uint64)(cbuf[4] & 0177) << 1);
|
||||
if (cbuf[4] & 0200)
|
||||
*word |= 1;
|
||||
} else {
|
||||
*word = ((uint64)(cbuf[0] & 0377) << 28) |
|
||||
((uint64)(cbuf[1] & 0377) << 20) |
|
||||
((uint64)(cbuf[2] & 0377) << 12) |
|
||||
((uint64)(cbuf[3] & 0377) << 4) |
|
||||
(uint64)(cbuf[4] & 017);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SAV file loader
|
||||
@@ -538,14 +561,14 @@ int get_word(FILE *fileref, uint64 *word)
|
||||
JRST start
|
||||
*/
|
||||
|
||||
t_stat load_sav (FILE *fileref)
|
||||
t_stat load_sav (FILE *fileref, int ftype)
|
||||
{
|
||||
uint64 data;
|
||||
uint32 pa;
|
||||
int32 wc;
|
||||
|
||||
for ( ;; ) { /* loop */
|
||||
if (get_word(fileref, &data))
|
||||
if (get_word(fileref, &data, ftype))
|
||||
return SCPE_OK;
|
||||
wc = (int32)(data >> 18);
|
||||
pa = (uint32) (data & RMASK);
|
||||
@@ -559,7 +582,7 @@ t_stat load_sav (FILE *fileref)
|
||||
pa &= RMASK;
|
||||
wc++;
|
||||
wc &= RMASK;
|
||||
if (get_word(fileref, &data))
|
||||
if (get_word(fileref, &data, ftype))
|
||||
return SCPE_FMT;
|
||||
M[pa] = data;
|
||||
} /* end if count*/
|
||||
@@ -594,7 +617,7 @@ t_stat load_sav (FILE *fileref)
|
||||
#define PAG_V_PN 9
|
||||
#define DIRSIZ (2 * PAG_SIZE)
|
||||
|
||||
t_stat load_exe (FILE *fileref)
|
||||
t_stat load_exe (FILE *fileref, int ftype)
|
||||
{
|
||||
uint64 data, dirbuf[DIRSIZ], pagbuf[PAG_SIZE], entbuf[2];
|
||||
int32 ndir, entvec, i, j, k, cont, bsz, bty, rpt, wc;
|
||||
@@ -604,8 +627,9 @@ uint32 ma;
|
||||
ndir = entvec = 0; /* no dir, entvec */
|
||||
cont = 1;
|
||||
do {
|
||||
wc = sim_fread (&data, sizeof (uint64), 1, fileref);/* read blk hdr */
|
||||
if (wc == 0) /* error? */
|
||||
|
||||
wc = get_word(fileref, &data, ftype);
|
||||
if (wc != 0) /* error? */
|
||||
return SCPE_FMT;
|
||||
bsz = (int32) ((data & RMASK) - 1); /* get count */
|
||||
if (bsz < 0) /* zero? */
|
||||
@@ -616,9 +640,11 @@ do {
|
||||
case EXE_DIR: /* directory */
|
||||
if (ndir != 0) /* got one */
|
||||
return SCPE_FMT;
|
||||
ndir = sim_fread (dirbuf, sizeof (uint64), bsz, fileref);
|
||||
if (ndir < bsz) /* error */
|
||||
return SCPE_FMT;
|
||||
for (i = 0; i < bsz; i++) {
|
||||
if (get_word(fileref, &dirbuf[i], ftype))
|
||||
return SCPE_FMT;
|
||||
}
|
||||
ndir = bsz;
|
||||
break;
|
||||
|
||||
case EXE_PDV: /* optional */
|
||||
@@ -628,9 +654,11 @@ do {
|
||||
case EXE_VEC: /* entry vec */
|
||||
if (bsz != 2) /* must be 2 wds */
|
||||
return SCPE_FMT;
|
||||
entvec = sim_fread (entbuf, sizeof (uint64), bsz, fileref);
|
||||
if (entvec < 2) /* error? */
|
||||
return SCPE_FMT;
|
||||
for (i = 0; i < bsz; i++) {
|
||||
if (get_word(fileref, &entbuf[i], ftype))
|
||||
return SCPE_FMT;
|
||||
}
|
||||
entvec = bsz;
|
||||
cont = 0; /* stop */
|
||||
break;
|
||||
|
||||
@@ -651,10 +679,11 @@ for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
|
||||
rpt = ((int32) ((dirbuf[i + 1] >> 27) + 1)) & 0777; /* repeat count */
|
||||
for (j = 0; j < rpt; j++, mpage++) { /* loop thru rpts */
|
||||
if (fpage) { /* file pages? */
|
||||
(void)sim_fseek (fileref, (fpage << PAG_V_PN) * sizeof (uint64), SEEK_SET);
|
||||
wc = sim_fread (pagbuf, sizeof (uint64), PAG_SIZE, fileref);
|
||||
if (wc < PAG_SIZE)
|
||||
return SCPE_FMT;
|
||||
(void)sim_fseek (fileref, (fpage << PAG_V_PN) * 5, SEEK_SET);
|
||||
for (k = 0; k < PAG_SIZE; k++) {
|
||||
if (get_word(fileref, &pagbuf[k], ftype))
|
||||
break;
|
||||
}
|
||||
fpage++;
|
||||
}
|
||||
ma = mpage << PAG_V_PN; /* mem addr */
|
||||
@@ -667,18 +696,103 @@ for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
|
||||
} /* end directory */
|
||||
if (entvec && entbuf[1])
|
||||
PC = (int32) (entbuf[1] & RMASK); /* start addr */
|
||||
else if (entvec == 0)
|
||||
PC = (int32) (M[0120] & RMASK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static int exb_pos = -1;
|
||||
int get_exb_byte (FILE *fileref, int *byt, int ftype)
|
||||
{
|
||||
static uint64 word;
|
||||
|
||||
exb_pos++;
|
||||
switch(exb_pos & 3) {
|
||||
case 0: if (get_word(fileref, &word, ftype))
|
||||
return 1;
|
||||
*byt = ((word >> 18) & 0377);
|
||||
break;
|
||||
case 1: *byt = ((word >> 26) & 0377);
|
||||
break;
|
||||
case 2: *byt = ((word >> 0) & 0377);
|
||||
break;
|
||||
case 3: *byt = ((word >> 8) & 0377);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
t_stat load_exb (FILE *fileref, int ftype)
|
||||
{
|
||||
int odd = 0;
|
||||
int pos = 0;
|
||||
int wc;
|
||||
int byt;
|
||||
uint64 word;
|
||||
t_addr addr;
|
||||
|
||||
exb_pos = -1;
|
||||
for ( ;; ) {
|
||||
/* All records start on even byte */
|
||||
if (odd && get_exb_byte (fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
if (get_exb_byte(fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
wc = byt;
|
||||
if (get_exb_byte(fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
wc |= byt << 8;
|
||||
wc -= 4;
|
||||
odd = wc & 1;
|
||||
if (get_exb_byte(fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
addr = byt;
|
||||
if (get_exb_byte(fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
addr |= byt << 8;
|
||||
if (get_exb_byte(fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
addr |= byt << 16;
|
||||
if (get_exb_byte(fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
addr |= byt << 24;
|
||||
/* Empty record gives start address */
|
||||
if (wc == 0) {
|
||||
PC = addr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
pos = 0;
|
||||
for (; wc > 0; wc--, pos++) {
|
||||
if (get_exb_byte(fileref, &byt, ftype))
|
||||
return SCPE_FMT;
|
||||
switch(pos) {
|
||||
case 0: word = ((uint64)byt); break;
|
||||
case 1: word |= ((uint64)byt) << 8; break;
|
||||
case 2: word |= ((uint64)byt) << 16; break;
|
||||
case 3: word |= ((uint64)byt) << 24; break;
|
||||
case 4: word |= ((uint64)(byt & 017)) << 32;
|
||||
M[addr++] = word;
|
||||
pos = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_FMT;
|
||||
}
|
||||
|
||||
/* Master loader */
|
||||
|
||||
t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
|
||||
{
|
||||
uint64 data;
|
||||
int32 wc, fmt;
|
||||
int ftype;
|
||||
extern int32 sim_switches;
|
||||
|
||||
fmt = 0; /* no fmt */
|
||||
ftype = 0;
|
||||
if (sim_switches & SWMASK ('C')) /* -c? core dump */
|
||||
ftype = 1;
|
||||
if (sim_switches & SWMASK ('R')) /* -r? */
|
||||
fmt = FMT_R;
|
||||
else if (sim_switches & SWMASK ('S')) /* -s? */
|
||||
@@ -689,12 +803,16 @@ else if (sim_switches & SWMASK ('D')) /* -d? */
|
||||
fmt = FMT_D;
|
||||
else if (sim_switches & SWMASK ('I')) /* -i? */
|
||||
fmt = FMT_I;
|
||||
else if (sim_switches & SWMASK ('B')) /* -b? */
|
||||
fmt = FMT_B;
|
||||
else if (match_ext (fnam, "RIM")) /* .RIM? */
|
||||
fmt = FMT_R;
|
||||
else if (match_ext (fnam, "SAV")) /* .SAV? */
|
||||
fmt = FMT_S;
|
||||
else if (match_ext (fnam, "EXE")) /* .EXE? */
|
||||
fmt = FMT_E;
|
||||
else if (match_ext (fnam, "EXB")) /* .EXB? */
|
||||
fmt = FMT_B;
|
||||
else if (match_ext (fnam, "DMP")) /* .DMP? */
|
||||
fmt = FMT_D;
|
||||
else if (match_ext (fnam, "BIN")) /* .BIN? */
|
||||
@@ -716,16 +834,19 @@ switch (fmt) { /* case fmt */
|
||||
return load_rim (fileref);
|
||||
|
||||
case FMT_S: /* SAV */
|
||||
return load_sav (fileref);
|
||||
return load_sav (fileref, ftype);
|
||||
|
||||
case FMT_E: /* EXE */
|
||||
return load_exe (fileref);
|
||||
return load_exe (fileref, ftype);
|
||||
|
||||
case FMT_D: /* DMP */
|
||||
return load_dmp (fileref);
|
||||
|
||||
case FMT_I: /* SBLK */
|
||||
return load_sblk (fileref);
|
||||
|
||||
case FMT_B: /* EXB */
|
||||
return load_exb (fileref, ftype);
|
||||
}
|
||||
|
||||
printf ("Can't determine load file format\n");
|
||||
@@ -759,13 +880,22 @@ static const char *opcode[] = {
|
||||
"LUUO10", "LUUO11", "LUUO12", "LUUO13", "LUUO14", "LUUO15", "LUUO16", "LUUO17",
|
||||
"LUUO20", "LUUO21", "LUUO22", "LUUO23", "LUUO24", "LUUO25", "LUUO26", "LUUO27",
|
||||
"LUUO30", "LUUO31", "LUUO32", "LUUO33", "LUUO34", "LUUO35", "LUUO36", "LUUO37",
|
||||
"MUUO40", "MUUO41", "MUUO42", "MUUO43", "MUUO44", "MUUO45", "MUUO46", "MUUO47",
|
||||
"MUUO50", "MUUO51", "MUUO52", "MUUO53", "MUUO54", "MUUO55", "MUUO56", "MUUO57",
|
||||
"MUUO60", "MUUO61", "MUUO62", "MUUO63", "MUUO64", "MUUO65", "MUUO66", "MUUO67",
|
||||
"MUUO70", "MUUO71", "MUUO72", "MUUO73", "MUUO74", "MUUO75", "MUUO76", "MUUO77",
|
||||
"CALL", "INITI", "MUUO42", "MUUO43", "MUUO44", "MUUO45", "MUUO46", "CALLI",
|
||||
#if KL
|
||||
"OPEN", "TTCALL", "PMOVE", "PMOVEM", "MUUO54", "RENAME", "IN", "OUT",
|
||||
#else
|
||||
"OPEN", "TTCALL", "MUUO52", "MUUO53", "MUUO54", "RENAME", "IN", "OUT",
|
||||
#endif
|
||||
"SETSTS", "STATO", "STATUS", "GETSTS", "INBUF", "OUTBUF", "INPUT", "OUTPUT",
|
||||
"CLOSE", "RELEAS", "MTAPE", "UGETF", "USETI", "USETO", "LOOKUP", "ENTER",
|
||||
|
||||
"UJEN", "MUUO101", "MUUO102", "JSYS", "MUUO104", "MUUO105", "MUUO106",
|
||||
#if KL
|
||||
"UJEN", "GFAD", "GFSB", "JSYS", "ADJSP", "GFMP", "GFDV ",
|
||||
"DFAD", "DFSB", "DFMP", "DFDV", "DADD", "DSUB", "DMUL", "DDIV",
|
||||
#else
|
||||
"UJEN", "MUUO101", "MUUO102", "JSYS", "MUUO104", "MUUO105", "MUUO106",
|
||||
"DFAD", "DFSB", "DFMP", "DFDV", "MUUO114", "MUUO115", "MUUO116", "MUUO117",
|
||||
#endif
|
||||
"DMOVE", "DMOVN", "FIX", "EXTEND", "DMOVEM", "DMOVNM", "FIXR", "FLTR",
|
||||
"UFA", "DFN", "FSC", "ADJBP", "ILDB", "LDB", "IDPB", "DPB",
|
||||
"FAD", "FADL", "FADM", "FADB", "FADR", "FADRL", "FADRM", "FADRB",
|
||||
|
||||
907
PDP10/kx10_tu.c
907
PDP10/kx10_tu.c
File diff suppressed because it is too large
Load Diff
101
README.md
101
README.md
@@ -1,8 +1,8 @@
|
||||
|
||||
[](https://scan.coverity.com/projects/rcornwell-sims)
|
||||
|
||||
This is a working copy of my Burroughs B5500, Dec PDP6, KA10, KI10, SEL32, IBM 360 and IBM7000
|
||||
series simulators for SimH.
|
||||
This is a working copy of my Burroughs B5500, Dec PDP6, KA10, KI10, KL10, SEL32, IBM 360
|
||||
and IBM7000 series simulators for SimH.
|
||||
|
||||
# Stable released simulators.
|
||||
|
||||
@@ -64,7 +64,14 @@ Latest status for I7000 Cpus:
|
||||
|
||||
Emulates a dual CPU B5500 with up to 32K of memory. I can support either DFX disks or
|
||||
dual disks up to 20 units. Up to 16 magnetic tapes drives is support. 2 Card readers
|
||||
a card punch and a pair of line printers.
|
||||
a card punch and a pair of line printers. Will run MCP XIII and XV.
|
||||
|
||||
* Up to either 10 disks with DFX support or 20 disks without.
|
||||
* Up to 16 magnetic tape drives.
|
||||
* Dual card reader.
|
||||
* Dual Line printer.
|
||||
* Single card punch.
|
||||
* Up to 32 terminal lines.
|
||||
|
||||
# Dec PDP6
|
||||
|
||||
@@ -88,76 +95,60 @@ The PDP6 runs TOPS 10 4.5 off Dectape.
|
||||
|
||||
Type 340 graphics display.
|
||||
|
||||
# Dec KA10 & KI10
|
||||
# Dec KA10 & KI10 & KL10
|
||||
|
||||
These are nearing release. Please report any issues that you find in them.
|
||||
|
||||
The KA10 sim has successfully run Tops 10 4.5, 5.03 and Tops 10 6.03.
|
||||
The KI10 sim has successfully run Tops 10 6.03 with VMSER
|
||||
The KA10 sim has successfully run ITS.
|
||||
The KA10 sim has successfully run WAITS (with and without BBN pager).
|
||||
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.
|
||||
|
||||
Disk
|
||||
* RC10 RD10/RM10
|
||||
* RP10 RP01/RP02/RP03
|
||||
* RH10 RP04/RP06/RP07 (RP07 not supported under 6.03).
|
||||
* RH10 RS04
|
||||
* RH10/RH20 RP04/RP06/RP07 (RP07 not supported under 6.03).
|
||||
* RH10/RH20 RS04
|
||||
* PMP (P. PETIT'S IBM CHANNEL)
|
||||
* System Concepts DC-10 IBM 2314
|
||||
|
||||
Tape
|
||||
* TM10A or B
|
||||
* RH10 TM03/TU16
|
||||
* RH10/RH20 TM03/TU16
|
||||
* TD10 Dectape
|
||||
|
||||
Paper Tape
|
||||
* Punch
|
||||
* Reader
|
||||
|
||||
DC10E terminal mux.
|
||||
Morton tty Mux for ITS.
|
||||
Knight Kludge mux for ITS.
|
||||
* DC10E terminal mux.
|
||||
* Morton tty Mux for ITS.
|
||||
* Knight Kludge mux for ITS.
|
||||
* Terminals on KL10 Front End.
|
||||
|
||||
IMP networking support for ITS and TENEX.
|
||||
CH10 networking support for ITS.
|
||||
* LP10 Line printer.
|
||||
* LP20 Line printer on KL10 Front End.
|
||||
|
||||
340 Display Station support.
|
||||
* IMP networking support for ITS and TENEX.
|
||||
* NIA20 networking support for KL10.
|
||||
* CH10 networking support for ITS.
|
||||
|
||||
Optional support for PDP6 devices (standard if WAITS included).
|
||||
* 340 Display Station support.
|
||||
* III Display support for WAITS (in progress).
|
||||
|
||||
* Optional support for PDP6 devices (standard if WAITS included).
|
||||
|
||||
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.
|
||||
|
||||
Support for KL10A will be started in the summer.
|
||||
|
||||
# Development Simulators.
|
||||
|
||||
# Dec KL10
|
||||
|
||||
Still in initial coding stages.
|
||||
|
||||
Disk
|
||||
* RH10 RP04/RP06/RP07
|
||||
* RH10 RS04
|
||||
* RH20 RP04/RP06/RP07
|
||||
* RH20 RS04
|
||||
|
||||
Tape
|
||||
* TM10A or B
|
||||
* RH10 TM03/TU16
|
||||
* RH20 TM03/TU16
|
||||
|
||||
DC10E terminal mux.
|
||||
Terminals attached to front end processor
|
||||
|
||||
IMP networking support for ITS and TENEX.
|
||||
|
||||
# ICL 1900 simulator.
|
||||
|
||||
This is a new simulator. Will pass 1904E/1905E CPU diagnostics (FLIT). Will boot paper
|
||||
tape executive E4BM and tape executive E6RM. Still need to add more devices and test
|
||||
with Goerge 2 and 3.
|
||||
|
||||
The CPU can be configured for model A, B or C type system. Or models 1901 throgh 1909.
|
||||
Paging is currently not supported. Both standard interface and older non-standard interface
|
||||
are supported on most device.
|
||||
|
||||
|
||||
# IBM 360 simulator.
|
||||
|
||||
Currently will run IPL TOS/360, DOS/360, OS/360. TSO support still in progress.
|
||||
@@ -186,18 +177,14 @@ The current test version is for the SEL 32/27, 32/67, 32/87, 32/97 computers.
|
||||
Support for 32/55, 32/75, V6, and V9 computers may be added in the future.
|
||||
This simulator is co-authors with James C. Bevier. I did the initial parts
|
||||
of the simulator, James took it to a working simulator, I am assisting him
|
||||
in maintaining and enhancing the simulator.
|
||||
|
||||
# SEL Concept/32
|
||||
|
||||
This simulator is running a test version of MPX-32 1.5F. It is capable of
|
||||
creating a disk image of the O/S from a SDT tape. The disk image can be
|
||||
booted, initialized, and run many of the MPX utilities; including OPCOM & TSM.
|
||||
Eight terminals can be used to access TSM via Telnet port 4747. Initial
|
||||
support has been added for excess 64 floating point arithmetic. More testing
|
||||
is still required. The sim32disk.gz can be uncompressed and booted with the
|
||||
sel32.27.sim32.disk.ini initialization file. The sim32sdt.tap.gz file can
|
||||
also be uncompressed and started with the sel32.27.sim32.tape.ini initialization
|
||||
file to install from tape.
|
||||
in maintaining and enhancing the simulator. This simulator is running a test
|
||||
version of MPX-32 1.5F. It is capable of creating a disk image of the O/S
|
||||
from a SDT tape. The disk image can be booted, initialized, and run many of
|
||||
the MPX utilities; including OPCOM & TSM. Eight terminals can be used to
|
||||
access TSM via Telnet port 4747. Initial support has been added for excess
|
||||
64 floating point arithmetic. More testing is still required. The sim32disk.gz
|
||||
can be uncompressed and booted with the sel32.27.sim32.disk.ini initialization file.
|
||||
The sim32sdt.tap.gz file can also be uncompressed and started with the
|
||||
sel32.27.sim32.tape.ini initialization file to install from tape.
|
||||
|
||||
|
||||
|
||||
@@ -975,6 +975,18 @@ display_init(enum display_type type, int sf, void *dptr)
|
||||
fprintf(stderr, "Display initialization failed\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
display_close(void *dptr)
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
free (points);
|
||||
ws_shutdown();
|
||||
|
||||
initialized = 0;
|
||||
}
|
||||
|
||||
void
|
||||
display_reset(void)
|
||||
|
||||
@@ -65,6 +65,11 @@ enum display_type {
|
||||
*/
|
||||
extern int display_init(enum display_type, int scale, void *dptr);
|
||||
|
||||
/*
|
||||
* close display
|
||||
*/
|
||||
extern void display_close(void *dptr);
|
||||
|
||||
/* return size of virtual display */
|
||||
extern int display_xpoints(void);
|
||||
extern int display_ypoints(void);
|
||||
|
||||
BIN
doc/ka10_doc.doc
BIN
doc/ka10_doc.doc
Binary file not shown.
BIN
doc/ki10_doc.doc
BIN
doc/ki10_doc.doc
Binary file not shown.
BIN
doc/kl10_doc.doc
Normal file
BIN
doc/kl10_doc.doc
Normal file
Binary file not shown.
29
makefile
29
makefile
@@ -109,8 +109,8 @@ endif
|
||||
ifneq (,$(or $(findstring pdp6,${MAKECMDGOALS}),$(findstring pdp10-ka,${MAKECMDGOALS}),$(findstring pdp10-ki,${MAKECMDGOALS})))
|
||||
VIDEO_USEFUL = true
|
||||
endif
|
||||
# building the KA10 or KI10 networking can be used.
|
||||
ifneq (,$(or $(findstring pdp10-ka,${MAKECMDGOALS}),$(findstring pdp10-ki,${MAKECMDGOALS})))
|
||||
# building the KA10, KI10 or KL10 networking can be used.
|
||||
ifneq (,$(or $(findstring pdp10-ka,${MAKECMDGOALS}),$(findstring pdp10-ki,${MAKECMDGOALS},$(findstring pdp10-kl,${MAKECMDGOALS}))))
|
||||
NETWORK_USEFUL = true
|
||||
endif
|
||||
# building the PDP-7 needs video support
|
||||
@@ -2023,13 +2023,13 @@ KA10 = ${KA10D}/kx10_cpu.c ${KA10D}/kx10_sys.c ${KA10D}/kx10_df.c \
|
||||
${KA10D}/kx10_rp.c ${KA10D}/kx10_rc.c ${KA10D}/kx10_dt.c \
|
||||
${KA10D}/kx10_dk.c ${KA10D}/kx10_cr.c ${KA10D}/kx10_cp.c \
|
||||
${KA10D}/kx10_tu.c ${KA10D}/kx10_rs.c ${KA10D}/ka10_pd.c \
|
||||
${KA10D}/kx10_imp.c ${KA10D}/ka10_tk10.c \
|
||||
${KA10D}/kx10_rh.c ${KA10D}/kx10_imp.c ${KA10D}/ka10_tk10.c \
|
||||
${KA10D}/ka10_mty.c ${KA10D}/ka10_imx.c ${KA10D}/ka10_ch10.c \
|
||||
${KA10D}/ka10_stk.c ${KA10D}/ka10_ten11.c ${KA10D}/ka10_auxcpu.c \
|
||||
$(KA10D)/ka10_pmp.c ${KA10D}/ka10_dkb.c ${KA10D}/pdp6_dct.c \
|
||||
${KA10D}/pdp6_dtc.c ${KA10D}/pdp6_mtc.c ${KA10D}/pdp6_dsk.c \
|
||||
${KA10D}/pdp6_dcs.c ${KA10D}/ka10_dpk.c ${KA10D}/kx10_dpy.c \
|
||||
${PDP10D}/ka10_ai.c ${DISPLAYL} ${DISPLAY340}
|
||||
${PDP10D}/ka10_ai.c ${KA10D}/ka10_iii.c ${DISPLAYL} ${DISPLAY340}
|
||||
KA10_OPT = -DKA=1 -DUSE_INT64 -I ${KA10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KA10_DISPLAY_OPT}
|
||||
ifneq (${PANDA_LIGHTS},)
|
||||
# ONLY for Panda display.
|
||||
@@ -2045,7 +2045,7 @@ endif
|
||||
KI10 = ${KI10D}/kx10_cpu.c ${KI10D}/kx10_sys.c ${KI10D}/kx10_df.c \
|
||||
${KI10D}/kx10_dp.c ${KI10D}/kx10_mt.c ${KI10D}/kx10_cty.c \
|
||||
${KI10D}/kx10_lp.c ${KI10D}/kx10_pt.c ${KI10D}/kx10_dc.c \
|
||||
${KI10D}/kx10_rp.c ${KI10D}/kx10_rc.c \
|
||||
${KI10D}/kx10_rh.c ${KI10D}/kx10_rp.c ${KI10D}/kx10_rc.c \
|
||||
${KI10D}/kx10_dt.c ${KI10D}/kx10_dk.c ${KI10D}/kx10_cr.c \
|
||||
${KI10D}/kx10_cp.c ${KI10D}/kx10_tu.c ${KI10D}/kx10_rs.c \
|
||||
${KI10D}/kx10_imp.c ${KI10D}/kx10_dpy.c ${DISPLAYL} ${DISPLAY340}
|
||||
@@ -2057,6 +2057,14 @@ KI10 += ${KA10D}/ka10_lights.c
|
||||
KI10_LDFLAGS = -lusb-1.0
|
||||
endif
|
||||
|
||||
KL10D = ${SIMHD}/PDP10
|
||||
KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \
|
||||
${KL10D}/kx10_mt.c ${KL10D}/kx10_dc.c ${KL10D}/kx10_rh.c \
|
||||
${KL10D}/kx10_rp.c ${KL10D}/kx10_tu.c ${KL10D}/kx10_rs.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
|
||||
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT}
|
||||
|
||||
ATT3B2D = ${SIMHD}/3B2
|
||||
ATT3B2 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_mmu.c \
|
||||
${ATT3B2D}/3b2_iu.c ${ATT3B2D}/3b2_if.c \
|
||||
@@ -2131,7 +2139,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 ibm360 ibm360_32 icl1900 pdp6 sel32
|
||||
ALL = b5500 i701 i704 i7010 i7070 i7080 i7090 pdp10-ka pdp10-ki pdp10-kl ibm360 ibm360_32 icl1900 pdp6 sel32
|
||||
|
||||
all : ${ALL}
|
||||
|
||||
@@ -2965,6 +2973,15 @@ ifneq (,$(call find_test,${PDP10D},ki10))
|
||||
$@ $(call find_test,${PDP10D},ki10) ${TEST_ARG}
|
||||
endif
|
||||
|
||||
pdp10-kl : ${BIN}pdp10-kl${EXE}
|
||||
|
||||
${BIN}pdp10-kl${EXE} : ${KL10} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${KL10} ${SIM} ${KL10_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||
ifneq (,$(call find_test,${PDP10D},kl10))
|
||||
$@ $(call find_test,${PDP10D},kl10) ${TEST_ARG}
|
||||
endif
|
||||
|
||||
# Front Panel API Demo/Test program
|
||||
|
||||
frontpaneltest : ${BIN}frontpaneltest${EXE}
|
||||
|
||||
Reference in New Issue
Block a user