1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-16 16:27:19 +00:00

KA10: Added Card Reader and Card Punch. Some fixes to KI10.

Card reader and Card Punch now work. KI10 will refresh disk
structures and load backup from tape.
This commit is contained in:
Richard Cornwell 2016-07-24 22:09:46 -04:00
parent 0a5c7cbf87
commit 9ca9fdcea5
6 changed files with 304 additions and 259 deletions

View File

@ -35,7 +35,7 @@ LDFLAGS = -lm -lrt
BIN = ./
SIM = ../scp.c ../sim_console.c ../sim_fio.c ../sim_timer.c ../sim_tape.c \
../sim_sock.c ../sim_tmxr.c ../sim_ether.c ../sim_video.c ../sim_serial.c \
../sim_disk.c
../sim_disk.c ../sim_card.c
#
@ -46,16 +46,16 @@ KA10 = ${KA10D}ka10_cpu.c ${KA10D}ka10_sys.c ${KA10D}ka10_df.c \
${KA10D}ka10_dp.c ${KA10D}ka10_mt.c ${KA10D}ka10_cty.c \
${KA10D}ka10_lp.c ${KA10D}ka10_pt.c ${KA10D}ka10_dc.c \
${KA10D}ka10_rp.c ${KA10D}ka10_rc.c ${KA10D}ka10_dt.c \
${KA10D}ka10_dk.c
KA10_OPT = -I.. -DUSE_INT64 -DKA=1
${KA10D}ka10_dk.c ${KA10D}ka10_cr.c ${KA10D}ka10_cp.c
KA10_OPT = -I.. -DUSE_INT64 -DKA=1 -DUSE_SIM_CARD
KI10D = ./
KI10 = ${KA10D}ka10_cpu.c ${KA10D}ka10_sys.c ${KA10D}ka10_df.c \
${KA10D}ka10_dp.c ${KA10D}ka10_mt.c ${KA10D}ka10_cty.c \
${KA10D}ka10_lp.c ${KA10D}ka10_pt.c ${KA10D}ka10_dc.c \
${KA10D}ka10_rp.c ${KA10D}ka10_rc.c ${KA10D}ka10_dt.c \
${KA10D}ka10_dk.c
KI10_OPT = -I.. -DUSE_INT64 -DKI=1
${KA10D}ka10_dk.c ${KA10D}ka10_cr.c ${KA10D}ka10_cp.c
KI10_OPT = -I.. -DUSE_INT64 -DKI=1 -DUSE_SIM_CARD
#
# Build everything

View File

@ -1,4 +1,4 @@
/* ka10_cdp.c: PDP10 Card Punch
/* ka10_cp.c: PDP10 Card Punch
Copyright (c) 2016, Richard Cornwell
@ -32,19 +32,19 @@
#include "ka10_defs.h"
#include "sim_card.h"
#include "sim_defs.h"
#ifdef NUM_DEVS_CDP
#if (NUM_DEVS_CP > 0)
#define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE | MODE_026
#define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE | MODE_029
#define CDP_DEVNUM 0110
#define CP_DEVNUM 0110
/* std devices. data structures
cdp_dev Card Punch device descriptor
cdp_unit Card Punch unit descriptor
cdp_reg Card Punch register list
cdp_mod Card Punch modifiers list
cp_dev Card Punch device descriptor
cp_unit Card Punch unit descriptor
cp_reg Card Punch register list
cp_mod Card Punch modifiers list
*/
/* CONO Bits */
@ -77,41 +77,31 @@
#define HOPPER_LOW 0100000 /* less 200 cards 20 */
#define TEST 0400000 /* In test mode 18 */
/* Device status information stored in u5 */
#define URCSTA_EOF 0001 /* Hit end of file */
#define URCSTA_ERR 0002 /* Error reading record */
#define URCSTA_CARD 0004 /* Unit has card in buffer */
#define URCSTA_FULL 0004 /* Unit has full buffer */
#define URCSTA_BUSY 0010 /* Device is busy */
t_stat cdp_devio(uint32 dev, uint64 *data);
void cdp_ini(UNIT *, t_bool);
t_stat cdp_srv(UNIT *);
t_stat cdp_reset(DEVICE *);
t_stat cdp_attach(UNIT *, CONST char *);
t_stat cdp_detach(UNIT *);
t_stat cdp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
const char *cdp_description(DEVICE *dptr);
t_stat cp_devio(uint32 dev, uint64 *data);
t_stat cp_srv(UNIT *);
t_stat cp_reset(DEVICE *);
t_stat cp_attach(UNIT *, CONST char *);
t_stat cp_detach(UNIT *);
t_stat cp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
const char *cp_description(DEVICE *dptr);
DIB cdp_dib = { CDP_DEVNUM, 1, cdp_devio, NULL};
DIB cp_dib = { CP_DEVNUM, 1, cp_devio, NULL};
UNIT cdp_unit[] = {
{UDATA(cdp_srv, UNIT_S_CHAN(CHAN_CHUREC) | UNIT_CDP, 0), 600}, /* A */
};
UNIT cp_unit = {UDATA(cp_srv, UNIT_CDP, 0), 600 };
MTAB cdp_mod[] = {
MTAB cp_mod[] = {
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_card_set_fmt, &sim_card_show_fmt, NULL},
{0}
};
DEVICE cdp_dev = {
"CP", cdp_unit, NULL, cdp_mod,
NUM_DEVS_CDP, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &cdp_attach, &cdp_detach,
&cdp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
NULL, NULL, &cdp_help, NULL, NULL, &cdp_description
DEVICE cp_dev = {
"CP", &cp_unit, NULL, cp_mod,
NUM_DEVS_CP, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &cp_attach, &cp_detach,
&cp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
NULL, NULL, &cp_help, NULL, NULL, &cp_description
};
@ -120,51 +110,52 @@ DEVICE cdp_dev = {
/* Card punch routine
*/
t_stat cdp_devio(uint32 dev, uint64 *data) {
t_stat cp_devio(uint32 dev, uint64 *data) {
uint64 res;
DEVICE *dptr = &cdp_dev[0];
UNIT *uptr = &cdp_unit[0];
UNIT *uptr = &cp_unit;
struct _card_data *dp;
#define PIA 0000007
#define DATA_REQ 0000010
#define PUNCH_ON 0000040
#define END_CARD 0000100 /* Eject or column 80 */
#define END_CARD_EN 0000200
#define CARD_IN_PUNCH 0000400 /* Card ready to punch */
#define ERROR 0001000 /* Punch error */
#define TROUBLE_EN 0002000
#define TROUBLE 0004000 /* Bit 18,22,23, or 21 */
#define EJECT_FAIL 0010000 /* Could not eject card 23 */
#define PICK_FAIL 0020000 /* Could not pick up card 22 */
#define NEED_OPR 0040000 /* Hopper empty, chip full 21 */
#define HOPPER_LOW 0100000 /* less 200 cards 20 */
#define TEST 0400000 /* In test mode 18 */
switch(dev & 3) {
case CONI:
*data = uptr->u3;
sim_debug(DEBUG_CONI, &cp_dev, "CP: CONI %012llo\n", *data);
break;
case CONO:
uptr->u3 &= ~7;
uptr->u3 |= *data & (PUNCH_ON|07);
clr_interrupt(dev);
sim_debug(DEBUG_CONO, &cp_dev, "CP: CONO %012llo\n", *data);
uptr->u3 &= ~PIA;
uptr->u3 |= *data & PIA;
if (*data & CLR_PUNCH) {
uptr->u3 &= ~(TROUBLE|ERROR|END_CARD|END_CARD_EN|TROUBLE_EN);
break;
}
if (
#define SET_DATA_REQ 0000010
#define CLR_DATA_REQ 0000020
#define SET_PUNCH_ON 0000040
#define CLR_END_CARD 0000100
#define EN_END_CARD 0000200
#define DIS_END_CARD 0000400
#define CLR_ERROR 0001000
#define EN_TROUBLE 0002000
#define DIS_TROUBLE 0004000
#define EJECT 0010000 /* Finish punch and eject */
#define OFFSET_CARD 0040000 /* Offset card stack */
#define CLR_PUNCH 0100000 /* Clear Trouble, Error, End */
if (uptr->u3 & PUNCH_ON) {
if (*data & SET_DATA_REQ) {
uptr->u3 |= DATA_REQ;
set_interrupt(dev, uptr->u3);
}
if (*data & CLR_DATA_REQ)
uptr->u3 &= ~DATA_REQ;
if (*data & CLR_END_CARD)
uptr->u3 &= ~END_CARD;
if (*data & EN_END_CARD)
uptr->u3 |= END_CARD_EN;
if (*data & DIS_END_CARD)
uptr->u3 &= ~END_CARD_EN;
if (*data & EN_TROUBLE)
uptr->u3 |= TROUBLE_EN;
if (*data & DIS_TROUBLE)
uptr->u3 &= ~TROUBLE_EN;
if (*data & EJECT && uptr->u3 & CARD_IN_PUNCH) {
uptr->u4 = 80;
uptr->u3 &= ~DATA_REQ;
sim_activate(uptr, uptr->wait);
}
if ((uptr->u3 & (TROUBLE|TROUBLE_EN)) == (TROUBLE|TROUBLE_EN))
set_interrupt(CP_DEVNUM, uptr->u3);
if ((uptr->u3 & (END_CARD|END_CARD_EN)) == (END_CARD|END_CARD_EN))
set_interrupt(CP_DEVNUM, uptr->u3);
if (*data & PUNCH_ON) {
uptr->u3 |= PUNCH_ON;
sim_activate(uptr, uptr->wait);
}
break;
@ -176,6 +167,8 @@ t_stat cdp_devio(uint32 dev, uint64 *data) {
dp->image[uptr->u4++] = *data & 0xfff;
uptr->u3 &= ~DATA_REQ;
clr_interrupt(dev);
sim_debug(DEBUG_DATAIO, &cp_dev, "CP: DATAO %012llo %d\n", *data,
uptr->u4);
sim_activate(uptr, uptr->wait);
break;
}
@ -184,68 +177,69 @@ t_stat cdp_devio(uint32 dev, uint64 *data) {
/* Handle transfer of data for card punch */
t_stat
cdp_srv(UNIT *uptr) {
int u = (uptr - cdp_unit);
cp_srv(UNIT *uptr) {
if (uptr->u5 & URCSTA_BUSY) {
/* Done waiting, punch card */
if (uptr->u5 & URCSTA_FULL) {
switch(sim_punch_card(uptr, NULL)) {
case SCPE_EOF:
case SCPE_UNATT:
chan_set_eof(chan);
break;
/* If we get here, something is wrong */
case SCPE_IOERR:
chan_set_error(chan);
break;
case SCPE_OK:
break;
}
uptr->u5 &= ~URCSTA_FULL;
if (uptr->u3 & PUNCH_ON) {
uptr->u3 |= CARD_IN_PUNCH;
if (uptr->u3 & DATA_REQ) {
sim_activate(uptr, uptr->wait);
return SCPE_OK;
}
if (uptr->u4 < 80) {
if ((uptr->u3 & DATA_REQ) == 0) {
uptr->u3 |= DATA_REQ;
set_interrupt(CP_DEVNUM, uptr->u3);
}
sim_activate(uptr, uptr->wait);
return SCPE_OK;
}
uptr->u4 = 0;
uptr->u3 &= ~(PUNCH_ON|CARD_IN_PUNCH);
uptr->u3 |= END_CARD;
switch(sim_punch_card(uptr, NULL)) {
case SCPE_EOF:
case SCPE_UNATT:
uptr->u3 |= PICK_FAIL|TROUBLE;
break;
/* If we get here, something is wrong */
case SCPE_IOERR:
uptr->u3 |= EJECT_FAIL|TROUBLE;
break;
case SCPE_OK:
break;
}
uptr->u5 &= ~URCSTA_BUSY;
if ((uptr->u3 & (TROUBLE|TROUBLE_EN)) == (TROUBLE|TROUBLE_EN))
set_interrupt(CP_DEVNUM, uptr->u3);
if (uptr->u3 & END_CARD_EN)
set_interrupt(CP_DEVNUM, uptr->u3);
}
/* Copy next column over */
if (uptr->u5 & URCSTA_WRITE && uptr->u4 < 80) {
struct _card_data *data;
uint8 ch = 0;
data = (struct _card_data *)uptr->up7;
sim_activate(uptr, uptr->wait);
}
return SCPE_OK;
}
void
cdp_ini(UNIT *uptr, t_bool f) {
}
t_stat
cdp_attach(UNIT * uptr, CONST char *file)
cp_attach(UNIT * uptr, CONST char *file)
{
t_stat r;
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r;
uptr->u5 = 0;
uptr->u3 = 0;
uptr->u4 = 0;
return SCPE_OK;
}
t_stat
cdp_detach(UNIT * uptr)
cp_detach(UNIT * uptr)
{
if (uptr->u5 & URCSTA_FULL)
if (uptr->u3 & CARD_IN_PUNCH)
sim_punch_card(uptr, NULL);
return sim_card_detach(uptr);
}
t_stat
cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
cp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "Card Punch\n\n");
fprint_set_help(st, dptr);
@ -254,7 +248,7 @@ cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
}
const char *
cdp_description(DEVICE *dptr)
cp_description(DEVICE *dptr)
{
return "Card Punch";
}

View File

@ -374,9 +374,9 @@ int opflags[] = {
0, 0, 0, 0,
#endif
/* UFA */ /* DFN */ /* FSC */ /* IBP */
FCE|FBR, FCE|FAC|SAC, FAC|SAC, FCEPSE,
FCE|FBR, FCE|FAC|SAC, FAC|SAC, 0,
/* ILDB */ /* LDB */ /* IDPB */ /* DPB */
FCEPSE, FCE, FCEPSE, FCE,
0, 0, 0, 0,
/* FAD */ /* FADL */ /* FADM */ /* FADB */
SAC|FBR|FCE, SAC|SAC2|FBR|FCE, FCEPSE|FBR, SAC|FBR|FCEPSE,
/* FADR */ /* FADRI */ /* FADRM */ /* FADRB */
@ -984,7 +984,7 @@ t_stat null_dev(uint32 dev, uint64 *data) {
/*
* Handle page lookup on KI10
*/
int page_lookup(int addr, int flag, int *loc, int wr, int fetch) {
int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) {
uint64 data;
int base;
int page = addr >> 9;
@ -995,7 +995,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int fetch) {
if (page_fault)
return 0;
if (uf || ((xct_flag & 1) && !fetch && ((wr == 0) || modify)) ||
if (uf || ((xct_flag & 1) && !cur_context && ((wr == 0) || modify)) ||
((xct_flag & 2) && wr)) {
base = ub_ptr;
uf = 1;
@ -1039,7 +1039,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int fetch) {
private_page = 1;
// fprintf(stderr, " public");
}
if (fetch && ((data & 0200000) != 0))
if (cur_context && ((data & 0200000) != 0))
FLAGS |= PUBLIC;
if ((data & LSIGN) == 0 || (wr & ((data & 0100000) == 0))) {
fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 28) | 020LL;
@ -1123,7 +1123,7 @@ int Mem_write_nopage() {
/*
* Translation logic for KA10
*/
int page_lookup(int addr, int flag, int *loc, int wr, int fetch) {
int page_lookup(int addr, int flag, int *loc, int wr, int cur_context) {
if (!flag && (FLAGS & USER) != 0) {
if (addr <= ((Pl << 10) + 01777))
*loc = (AB + (Rl << 10)) & RMASK;
@ -1152,7 +1152,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int fetch) {
*
* Return of 0 if successful, 1 if there was an error.
*/
int Mem_read(int flag, int fetch) {
int Mem_read(int flag, int cur_context) {
int addr;
if (AB < 020) {
@ -1160,7 +1160,7 @@ int Mem_read(int flag, int fetch) {
if (FLAGS & USER) {
MB = get_reg(AB);
return 0;
} else if (xct_flag & 1 && !fetch) {
} else if (xct_flag & 1 && !cur_context) {
if (FLAGS & USERIO) {
if (fm_sel == 0)
goto read;
@ -1175,7 +1175,7 @@ int Mem_read(int flag, int fetch) {
} else {
read:
sim_interval--;
if (!page_lookup(AB, flag, &addr, 0, fetch))
if (!page_lookup(AB, flag, &addr, 0, cur_context))
return 1;
if (addr >= (int)MEMSIZE) {
nxm_flag = 1;
@ -1192,7 +1192,7 @@ read:
*
* Return of 0 if successful, 1 if there was an error.
*/
int Mem_write(int flag) {
int Mem_write(int flag, int cur_context) {
int addr;
if (AB < 020) {
@ -1200,7 +1200,8 @@ int Mem_write(int flag) {
if (FLAGS & USER) {
set_reg(AB, MB);
return 0;
} else if (((xct_flag & 1) && modify) || (xct_flag & 2)) {
} else if (!cur_context &&
((xct_flag & 1) && modify) || (xct_flag & 2)) {
if (FLAGS & USERIO) {
if (fm_sel == 0)
goto write;
@ -1216,7 +1217,7 @@ int Mem_write(int flag) {
} else {
write:
sim_interval--;
if (!page_lookup(AB, flag, &addr, 1, 0))
if (!page_lookup(AB, flag, &addr, 1, cur_context))
return 1;
#if KI | KL
if (private_page)
@ -1279,6 +1280,10 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */
pi_rq = 0;
pi_ov = 0;
BYF5 = 0;
#if KI | KL
private_page = 0;
page_fault = 0;
#endif
while ( reason == 0) { /* loop until ABORT */
if (sim_interval <= 0) { /* check clock queue */
@ -1293,6 +1298,26 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */
break;
}
#if KI | KL
/* Handle page fault and traps */
if (page_enable && (page_fault || private_page || (FLAGS & (TRP1|TRP2)))) {
if (page_fault || private_page) {
page_fault = private_page = 0;
AB = ub_ptr + (FLAGS & USER) ? 0427 : 0426;
MB = fault_data;
Mem_write_nopage();
AB = 0420;
} else {
AB = 0420 + ((FLAGS & (TRP1|TRP2)) >> 2);
FLAGS &= ~(TRP1|TRP2);
}
f_pc_inh = 1;
trap_flag = 1;
AB += (FLAGS & USER) ? ub_ptr : eb_ptr;
Mem_read_nopage();
goto no_fetch;
}
#endif
/* Normal instruction */
if (f_load_pc) {
@ -1306,18 +1331,11 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */
if (f_inst_fetch) {
fetch:
#if KI | KL
private_page = 0;
page_fault = 0;
#endif
Mem_read(pi_cycle | uuo_cycle, 1);
no_fetch:
IR = (MB >> 27) & 0777;
AC = (MB >> 23) & 017;
i_flags = opflags[IR];
#if KI | KL
FLAGS &= ~(TRP1|TRP2);
#endif
BYF5 = 0;
}
@ -1361,7 +1379,7 @@ no_fetch:
if (IR != 0254)
AR &= RMASK;
if (ind & !pi_rq)
if (Mem_read(pi_cycle | uuo_cycle, 0))
if (Mem_read(pi_cycle | uuo_cycle, 1))
goto last;
/* Handle events during a indirect loop */
if (sim_interval-- <= 0) {
@ -1418,12 +1436,14 @@ fetch_opr:
/* Set up to execute instruction */
f_inst_fetch = 1;
f_load_pc = 1;
f_pc_inh = 0;
nrf = 0;
fxu_hold_set = 0;
sac_inh = 0;
#if KI | KL
modify = 0;
f_pc_inh = trap_flag;
#else
f_pc_inh = 0;
#endif
/* Load pseudo registers based on flags */
if (i_flags & (FCEPSE|FCE)) {
@ -1525,7 +1545,7 @@ unasign:
}
#endif
AB = 040;
Mem_write(uuo_cycle);
Mem_write(uuo_cycle, 0);
AB += 1;
f_load_pc = 0;
f_pc_inh = 1;
@ -1739,7 +1759,7 @@ dpnorm:
/* Handle each half as seperate instruction */
if ((FLAGS & BYTI) == 0) {
MB = AR;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
FLAGS |= BYTI;
#if KI /* KL does this in one shot */
@ -1750,7 +1770,7 @@ dpnorm:
if ((FLAGS & BYTI)) {
AB = (AB + 1) & RMASK;
MB = MQ;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
FLAGS &= ~BYTI;
}
@ -1766,7 +1786,7 @@ dpnorm:
AR = BR;
AR &= FMASK;
MB = AR;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
FLAGS |= BYTI;
#if KI
@ -1778,7 +1798,7 @@ dpnorm:
MQ = (CM(MQ) + 1) & CMASK;
AB = (AB + 1) & RMASK;
MB = MQ;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
FLAGS &= ~BYTI;
}
@ -1840,7 +1860,7 @@ unasign:
MB = ((uint64)(IR) << 27) | ((uint64)(AC) << 23) | (uint64)(AB);
AB = 060;
uuo_cycle = 1;
Mem_write(uuo_cycle);
Mem_write(uuo_cycle, 0);
AB += 1;
f_load_pc = 0;
f_pc_inh = 1;
@ -1851,6 +1871,12 @@ unasign:
case 0134: /* ILDB */
case 0136: /* IDPB */
if ((FLAGS & BYTI) == 0) { /* BYF6 */
if (Mem_read(0, 1))
goto last;
AR = MB;
#if KI | KL
modify = 1;
#endif
SC = (AR >> 24) & 077;
SCAD = (((AR >> 30) & 077) + (0777 ^ SC) + 1) & 0777;
if (SCAD & 0400) {
@ -1864,6 +1890,9 @@ unasign:
SC = SCAD;
AR &= PMASK;
AR |= (uint64)(SC & 077) << 30;
MB = AR;
if (Mem_write(0, 1))
goto last;
if ((IR & 04) == 0)
break;
}
@ -1871,6 +1900,9 @@ unasign:
case 0135:/* LDB */
case 0137:/* DPB */
if (((FLAGS & BYTI) == 0) | !BYF5) {
if (Mem_read(0, 1))
goto last;
AR = MB;
SC = (AR >> 30) & 077;
MQ = (uint64)(1) << ( 077 & (AR >> 24));
MQ -= 1;
@ -1902,7 +1934,7 @@ unasign:
AR &= FMASK;
BR |= AR & MQ;
MB = BR;
Mem_write(0);
Mem_write(0, 0);
}
FLAGS &= ~BYTI; /* BYF6 */
BYF5 = 0;
@ -1920,7 +1952,7 @@ unasign:
BR = AR;
AR = AD;
MB = BR;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
break;
#endif
@ -2665,7 +2697,7 @@ fxnorm:
if (Mem_read(0, 0))
break;
AB = (AR & RMASK);
if (Mem_write(0))
if (Mem_write(0, 0))
break;
AD = (AR & RMASK) + CM(BR) + 1;
AR = AOB(AR);
@ -2811,7 +2843,7 @@ fxnorm:
if (uuo_cycle | pi_cycle) {
FLAGS &= ~(USER|PUBLIC); /* Clear USER */
}
Mem_write(uuo_cycle | pi_cycle);
Mem_write(uuo_cycle | pi_cycle, 0);
PC = BR & RMASK;
f_pc_inh = 1;
break;
@ -2830,7 +2862,7 @@ fxnorm:
}
AR &= FMASK;
MB = BR;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
break;
@ -2840,7 +2872,7 @@ fxnorm:
goto last;
AR = SOB(AR);
AB = BR & RMASK;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
if ((AR & C1) == 0) {
#if KI | KL
@ -3434,7 +3466,7 @@ test_op:
}
AR &= FMASK;
MB = AR;
if (Mem_write(pi_cycle))
if (Mem_write(pi_cycle, 0))
break;
AB = AR & RMASK;
goto fetch_opr;
@ -3442,7 +3474,7 @@ test_op:
case 1: /* 04 DATAI */
dev_tab[d](DATAI|(d<<2), &AR);
MB = AR;
Mem_write(pi_cycle);
Mem_write(pi_cycle, 0);
break;
case 3: /* 14 DATAO */
if (Mem_read(pi_cycle, 0))
@ -3456,7 +3488,7 @@ test_op:
case 5: /* 24 CONI */
dev_tab[d](CONI|(d<<2), &AR);
MB = AR;
Mem_write(pi_cycle);
Mem_write(pi_cycle, 0);
break;
case 6: /* 30 CONSZ */
dev_tab[d](CONI|(d<<2), &AR);
@ -3474,9 +3506,10 @@ test_op:
}
break;
}
if (!sac_inh && (i_flags & (SCE|FCEPSE))) {
MB = AR;
if (Mem_write(0))
if (Mem_write(0, 0))
goto last;
}
if (!sac_inh && ((i_flags & SAC) || ((i_flags & SACZ) && AC != 0)))
@ -3492,42 +3525,19 @@ test_op:
last:
#if KI | KL
/* Handle page fault and traps */
if (page_enable && (page_fault || private_page || (FLAGS & (TRP1|TRP2)))) {
if (page_fault || private_page) {
page_fault = private_page = 0;
if (pi_cycle) {
inout_fail = 1;
fprintf (stderr, "I/O Page fault PC=%06o\n", PC);
goto last2;
}
AB = ub_ptr + (FLAGS & USER) ? 0427 : 0426;
MB = fault_data;
Mem_write_nopage();
AB = 0420;
} else {
AB = 0420 + ((FLAGS & (TRP1|TRP2)) >> 2);
}
f_pc_inh = 1;
f_load_pc = 0;
f_inst_fetch = 0;
trap_flag = 1;
AB += (FLAGS & USER) ? ub_ptr : eb_ptr;
Mem_read_nopage();
goto no_fetch;
}
last2:
check_apr_irq();
#endif
if (!f_pc_inh & !pi_cycle) {
if (!f_pc_inh && !pi_cycle) {
PC = (PC + 1) & RMASK;
}
/* Dismiss an interrupt */
if (pi_cycle) {
#if KI | KL
if (page_enable && (page_fault || private_page)) {
page_fault = private_page = 0;
inout_fail = 1;
}
#endif
if ((IR & 0700) == 0700 && ((AC & 04) == 0)) {
pi_hold = pi_ov;
if (!pi_hold & f_inst_fetch) {

View File

@ -1,4 +1,4 @@
/* ka10_cdr.c: PDP10 Card reader.
/* ka10_cr.c: PDP10 Card reader.
Copyright (c) 2016, Richard Cornwell
@ -32,20 +32,20 @@
#include "ka10_defs.h"
#include "sim_card.h"
#include "sim_defs.h"
#ifdef NUM_DEVS_CDR
#if (NUM_DEVS_CR > 0)
#define UNIT_CDR UNIT_ATTABLE | UNIT_RO | UNIT_DISABLE | \
UNIT_ROABLE | MODE_026
UNIT_ROABLE | MODE_029
#define CDR_DEVNUM 0150
#define CR_DEVNUM 0150
/* std devices. data structures
cdr_dev Card Reader device descriptor
cdr_unit Card Reader unit descriptor
cdr_reg Card Reader register list
cdr_mod Card Reader modifiers list
cr_dev Card Reader device descriptor
cr_unit Card Reader unit descriptor
cr_reg Card Reader register list
cr_mod Card Reader modifiers list
*/
/* CONO Bits */
@ -56,7 +56,7 @@
#define EN_READY 0000100 /* Enable ready irq */
#define CLR_DATA_MISS 0000200 /* Clear data miss */
#define EN_TROUBLE 0000400 /* Enable trouble IRQ */
#define READ_CARD 0001000 /* Read in card */
#define READ_CARD 0001000 /* Read card */
#define OFFSET_CARD 0004000
#define CLR_READER 0010000 /* Clear reader */
/* CONI Bits */
@ -68,87 +68,98 @@
#define TROUBLE 00000400 /* Trouble */
#define READING 00001000 /* Reading card */
#define HOPPER_EMPTY 00002000
#define CARD_READ 00004000 /* Card in reader */
#define CARD_IN_READ 00004000 /* Card in reader */
#define STOP 00010000
#define MOTION_ERROR 00020000
#define CELL_ERROR 00040000
#define PICK_ERROR 00100000
#define RDY_READ_EN 00200000
#define TROUBLE_EN 00400000
#define READ_CARD 01000000
t_stat cr_devio(uint32 dev, uint64 *data);
t_stat cr_srv(UNIT *);
t_stat cr_reset(DEVICE *);
t_stat cr_attach(UNIT *, CONST char *);
t_stat cr_detach(UNIT *);
t_stat cr_help(FILE *, DEVICE *, UNIT *, int32, const char *);
const char *cr_description(DEVICE *dptr);
/* Device status information stored in u5 */
#define URCSTA_EOF 0001 /* Hit end of file */
#define URCSTA_ERR 0002 /* Error reading record */
#define URCSTA_CARD 0004 /* Unit has card in buffer */
#define URCSTA_FULL 0004 /* Unit has full buffer */
#define URCSTA_BUSY 0010 /* Device is busy */
DIB cr_dib = { CR_DEVNUM, 1, cr_devio, NULL};
t_stat cdr_devio(uint32 dev, uint64 *data);
t_stat cdr_srv(UNIT *);
t_stat cdr_reset(DEVICE *);
t_stat cdr_attach(UNIT *, CONST char *);
t_stat cdr_detach(UNIT *);
t_stat cdr_help(FILE *, DEVICE *, UNIT *, int32, const char *);
const char *cdr_description(DEVICE *dptr);
DIB cdr_dib = { CDR_DEVNUM, 1, cdr_devio, NULL};
UNIT cdr_unit[] = {
{UDATA(cdr_srv, UNIT_S_CHAN(CHAN_CHUREC) | UNIT_CDR, 0), 300}, /* A */
UNIT cr_unit = {
UDATA(cr_srv, UNIT_CDR, 0), 300,
};
MTAB cdr_mod[] = {
MTAB cr_mod[] = {
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_card_set_fmt, &sim_card_show_fmt, NULL},
{0}
};
DEVICE cdr_dev = {
"CR", cdr_unit, NULL, cdr_mod,
NUM_DEVS_CDR, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &cdr_attach, &sim_card_detach,
&cdr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
NULL, NULL, &cdr_help, NULL, NULL, &cdr_description
DEVICE cr_dev = {
"CR", &cr_unit, NULL, cr_mod,
NUM_DEVS_CR, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &cr_attach, &sim_card_detach,
&cr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
NULL, NULL, &cr_help, NULL, NULL, &cr_description
};
/*
* Device entry points for card reader.
*/
t_stat cdr_devio(uint32 dev, uint64 *data) {
UNIT *uptr = &cdr_unit;
t_stat cr_devio(uint32 dev, uint64 *data) {
UNIT *uptr = &cr_unit;
switch(dev & 3) {
case CONI:
*data = uptr->STATUS;
if (uptr->flags & UNIT_ATT &&
(uptr->u3 & (READING|CARD_IN_READ|END_CARD)) == 0)
uptr->u3 |= RDY_READ;
*data = uptr->u3;
if (uptr->u3 & RDY_READ_EN && uptr->u3 & RDY_READ)
set_interrupt(dev, uptr->u3);
sim_debug(DEBUG_CONI, &cr_dev, "CR: CONI %012llo\n", *data);
break;
case CONO:
clr_interrupt(dev);
fprintf(stderr, "PT: CONO %012llo\n\r", *data);
uptr->STATUS = (PI_DONE|DONE_FLG|BUSY_FLG|BIN_FLG) & *data;
if ((uptr->flags & UNIT_ATT))
uptr->STATUS |= TAPE_PR;
if (uptr->STATUS & BUSY_FLG) {
uptr->CHR = 0;
uptr->CHL = 0;
sim_activate (&ptr_unit, ptr_unit.wait);
sim_debug(DEBUG_CONO, &cr_dev, "CR: CONO %012llo\n", *data);
if (*data & CLR_READER) {
uptr->u3 = 0;
sim_cancel(uptr);
break;
}
if (uptr->STATUS & DONE_FLG)
set_interrupt(dev, uptr->STATUS);
uptr->u3 &= ~(PIA);
uptr->u3 |= *data & PIA;
uptr->u3 &= ~(*data & (CLR_DRDY|CLR_END_CARD|CLR_EOF|CLR_DATA_MISS));
if (*data & EN_TROUBLE)
uptr->u3 |= TROUBLE_EN;
if (*data & EN_READY)
uptr->u3 |= RDY_READ_EN;
if (*data & READ_CARD) {
uptr->u3 |= READING;
uptr->u3 &= ~(CARD_IN_READ|RDY_READ|DATA_RDY);
uptr->u4 = 0;
sim_activate(uptr, uptr->wait);
}
if (uptr->flags & UNIT_ATT &&
(uptr->u3 & (READING|CARD_IN_READ|END_CARD)) == 0)
uptr->u3 |= RDY_READ;
if (uptr->u3 & RDY_READ_EN && uptr->u3 & RDY_READ)
set_interrupt(dev, uptr->u3);
if (uptr->u3 & TROUBLE_EN &&
(uptr->u3 & (END_CARD|END_FILE|DATA_MISS|TROUBLE)) != 0)
set_interrupt(dev, uptr->u3);
break;
case DATAI:
if ((uptr->STATUS & DONE_FLG)) {
*data = ((uint64)uptr->CHL) << 18;
*data |= ((uint64)uptr->CHR);
fprintf(stderr, "PT: DATAI %012llo\n\r", *data);
uptr->STATUS |= BUSY_FLG;
uptr->STATUS &= ~DONE_FLG;
clr_interrupt(dev);
sim_activate (&ptr_unit, ptr_unit.wait);
}
clr_interrupt(dev);
if (uptr->u3 & DATA_RDY) {
*data = uptr->u5;
sim_debug(DEBUG_DATAIO, &cr_dev, "CR: DATAI %012llo\n", *data);
uptr->u3 &= ~DATA_RDY;
} else
*data = 0;
break;
case DATAO:
break;
@ -158,63 +169,69 @@ t_stat cdr_devio(uint32 dev, uint64 *data) {
/* Handle transfer of data for card reader */
t_stat
cdr_srv(UNIT *uptr) {
int u = (uptr - cdr_unit);
cr_srv(UNIT *uptr) {
struct _card_data *data;
data = (struct _card_data *)uptr->up7;
if (uptr->u3 & URCSTA_BUSY) {
uptr->u3 &= ~URCSTA_BUSY;
}
/* Check if new card requested. */
if (uptr->u4 == 0 &&
(uptr->u3 & (READ_CARD|CARD_READ)) == READ_CARD) {
if ((uptr->u3 & (READING|CARD_IN_READ)) == READING) {
switch(sim_read_card(uptr)) {
case SCPE_EOF:
uptr->u3 |= END_FILE;
if (uptr->u3 & TROUBLE_EN)
set_interrupt(CR_DEVNUM, uptr->u3);
return SCPE_OK;
case SCPE_UNATT:
return SCPE_OK;
case SCPE_IOERR:
uptr->u3 |= TROUBLE;
if (uptr->u3 & TROUBLE_EN)
set_interrupt(CR_DEVNUM, uptr->u3);
return SCPE_OK;
case SCPE_OK:
uptr->u3 |= CARD_READ;
uptr->u3 &= ~READ_CARD;
uptr->u3 |= CARD_IN_READ;
break;
}
uptr->u4 = 0;
sim_activate(uptr, uptr->wait);
return SCPE_OK;
}
/* Copy next column over */
if (uptr->u3 & CARD_READ) {
if (uptr->u3 & CARD_IN_READ) {
if (uptr->u4 >= 80) {
uptr->u3 &= ~(CARD_IN_READ|READING);
uptr->u3 |= END_CARD;
set_interrupt(CR_DEVNUM, uptr->u3);
sim_activate(uptr, uptr->wait);
return SCPE_OK;
}
uptr->u5 = data->image[uptr->u4++];
if (uptr->u3 & DATA_RDY) {
uptr->u3 |= DATA_MISS;
}
uptr->u3 |= DATA_RDY;
sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %03x\n", u, uptr->u5);
sim_debug(DEBUG_DATA, &cr_dev, "CR Char > %d %03x\n", uptr->u4, uptr->u5);
set_interrupt(CR_DEVNUM, uptr->u3);
sim_activate(uptr, uptr->wait);
}
return SCPE_OK;
}
t_stat
cdr_attach(UNIT * uptr, CONST char *file)
cr_attach(UNIT * uptr, CONST char *file)
{
t_stat r;
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r;
uptr->u3 &= URCSTA_BUSY;
uptr->u4 = 0;
uptr->u6 = 0;
uptr->u3 |= RDY_READ;
return SCPE_OK;
}
t_stat
cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
cr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "Card Reader\n\n");
fprintf (st, "The system supports one card reader.\n");
@ -224,7 +241,7 @@ cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
}
const char *
cdr_description(DEVICE *dptr)
cr_description(DEVICE *dptr)
{
return "Card Reader";
}

View File

@ -104,12 +104,13 @@
#define DEBUG_DATA 0x0000002 /* Show data transfers */
#define DEBUG_DETAIL 0x0000004 /* Show details */
#define DEBUG_EXP 0x0000008 /* Show error conditions */
#define DEBUG_CONI 0x0000010 /* Show CONI instructions */
#define DEBUG_CONO 0x0000020 /* Show CONO instructions */
#define DEBUG_DATAIO 0x0000040 /* Show DATAI/O instructions */
#define DEBUG_IRQ 0x0000080 /* Show IRQ requests */
#define DEBUG_CONI 0x0000020 /* Show CONI instructions */
#define DEBUG_CONO 0x0000040 /* Show CONO instructions */
#define DEBUG_DATAIO 0x0000080 /* Show DATAI/O instructions */
#define DEBUG_IRQ 0x0000100 /* Show IRQ requests */
extern DEBTAB dev_debug[];
extern DEBTAB crd_debug[];
/* Operating system flags, kept in cpu_unit.flags */
@ -253,6 +254,8 @@ extern DEVICE rpd_dev;
extern DEVICE lpt_dev;
extern DEVICE ptp_dev;
extern DEVICE ptr_dev;
extern DEVICE cr_dev;
extern DEVICE cp_dev;
extern DEVICE rca_dev;
extern DEVICE rcb_dev;
extern DEVICE dc_dev;
@ -301,6 +304,8 @@ int df10_write(struct df10 *df);
#define NUM_DEVS_DP 2
#define NUM_DEVS_LP 1
#define NUM_DEVS_PT 1
#define NUM_DEVS_CR 1
#define NUM_DEVS_CP 1
#define NUM_DEVS_DC 1
#define NUM_DEVS_RC 1
#define NUM_DEVS_DT 0

View File

@ -25,6 +25,7 @@
*/
#include "ka10_defs.h"
#include "sim_card.h"
#include <ctype.h>
@ -66,6 +67,12 @@ DEVICE *sim_devices[] = {
#if (NUM_DEVS_LP > 0)
&lpt_dev,
#endif
#if (NUM_DEVS_CR > 0)
&cr_dev,
#endif
#if (NUM_DEVS_CP > 0)
&cp_dev,
#endif
#if (NUM_DEVS_MT > 0)
&mt_dev,
#endif
@ -130,6 +137,18 @@ DEBTAB dev_debug[] = {
{0, 0}
};
/* Simulator debug controls */
DEBTAB crd_debug[] = {
{"CMD", DEBUG_CMD, "Show command execution to devices"},
{"DATA", DEBUG_DATA, "Show data transfers"},
{"DETAIL", DEBUG_DETAIL, "Show details about device"},
{"EXP", DEBUG_EXP, "Show exception information"},
{"CONI", DEBUG_CONI, "Show coni instructions"},
{"CONO", DEBUG_CONO, "Show coni instructions"},
{"DATAIO", DEBUG_DATAIO, "Show datai and datao instructions"},
{"CARD", DEBUG_CARD, "Show Card read/punches"},
{0, 0}
};
/* Binary loader, supports RIM10, SAV, EXE */