I7000: Initial release of a set of simulators for IBM 7000 series mainframes.
These include simulators for the IBM 701, IBM 702, IBM 704, IBM 705, IBM 705/3, IBM 709, IBM 1410/IBM 7010, IBM 7070, IBM 7080, IBM 7090 and IBM7094. These basically were a collection of machines that shared a common set it peripherals, Each group had its own instruction set, hence different simulators. IBM 701 -> i701 IBM 702/705/705/3/7080 -> i7080 IBM 7070/7074 -> i7070 IBM 1410/7010 -> i7010 IBM 704 -> i704 IBM 704/709/7090/7094 -> i7090 The i7090 can be set to simulate a IBM 704 however you end up disabling almost everything, since the 704 did not have any channels. A build option exists that allows this one to be built without all the extra features. The i7090 simulator’s implementation of the IBM 7094 is a more complete implementation of the IBM 7094 which can run CTSS while the existing simh I7094 can’t.
This commit is contained in:
parent
e78ef46ccb
commit
b5ea9ec38e
51 changed files with 40064 additions and 2 deletions
54
I7000/README.md
Normal file
54
I7000/README.md
Normal file
|
@ -0,0 +1,54 @@
|
|||
Latest status for I7000 Cpus:
|
||||
|
||||
## i701
|
||||
|
||||
* Largely untested.
|
||||
|
||||
## i704
|
||||
* SAP works.
|
||||
* Fort2 unfinished.
|
||||
|
||||
## i7010
|
||||
* PR155 works.
|
||||
* PR108 works.
|
||||
* Most Diags appear to pass without serious error.
|
||||
* Protection mode has some errors left.
|
||||
* Protection mode does not handle setting H or L to 0.
|
||||
|
||||
## i7070
|
||||
* Will load Diags, need to remember how to run them to run
|
||||
* tests on machine.
|
||||
|
||||
## i7080
|
||||
* Sort of working.
|
||||
* RWW, ECB untested.
|
||||
* TLx instructions implimented, untested, see 8SE
|
||||
* Will boot from card.
|
||||
* Tape system appear to be working.
|
||||
|
||||
* 8CU10B errors:
|
||||
410, 412, 413, 414, 418, 419, 420-427 error becuase
|
||||
storage is not parity checked.
|
||||
440 divide not producing correct sign on error.
|
||||
|
||||
## i7090
|
||||
* Working with exceptions.
|
||||
|
||||
* Known bugs:
|
||||
|
||||
* DFDP/DFMP Sometimes off by +/-1 or 2 in least signifigant part of result.
|
||||
* EAD +n + -n should be -0 is +0
|
||||
* Not all channel skips working for 9P01C.
|
||||
* HTx Not sure what problems are, does not quite work.
|
||||
* DKx Sometimes fails diagnostics with missing inhibit of interrupt.
|
||||
|
||||
* CTSS works.
|
||||
|
||||
* IBSYS works.
|
||||
|
||||
* Stand alone assembler works.
|
||||
|
||||
* Lisp 1.5 works.
|
||||
|
||||
* Signifigence mode Not tested, Test Code Needed.
|
||||
|
363
I7000/i7000_cdp.c
Normal file
363
I7000/i7000_cdp.c
Normal file
|
@ -0,0 +1,363 @@
|
|||
/* i7000_cdp.c: IBM 7000 Card Punch
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This is the standard card punch.
|
||||
|
||||
These units each buffer one record in local memory and signal
|
||||
ready when the buffer is full or empty. The channel must be
|
||||
ready to recieve/transmit data when they are activated since
|
||||
they will transfer their block during chan_cmd. All data is
|
||||
transmitted as BCD characters.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7000_defs.h"
|
||||
#include "sim_card.h"
|
||||
#include "sim_defs.h"
|
||||
#ifdef NUM_DEVS_CDP
|
||||
|
||||
#define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE | MODE_026
|
||||
|
||||
|
||||
/* Flags for punch and reader. */
|
||||
#define ATTENA (1 << (UNIT_V_UF+7))
|
||||
#define ATTENB (1 << (UNIT_V_UF+14))
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
uint32 cdp_cmd(UNIT *, uint16, uint16);
|
||||
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 stk_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *stk_description(DEVICE *dptr);
|
||||
|
||||
UNIT cdp_unit[] = {
|
||||
{UDATA(cdp_srv, UNIT_S_CHAN(CHAN_CHUREC) | UNIT_CDP, 0), 600}, /* A */
|
||||
#if NUM_DEVS_CDP > 1
|
||||
{UDATA(cdp_srv, UNIT_S_CHAN(CHAN_CHUREC+1) | UNIT_CDP, 0), 600}, /* B */
|
||||
#endif
|
||||
};
|
||||
|
||||
MTAB cdp_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"},
|
||||
#ifdef I7070
|
||||
{ATTENA|ATTENB,0, NULL, "NOATTEN", NULL, NULL, NULL, "No attention signal"},
|
||||
{ATTENA|ATTENB,ATTENA, "ATTENA", "ATTENA", NULL, NULL, NULL, "Signal Attention A"},
|
||||
{ATTENA|ATTENB,ATTENB, "ATTENB", "ATTENB", NULL, NULL, NULL, "Signal Attention B"},
|
||||
#endif
|
||||
#ifdef I7010
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
||||
&get_chan, NULL, "Set device channel"},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE cdp_dev = {
|
||||
"CDP", 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
|
||||
};
|
||||
|
||||
#ifdef STACK_DEV
|
||||
UNIT stack_unit[] = {
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
{ UDATA (NULL, UNIT_DIS, 0) }, /* unused */
|
||||
};
|
||||
|
||||
DEVICE stack_dev = {
|
||||
"STKR", stack_unit, NULL, NULL,
|
||||
NUM_DEVS_CDP * 10, 10, 31, 1, 8, 7,
|
||||
NULL, NULL, NULL, NULL, &sim_card_attach, &sim_card_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
|
||||
NULL, NULL, &stk_help, NULL, NULL, &stk_description
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Card punch routine
|
||||
|
||||
Modifiers have been checked by the caller
|
||||
C modifier is recognized (column binary is implemented)
|
||||
*/
|
||||
|
||||
|
||||
uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - cdp_unit);
|
||||
int stk = dev & 017;
|
||||
|
||||
/* Are we currently tranfering? */
|
||||
if (uptr->u5 & URCSTA_WRITE)
|
||||
return SCPE_BUSY;
|
||||
|
||||
if (stk == 10)
|
||||
stk = 0;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
#ifdef STACK_DEV
|
||||
if ((stack_unit[stk * u].flags & UNIT_ATT) == 0)
|
||||
#endif
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
switch(cmd) {
|
||||
/* Test ready */
|
||||
case IO_TRS:
|
||||
sim_debug(DEBUG_CMD, &cdp_dev, "%d: Cmd TRS\n", u);
|
||||
return SCPE_OK;
|
||||
|
||||
/* Suppress punch */
|
||||
case IO_RUN:
|
||||
uptr->u5 &= ~URCSTA_FULL;
|
||||
sim_debug(DEBUG_CMD, &cdp_dev, "%d: Cmd RUN\n", u);
|
||||
return SCPE_OK;
|
||||
|
||||
/* Retieve data from CPU */
|
||||
case IO_WRS:
|
||||
#ifdef STACK_DEV
|
||||
uptr->u5 &= ~0xF0000;
|
||||
uptr->u5 |= stk << 16;
|
||||
#endif
|
||||
sim_debug(DEBUG_CMD, &cdp_dev, "%d: Cmd WRS\n", u);
|
||||
chan_set_sel(chan, 1);
|
||||
uptr->u5 |= URCSTA_WRITE;
|
||||
uptr->u4 = 0;
|
||||
if ((uptr->u5 & URCSTA_BUSY) == 0)
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
}
|
||||
chan_set_attn(chan);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
/* Handle transfer of data for card punch */
|
||||
t_stat
|
||||
cdp_srv(UNIT *uptr) {
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - cdp_unit);
|
||||
/* Waiting for disconnect */
|
||||
if (uptr->u5 & URCSTA_WDISCO) {
|
||||
if (chan_stat(chan, DEV_DISCO)) {
|
||||
chan_clear(chan, DEV_SEL|DEV_WEOR);
|
||||
uptr->u5 &= ~ URCSTA_WDISCO;
|
||||
} else {
|
||||
/* No disco yet, try again in a bit */
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
}
|
||||
/* If still busy, schedule another wait */
|
||||
if (uptr->u5 & URCSTA_BUSY)
|
||||
sim_activate(uptr, uptr->wait);
|
||||
}
|
||||
|
||||
if (uptr->u5 & URCSTA_BUSY) {
|
||||
/* Done waiting, punch card */
|
||||
if (uptr->u5 & URCSTA_FULL) {
|
||||
#ifdef STACK_DEV
|
||||
switch(sim_punch_card(uptr,
|
||||
&stack_unit[(u * 10) + ((uptr->u5 >> 16) & 0xf)])) {
|
||||
#else
|
||||
switch(sim_punch_card(uptr, NULL)) {
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
uptr->u5 &= ~URCSTA_BUSY;
|
||||
#ifdef I7070
|
||||
switch(uptr->flags & (ATTENA|ATTENB)) {
|
||||
case ATTENA: chan_set_attn_a(chan); break;
|
||||
case ATTENB: chan_set_attn_b(chan); break;
|
||||
}
|
||||
#endif
|
||||
#ifdef I7010
|
||||
chan_set_attn_urec(chan, cdp_dib.addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
switch(chan_read_char(chan, &ch, 0)) {
|
||||
case TIME_ERROR:
|
||||
case END_RECORD:
|
||||
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
|
||||
uptr->u5 &= ~URCSTA_WRITE;
|
||||
break;
|
||||
case DATA_OK:
|
||||
if (ch == 0)
|
||||
ch = 020;
|
||||
else if (ch == 020)
|
||||
ch = 0;
|
||||
sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch);
|
||||
data->image[uptr->u4++] = sim_bcd_to_hol(ch);
|
||||
if (uptr->u4 == 80) {
|
||||
chan_set(chan, DEV_REOR);
|
||||
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
|
||||
uptr->u5 &= ~URCSTA_WRITE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sim_activate(uptr, 10);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cdp_ini(UNIT *uptr, t_bool f) {
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdp_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u5 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdp_detach(UNIT * uptr)
|
||||
{
|
||||
if (uptr->u5 & URCSTA_FULL)
|
||||
#ifdef STACK_DEV
|
||||
sim_punch_card(uptr, &stack_unit[
|
||||
((uptr - cdp_unit) * 10) + ((uptr->u5 >> 16) & 0xf)]);
|
||||
#else
|
||||
sim_punch_card(uptr, NULL);
|
||||
#endif
|
||||
return sim_card_detach(uptr);
|
||||
}
|
||||
|
||||
#ifdef STACK_DEV
|
||||
t_stat
|
||||
stk_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "%s\n\n", stk_description(dptr));
|
||||
fprintf (st, "Allows stack control functions to direct cards to specific ");
|
||||
fprintf (st, "bins based on stacker\nselection. Attach cards here if you ");
|
||||
fprintf (st, "wish this specific stacker select to recieve\nthis group of");
|
||||
fprintf (st, " cards. If nothing is attached cards will be punched on the");
|
||||
fprintf (st, " default\npunch\n\n");
|
||||
sim_card_attach_help(st, dptr, uptr, flag, cptr);
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
stk_description(DEVICE *dptr)
|
||||
{
|
||||
return "Card stacking device";
|
||||
}
|
||||
#endif
|
||||
|
||||
t_stat
|
||||
cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "%s\n\n", cdp_description(dptr));
|
||||
#ifdef STACK_DEV
|
||||
fprintf (st, "If the punch device is not attached and instead the %s ", stack_dev.name);
|
||||
fprintf (st, "device is attached,\nthe cards will be sent out to the ");
|
||||
fprintf (st, "given stacker based on the flag set by\nthe processor.\n\n");
|
||||
#endif
|
||||
#ifdef I7070
|
||||
fprintf (st, "Unit record devices can be configured to interrupt the CPU on\n");
|
||||
fprintf (st, "one of two priority channels A or B, to set this\n\n");
|
||||
fprintf (st, " sim> SET %s ATTENA to set device to raise Atten A\n\n", dptr->name);
|
||||
#endif
|
||||
#ifdef I7010
|
||||
help_set_chan_type(st, dptr, "Card punches");
|
||||
#endif
|
||||
sim_card_attach_help(st, dptr, uptr, flag, cptr);
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
cdp_description(DEVICE *dptr)
|
||||
{
|
||||
#ifdef I7010
|
||||
return "1402 Card Punch";
|
||||
#endif
|
||||
#ifdef I7070
|
||||
return "7550 Card Punch";
|
||||
#endif
|
||||
#ifdef I7080
|
||||
return "721 Card Punch";
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
408
I7000/i7000_cdr.c
Normal file
408
I7000/i7000_cdr.c
Normal file
|
@ -0,0 +1,408 @@
|
|||
/* i7000_cdr.c: IBM 7000 Card reader.
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This is the standard card reader.
|
||||
|
||||
These units each buffer one record in local memory and signal
|
||||
ready when the buffer is full or empty. The channel must be
|
||||
ready to recieve/transmit data when they are activated since
|
||||
they will transfer their block during chan_cmd. All data is
|
||||
transmitted as BCD characters.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7000_defs.h"
|
||||
#include "sim_card.h"
|
||||
#include "sim_defs.h"
|
||||
#ifdef NUM_DEVS_CDR
|
||||
|
||||
#define UNIT_CDR UNIT_ATTABLE | UNIT_RO | UNIT_DISABLE | \
|
||||
UNIT_ROABLE | MODE_026
|
||||
|
||||
/* Flags for punch and reader. */
|
||||
#define ATTENA (1 << (UNIT_V_UF+7))
|
||||
#define ATTENB (1 << (UNIT_V_UF+14))
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
uint32 cdr_cmd(UNIT *, uint16, uint16);
|
||||
t_stat cdr_boot(int32, DEVICE *);
|
||||
t_stat cdr_srv(UNIT *);
|
||||
t_stat cdr_reset(DEVICE *);
|
||||
t_stat cdr_attach(UNIT *, CONST char *);
|
||||
t_stat cdr_detach(UNIT *);
|
||||
extern t_stat chan_boot(int32, DEVICE *);
|
||||
#ifdef I7070
|
||||
t_stat cdr_setload(UNIT *, int32, CONST char *, void *);
|
||||
t_stat cdr_getload(FILE *, UNIT *, int32, CONST void *);
|
||||
#endif
|
||||
t_stat cdr_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *cdr_description(DEVICE *dptr);
|
||||
|
||||
UNIT cdr_unit[] = {
|
||||
{UDATA(cdr_srv, UNIT_S_CHAN(CHAN_CHUREC) | UNIT_CDR, 0), 300}, /* A */
|
||||
#if NUM_DEVS_CDR > 1
|
||||
{UDATA(cdr_srv, UNIT_S_CHAN(CHAN_CHUREC+1) | UNIT_CDR, 0), 300}, /* B */
|
||||
#endif
|
||||
};
|
||||
|
||||
MTAB cdr_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"},
|
||||
#ifdef I7070
|
||||
{ATTENA|ATTENB, 0, NULL, "NOATTEN", NULL, NULL, NULL, "No attention signal"},
|
||||
{ATTENA|ATTENB, ATTENA, "ATTENA", "ATTENA", NULL, NULL, NULL, "Signal Attention A"},
|
||||
{ATTENA|ATTENB, ATTENB, "ATTENB", "ATTENB", NULL, NULL, NULL, "Signal Attention B"},
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "LCOL", "LCOL", &cdr_setload,
|
||||
&cdr_getload, NULL, "Load card column indicator"},
|
||||
#endif
|
||||
#ifdef I7010
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
||||
&get_chan, NULL, "Set device channel"},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE cdr_dev = {
|
||||
"CDR", cdr_unit, NULL, cdr_mod,
|
||||
NUM_DEVS_CDR, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, NULL, &cdr_boot, &cdr_attach, &sim_card_detach,
|
||||
&cdr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
|
||||
NULL, NULL, &cdr_help, NULL, NULL, &cdr_description
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Device entry points for card reader.
|
||||
*/
|
||||
uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - cdr_unit);
|
||||
int stk = dev & 017;
|
||||
|
||||
/* Are we currently tranfering? */
|
||||
if (uptr->u5 & URCSTA_READ)
|
||||
return SCPE_BUSY;
|
||||
|
||||
/* Test ready */
|
||||
if (cmd == IO_TRS && uptr->flags & UNIT_ATT) {
|
||||
sim_debug(DEBUG_CMD, &cdr_dev, "%d: Test Rdy\n", u);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (stk == 10)
|
||||
stk = 0;
|
||||
|
||||
#ifdef STACK_DEV
|
||||
uptr->u5 &= ~0xF0000;
|
||||
uptr->u5 |= stk << 16;
|
||||
#endif
|
||||
if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR))
|
||||
return SCPE_IOERR;
|
||||
|
||||
/* Process commands */
|
||||
switch(cmd) {
|
||||
case IO_RDS:
|
||||
sim_debug(DEBUG_CMD, &cdr_dev, "%d: Cmd RDS %02o\n", u, dev & 077);
|
||||
#ifdef I7010
|
||||
if (stk!= 9)
|
||||
#endif
|
||||
uptr->u5 &= ~(URCSTA_CARD|URCSTA_ERR);
|
||||
break;
|
||||
case IO_CTL:
|
||||
sim_debug(DEBUG_CMD, &cdr_dev, "%d: Cmd CTL %02o\n", u, dev & 077);
|
||||
#ifdef I7010
|
||||
uptr->u5 |= URCSTA_NOXFER;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
chan_set_attn(chan);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
/* If at eof, just return EOF */
|
||||
if (uptr->u5 & URCSTA_EOF) {
|
||||
chan_set_eof(chan);
|
||||
chan_set_attn(chan);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uptr->u5 |= URCSTA_READ;
|
||||
uptr->u4 = 0;
|
||||
|
||||
if ((uptr->u5 & URCSTA_NOXFER) == 0)
|
||||
chan_set_sel(chan, 0);
|
||||
/* Wake it up if not busy */
|
||||
if ((uptr->u5 & URCSTA_BUSY) == 0)
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Handle transfer of data for card reader */
|
||||
t_stat
|
||||
cdr_srv(UNIT *uptr) {
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - cdr_unit);
|
||||
struct _card_data *data;
|
||||
|
||||
data = (struct _card_data *)uptr->up7;
|
||||
|
||||
/* Waiting for disconnect */
|
||||
if (uptr->u5 & URCSTA_WDISCO) {
|
||||
if (chan_stat(chan, DEV_DISCO)) {
|
||||
chan_clear(chan, DEV_SEL|DEV_WEOR);
|
||||
uptr->u5 &= ~ URCSTA_WDISCO;
|
||||
} else {
|
||||
/* No disco yet, try again in a bit */
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
}
|
||||
/* If still busy, schedule another wait */
|
||||
if (uptr->u5 & URCSTA_BUSY)
|
||||
sim_activate(uptr, uptr->wait);
|
||||
}
|
||||
|
||||
if (uptr->u5 & URCSTA_BUSY) {
|
||||
uptr->u5 &= ~URCSTA_BUSY;
|
||||
#ifdef I7070
|
||||
switch(uptr->flags & (ATTENA|ATTENB)) {
|
||||
case ATTENA: chan_set_attn_a(chan); break;
|
||||
case ATTENB: chan_set_attn_b(chan); break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check if new card requested. */
|
||||
if (uptr->u4 == 0 && uptr->u5 & URCSTA_READ &&
|
||||
(uptr->u5 & URCSTA_CARD) == 0) {
|
||||
switch(sim_read_card(uptr)) {
|
||||
case SCPE_EOF:
|
||||
sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: EOF\n", u);
|
||||
/* Fall through */
|
||||
|
||||
case SCPE_UNATT:
|
||||
chan_set_eof(chan);
|
||||
chan_set_attn(chan);
|
||||
chan_clear(chan, DEV_SEL);
|
||||
uptr->u5 |= URCSTA_EOF;
|
||||
uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
|
||||
return SCPE_OK;
|
||||
case SCPE_IOERR:
|
||||
sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: ERF\n", u);
|
||||
uptr->u5 |= URCSTA_ERR;
|
||||
uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
|
||||
chan_set_attn(chan);
|
||||
chan_clear(chan, DEV_SEL);
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
uptr->u5 |= URCSTA_CARD;
|
||||
#ifdef I7010
|
||||
chan_set_attn_urec(chan, cdr_dib.addr);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef I7070
|
||||
/* Check if load card. */
|
||||
if (uptr->capac && (data->image[uptr->capac-1] & 0x800)) {
|
||||
uptr->u5 |= URCSTA_LOAD;
|
||||
chan_set_load_mode(chan);
|
||||
} else {
|
||||
uptr->u5 &= ~URCSTA_LOAD;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (uptr->u5 & URCSTA_NOXFER) {
|
||||
uptr->u5 &= ~(URCSTA_NOXFER|URCSTA_READ);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Copy next column over */
|
||||
if (uptr->u5 & URCSTA_READ && uptr->u4 < 80) {
|
||||
uint8 ch = 0;
|
||||
|
||||
#ifdef I7080
|
||||
/* Detect RSU */
|
||||
if (data->image[uptr->u4] == 0x924) {
|
||||
uptr->u5 &= ~URCSTA_READ;
|
||||
uptr->u5 |= URCSTA_WDISCO;
|
||||
chan_set(chan, DEV_REOR);
|
||||
sim_activate(uptr, 10);
|
||||
return SCPE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
ch = sim_hol_to_bcd(data->image[uptr->u4]);
|
||||
|
||||
/* Handle invalid punch */
|
||||
if (ch == 0x7f) {
|
||||
#ifdef I7080
|
||||
uptr->u5 &= ~(URCSTA_READ|URCSTA_BUSY);
|
||||
sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: bad punch %d\n", u,
|
||||
uptr->u4);
|
||||
chan_set_attn(chan);
|
||||
chan_set_error(chan);
|
||||
chan_clear(chan, DEV_SEL);
|
||||
#else
|
||||
uptr->u5 |= URCSTA_ERR;
|
||||
ch = 017;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef I7070
|
||||
/* During load, only sign on every 10 columns */
|
||||
if (uptr->u5 & URCSTA_LOAD && (uptr->u4 % 10) != 9)
|
||||
ch &= 0xf;
|
||||
#endif
|
||||
|
||||
switch(chan_write_char(chan, &ch, (uptr->u4 == 79)? DEV_REOR: 0)) {
|
||||
case TIME_ERROR:
|
||||
case END_RECORD:
|
||||
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY;
|
||||
uptr->u5 &= ~URCSTA_READ;
|
||||
break;
|
||||
case DATA_OK:
|
||||
uptr->u4++;
|
||||
break;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %02o\n", u, ch);
|
||||
sim_activate(uptr, 10);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat
|
||||
cdr_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
t_stat r;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
/* Read in one record */
|
||||
r = cdr_cmd(uptr, IO_RDS, cdr_dib.addr);
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
r = chan_boot(unit_num, dptr);
|
||||
return r;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u5 &= URCSTA_BUSY|URCSTA_WDISCO;
|
||||
uptr->u4 = 0;
|
||||
uptr->u6 = 0;
|
||||
#ifdef I7010
|
||||
chan_set_attn_urec(UNIT_G_CHAN(uptr->flags), cdr_dib.addr);
|
||||
#endif
|
||||
return SCPE_OK;
|
||||
}
|
||||
#ifdef I7070
|
||||
t_stat
|
||||
cdr_setload(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int i;
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
i = 0;
|
||||
while(*cptr != '\0') {
|
||||
if (*cptr < '0' || *cptr > '9')
|
||||
return SCPE_ARG;
|
||||
i = (i * 10) + (*cptr++) - '0';
|
||||
}
|
||||
if (i > 80)
|
||||
return SCPE_ARG;
|
||||
uptr->capac = i;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_getload(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "loadcolumn=%d", uptr->capac);
|
||||
return SCPE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
t_stat
|
||||
cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "%s\n\n", cdr_description(dptr));
|
||||
#if NUM_DEVS_CDR > 1
|
||||
fprintf (st, "The system supports up to two card readers.\n");
|
||||
#else
|
||||
fprintf (st, "The system supports one card reader.\n");
|
||||
#endif
|
||||
#ifdef I7070
|
||||
fprintf (st, "Unit record devices can be configured to interrupt the CPU on\n");
|
||||
fprintf (st, "one of two priority channels A or B, to set this\n\n");
|
||||
fprintf (st, " sim> SET %s ATTENA To set device to raise Atten A\n\n", dptr->name);
|
||||
fprintf (st, "The 7500 Card reader supported a load mode, this was\n");
|
||||
fprintf (st, "selected by use of a 12 punch in a given column. When this\n");
|
||||
fprintf (st, "was seen the card was read into 8 words. Normal read is\n");
|
||||
fprintf (st, "text only\n\n");
|
||||
fprintf (st, " sim> SET %s LCOL=72 Sets column to select load mode\n\n", dptr->name);
|
||||
#endif
|
||||
#if NUM_DEVS_CDR > 1
|
||||
#ifdef I7010
|
||||
help_set_chan_type(st, dptr, "Card reader");
|
||||
#endif
|
||||
#endif
|
||||
sim_card_attach_help(st, dptr, uptr, flag, cptr);
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
cdr_description(DEVICE *dptr)
|
||||
{
|
||||
#ifdef I7010
|
||||
return "1402 Card Reader";
|
||||
#endif
|
||||
#ifdef I7070
|
||||
return "7500 Card Reader";
|
||||
#endif
|
||||
#ifdef I7080
|
||||
return "711 Card Reader";
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
511
I7000/i7000_chan.c
Normal file
511
I7000/i7000_chan.c
Normal file
|
@ -0,0 +1,511 @@
|
|||
/* i7000_chan.c: IBM 7000 Channel simulator
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
channel
|
||||
|
||||
Common routines for handling channel functions.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7000_defs.h"
|
||||
|
||||
extern DEVICE *sim_devices[];
|
||||
|
||||
|
||||
|
||||
int num_devs[NUM_CHAN];
|
||||
|
||||
|
||||
t_stat
|
||||
chan_set_devs(DEVICE * dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NUM_CHAN; i++) {
|
||||
num_devs[i] = 0;
|
||||
}
|
||||
/* Build channel array */
|
||||
for (i = 0; sim_devices[i] != NULL; i++) {
|
||||
UNIT *uptr = sim_devices[i]->units;
|
||||
DIB *dibp = (DIB *) sim_devices[i]->ctxt;
|
||||
int ctype;
|
||||
int num;
|
||||
|
||||
/* If no DIB, not channel device */
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
/* Skip channel devices */
|
||||
if (sim_devices[i] == &chan_dev)
|
||||
continue;
|
||||
/* Skip disabled devices */
|
||||
if (sim_devices[i]->flags & DEV_DIS)
|
||||
continue;
|
||||
ctype = dibp->ctype;
|
||||
if (dibp->upc > 1) {
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int type = CHAN_G_TYPE(chan_unit[chan].flags);
|
||||
if (((1 << type) & ctype) == 0) {
|
||||
if ((chan_unit[chan].flags & CHAN_SET) ||
|
||||
((chan_unit[chan].flags & CHAN_AUTO)
|
||||
&& num_devs[chan] != 0)) {
|
||||
for (num = sim_devices[i]->numunits; num > 0; num--)
|
||||
(uptr++)->flags |= UNIT_DIS;
|
||||
goto nextdev;
|
||||
}
|
||||
}
|
||||
/* Set channel to highest type */
|
||||
if ((chan_unit[chan].flags & CHAN_SET) == 0) {
|
||||
/* Set type to highest found */
|
||||
for(type = 7; type >=0; type--)
|
||||
if (ctype & (1 << type))
|
||||
break;
|
||||
chan_unit[chan].flags &= ~(CHAN_MODEL);
|
||||
chan_unit[chan].flags |= CHAN_S_TYPE(type)|CHAN_SET;
|
||||
}
|
||||
num_devs[chan] += sim_devices[i]->numunits;
|
||||
if (dibp->ini != NULL) {
|
||||
for (num = sim_devices[i]->numunits; num > 0; num--) {
|
||||
uptr->flags &= ~UNIT_CHAN;
|
||||
uptr->flags |= UNIT_S_CHAN(chan);
|
||||
dibp->ini(uptr++, 1);
|
||||
}
|
||||
}
|
||||
goto nextdev;
|
||||
}
|
||||
|
||||
for (num = sim_devices[i]->numunits; num > 0; num--) {
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int type = CHAN_G_TYPE(chan_unit[chan].flags);
|
||||
|
||||
if ((uptr->flags & UNIT_DIS) == 0) {
|
||||
if (((1 << type) & ctype) == 0) {
|
||||
if ((chan_unit[chan].flags & CHAN_SET) ||
|
||||
((chan_unit[chan].flags & CHAN_AUTO)
|
||||
&& num_devs[chan] != 0)) {
|
||||
uptr->flags |= UNIT_DIS;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
/* Set channel to highest type */
|
||||
if ((chan_unit[chan].flags & CHAN_SET) == 0) {
|
||||
/* Set type to highest found */
|
||||
for(type = 7; type >=0; type--)
|
||||
if (ctype & (1 << type))
|
||||
break;
|
||||
chan_unit[chan].flags &= ~(CHAN_MODEL);
|
||||
chan_unit[chan].flags |= CHAN_S_TYPE(type)|CHAN_SET;
|
||||
}
|
||||
num_devs[chan]++;
|
||||
if (dibp->ini != NULL)
|
||||
dibp->ini(uptr, 1);
|
||||
}
|
||||
next:
|
||||
uptr++;
|
||||
}
|
||||
nextdev:
|
||||
;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Print help for "SET dev CHAN" based on allowed types */
|
||||
void help_set_chan_type(FILE *st, DEVICE *dptr, const char *name)
|
||||
{
|
||||
#if NUM_CHAN > 1
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
int ctype = dibp->ctype;
|
||||
int i;
|
||||
int m;
|
||||
|
||||
fprintf (st, "Devices can be moved to any channel via the command\n\n");
|
||||
fprintf (st, " sim> SET %s CHAN=x where x is", dptr->name);
|
||||
if (ctype & 3) {
|
||||
if (ctype == 1 || ctype == 2)
|
||||
fprintf(st, " only");
|
||||
fprintf (st, " %s", chname[0]);
|
||||
if ((ctype & ~3) != 0)
|
||||
fprintf(st, " or");
|
||||
}
|
||||
if ((ctype & ~3) != 0)
|
||||
fprintf(st, " %s to %s", chname[1], chname[NUM_CHAN-1]);
|
||||
fprintf (st, "\n\n%s can be attached to ", name);
|
||||
m = 1;
|
||||
for(i = 0; ctype != 0; i++) {
|
||||
if (ctype & m) {
|
||||
fprintf(st, "%s", chan_type_name[i]);
|
||||
ctype &= ~m;
|
||||
if (ctype != 0)
|
||||
fprintf(st, ", or ");
|
||||
}
|
||||
m <<= 1;
|
||||
}
|
||||
fprintf(st, " channel\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Sets the device onto a given channel */
|
||||
t_stat
|
||||
set_chan(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
int newch;
|
||||
int chan;
|
||||
int num;
|
||||
int type;
|
||||
int ctype;
|
||||
int compat;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
chan = UNIT_G_CHAN(uptr->flags);
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
for(newch = 0; newch < NUM_CHAN; newch++)
|
||||
if (strcmp(cptr, chname[newch]) == 0)
|
||||
break;
|
||||
if (newch == NUM_CHAN)
|
||||
return SCPE_ARG;
|
||||
if (newch == chan)
|
||||
return SCPE_OK;
|
||||
|
||||
ctype = dibp->ctype;
|
||||
compat = ctype;
|
||||
|
||||
/* Update the number of devices on this channel */
|
||||
num_devs[newch] = 0;
|
||||
for (num = 0; sim_devices[num] != NULL; num++) {
|
||||
UNIT *u = sim_devices[num]->units;
|
||||
DIB *dibp = (DIB *) sim_devices[num]->ctxt;
|
||||
int units = sim_devices[num]->numunits;
|
||||
|
||||
/* If no DIB, not channel device */
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
/* Skip channel devices */
|
||||
if (sim_devices[num] == &chan_dev)
|
||||
continue;
|
||||
/* Skip disabled devices */
|
||||
if (sim_devices[num]->flags & DEV_DIS)
|
||||
continue;
|
||||
if (dibp->upc > 1) {
|
||||
if ((u->flags & UNIT_DIS) == 0 &&
|
||||
UNIT_G_CHAN(u->flags) == chan) {
|
||||
num_devs[newch] += units;
|
||||
compat &= dibp->ctype;
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < units; i++) {
|
||||
if ((u->flags & UNIT_DIS) == 0 &&
|
||||
UNIT_G_CHAN(u->flags) == chan) {
|
||||
num_devs[newch]++;
|
||||
compat &= dibp->ctype;
|
||||
}
|
||||
u++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If nothing left on channel, drop set bit */
|
||||
if (num_devs[newch] == 0 && chan_unit[newch].flags & CHAN_AUTO) {
|
||||
chan_unit[newch].flags &= ~CHAN_SET;
|
||||
compat = ctype;
|
||||
}
|
||||
|
||||
/* Check if same type or everyone can handle new type */
|
||||
type = CHAN_G_TYPE(chan_unit[newch].flags);
|
||||
if (((1 << type) & ctype) == 0) {
|
||||
/* If set or no common types */
|
||||
if (chan_unit[newch].flags & CHAN_SET && compat == 0)
|
||||
return SCPE_IERR;
|
||||
if ((chan_unit[newch].flags & CHAN_AUTO) &&
|
||||
(compat == 0 && num_devs[newch] != 0))
|
||||
return SCPE_IERR;
|
||||
else {
|
||||
/* Set type to highest compatable type */
|
||||
for(type = 7; type >=0; type--)
|
||||
if (compat >> type)
|
||||
break;
|
||||
chan_unit[newch].flags &= ~(CHAN_MODEL);
|
||||
chan_unit[newch].flags |= CHAN_S_TYPE(type)|CHAN_SET;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set channel to highest type */
|
||||
if ((chan_unit[chan].flags & CHAN_SET) == 0) {
|
||||
/* Set type to highest found */
|
||||
for(type = 7; type >=0; type--)
|
||||
if (ctype >> type)
|
||||
break;
|
||||
chan_unit[chan].flags &= ~(CHAN_MODEL);
|
||||
chan_unit[chan].flags |= CHAN_S_TYPE(type)|CHAN_SET;
|
||||
}
|
||||
|
||||
/* Detach unit from orignal channel */
|
||||
if (dibp->upc > 1)
|
||||
num_devs[chan] -= dptr->numunits;
|
||||
else
|
||||
num_devs[chan]--;
|
||||
if (num_devs[chan] == 0 && (chan_unit[chan].flags & CHAN_AUTO))
|
||||
chan_unit[chan].flags &= ~CHAN_SET;
|
||||
|
||||
/* Hook up to new channel */
|
||||
if (dibp->upc > 1) {
|
||||
uint32 unit;
|
||||
for (unit = 0; unit < dptr->numunits; unit++) {
|
||||
/* Set the new channel */
|
||||
dptr->units[unit].flags &= ~UNIT_CHAN;
|
||||
dptr->units[unit].flags |= UNIT_S_CHAN(newch);
|
||||
}
|
||||
num_devs[newch] += dptr->numunits;
|
||||
} else {
|
||||
/* Set the new channel */
|
||||
uptr->flags &= ~UNIT_CHAN;
|
||||
uptr->flags |= UNIT_S_CHAN(newch);
|
||||
num_devs[newch]++;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Print devices on channel */
|
||||
t_stat
|
||||
print_chan(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
int chan = uptr - chan_unit;
|
||||
int i;
|
||||
|
||||
/* Check all devices */
|
||||
fprintf(st, "units=");
|
||||
for (i = 0; sim_devices[i] != NULL; i++) {
|
||||
UNIT *u = sim_devices[i]->units;
|
||||
DIB *dibp = (DIB *) sim_devices[i]->ctxt;
|
||||
uint32 num;
|
||||
|
||||
/* If no DIB, not channel device */
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
/* Skip channel devices */
|
||||
if (sim_devices[i] == &chan_dev)
|
||||
continue;
|
||||
/* Skip disabled devices */
|
||||
if (sim_devices[i]->flags & DEV_DIS)
|
||||
continue;
|
||||
if (dibp->upc > 1) {
|
||||
if ((u->flags & UNIT_DIS) == 0 &&
|
||||
UNIT_G_CHAN(u->flags) == chan)
|
||||
fprintf(st, "%s, ", sim_devices[i]->name);
|
||||
} else {
|
||||
for (num = 0; num < sim_devices[i]->numunits; num++) {
|
||||
if ((u->flags & UNIT_DIS) == 0 &&
|
||||
UNIT_G_CHAN(u->flags) == chan)
|
||||
fprintf(st, "%s%d, ", sim_devices[i]->name, num);
|
||||
u++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
get_chan(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
int chan;
|
||||
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
chan = UNIT_G_CHAN(uptr->flags);
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "Chan=%s", chname[chan]);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
chan9_set_select(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int newsel;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
if (*cptr == '\0' || cptr[1] != '\0')
|
||||
return SCPE_ARG;
|
||||
if (*cptr == '0')
|
||||
newsel = 0;
|
||||
else if (*cptr == '1')
|
||||
newsel = 1;
|
||||
else
|
||||
return SCPE_ARG;
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
if (dptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
/* Change to new selection. */
|
||||
if (dibp->upc > 1) {
|
||||
uint32 unit;
|
||||
for (unit = 0; unit < dptr->numunits; unit++) {
|
||||
if (newsel)
|
||||
dptr->units[unit].flags |= UNIT_SELECT;
|
||||
else
|
||||
dptr->units[unit].flags &= ~UNIT_SELECT;
|
||||
}
|
||||
} else {
|
||||
if (newsel)
|
||||
uptr->flags |= UNIT_SELECT;
|
||||
else
|
||||
uptr->flags &= ~UNIT_SELECT;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
chan9_get_select(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
if (uptr->flags & UNIT_SELECT)
|
||||
fputs("Select=1", st);
|
||||
else
|
||||
fputs("Select=0", st);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Check channel for error */
|
||||
int chan_error(int chan)
|
||||
{
|
||||
return chan_flags[chan] & CHS_ATTN;
|
||||
}
|
||||
|
||||
/* Check channel for flag, clear it if it was set */
|
||||
int chan_stat(int chan, uint32 flag)
|
||||
{
|
||||
if (chan_flags[chan] & flag) {
|
||||
chan_flags[chan] &= ~flag;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check channel for flag */
|
||||
int chan_test(int chan, uint32 flag)
|
||||
{
|
||||
if (chan_flags[chan] & flag)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check channel is selected */
|
||||
int chan_select(int chan)
|
||||
{
|
||||
return chan_flags[chan] & DEV_SEL;
|
||||
}
|
||||
|
||||
/* Check channel is active */
|
||||
int chan_active(int chan)
|
||||
{
|
||||
return (chan_flags[chan] &
|
||||
(DEV_DISCO |DEV_SEL | STA_ACTIVE | STA_WAIT | STA_TWAIT)) != 0;
|
||||
}
|
||||
|
||||
void
|
||||
chan_set_attn(int chan)
|
||||
{
|
||||
chan_flags[chan] |= CHS_ATTN;
|
||||
}
|
||||
|
||||
void
|
||||
chan_set_eof(int chan)
|
||||
{
|
||||
chan_flags[chan] |= CHS_EOF;
|
||||
}
|
||||
|
||||
void
|
||||
chan_set_error(int chan)
|
||||
{
|
||||
chan_flags[chan] |= CHS_ERR;
|
||||
}
|
||||
|
||||
void
|
||||
chan_set_sel(int chan, int need)
|
||||
{
|
||||
chan_flags[chan] &=
|
||||
~(DEV_WEOR | DEV_REOR | DEV_FULL | DEV_WRITE | DEV_DISCO);
|
||||
chan_flags[chan] |= DEV_SEL;
|
||||
if (need)
|
||||
chan_flags[chan] |= DEV_WRITE;
|
||||
}
|
||||
|
||||
void
|
||||
chan_clear_status(int chan)
|
||||
{
|
||||
chan_flags[chan] &=
|
||||
~(CHS_ATTN | CHS_EOT | CHS_BOT | DEV_REOR | DEV_WEOR);
|
||||
}
|
||||
|
||||
void
|
||||
chan_set(int chan, uint32 flag)
|
||||
{
|
||||
chan_flags[chan] |= flag;
|
||||
}
|
||||
|
||||
void
|
||||
chan_clear(int chan, uint32 flag)
|
||||
{
|
||||
chan_flags[chan] &= ~flag;
|
||||
}
|
||||
|
||||
void
|
||||
chan9_clear_error(int chan, int sel) {
|
||||
chan_flags[chan] &= ~(SNS_UEND | (SNS_ATTN1 >> sel));
|
||||
}
|
||||
|
||||
void
|
||||
chan9_set_attn(int chan, int sel)
|
||||
{
|
||||
uint16 mask = SNS_ATTN1 >> sel;
|
||||
|
||||
chan9_set_error(chan, mask);
|
||||
}
|
||||
|
292
I7000/i7000_chron.c
Normal file
292
I7000/i7000_chron.c
Normal file
|
@ -0,0 +1,292 @@
|
|||
/* i7090_chron.c: IBM 7090 Chrono clock on MT drive.
|
||||
|
||||
Copyright (c) 2005-2016, 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 "i7000_defs.h"
|
||||
#include <time.h>
|
||||
|
||||
#ifdef NUM_DEVS_CHRON
|
||||
#define BUFFSIZE (12)
|
||||
|
||||
#define UNIT_MT(x) UNIT_DISABLE | UNIT_ROABLE | \
|
||||
UNIT_S_CHAN(x)
|
||||
|
||||
/* in u3 is device address */
|
||||
/* in u4 is current buffer position */
|
||||
/* in u5 */
|
||||
#define MT_RDS 1
|
||||
#define MT_RDSB 2
|
||||
#define MT_SKIP 11 /* Do skip to end of record */
|
||||
#define MT_CMDMSK 000017 /* Command being run */
|
||||
#define MT_RDY 000020 /* Device is ready for command */
|
||||
#define MT_IDLE 000040 /* Tape still in motion */
|
||||
#define MT_EOR 000200 /* Hit end of record */
|
||||
#define MT_ERR 000400 /* Device recieved error */
|
||||
#define MT_BOT 001000 /* Unit at begining of tape */
|
||||
#define MT_EOT 002000 /* Unit at end of tape */
|
||||
|
||||
uint32 chron_cmd(UNIT *, uint16, uint16);
|
||||
t_stat chron_srv(UNIT *);
|
||||
t_stat chron_reset(DEVICE *);
|
||||
t_stat set_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat get_addr(FILE * st, UNIT *uptr, int32 v, CONST void *desc);
|
||||
t_stat chron_help(FILE *st, DEVICE *dptr, UNIT *uptr,
|
||||
int32 flags, const char *ctxt);
|
||||
const char *chron_description (DEVICE *dptr);
|
||||
|
||||
/* One buffer per channel */
|
||||
uint8 chron_buffer[BUFFSIZE];
|
||||
|
||||
UNIT chron_unit[] = {
|
||||
/* Controller 1 */
|
||||
{UDATA(&chron_srv, UNIT_MT(1) | UNIT_DIS, 0), 10}, /* 0 */
|
||||
};
|
||||
|
||||
MTAB chron_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "UNIT", "UNIT", &set_addr, &get_addr,
|
||||
NULL, "Chronoclock unit number"},
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan, &get_chan,
|
||||
NULL, "Chronoclock channel"},
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE chron_dev = {
|
||||
"CHRON", chron_unit, NULL, chron_mod,
|
||||
NUM_DEVS_CHRON, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, &chron_reset, NULL, NULL, NULL,
|
||||
&chron_dib, DEV_DISABLE, 0, NULL,
|
||||
NULL, NULL, &chron_help, NULL, NULL, &chron_description
|
||||
};
|
||||
|
||||
uint32 chron_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int time = 30;
|
||||
int unit = (dev & 017);
|
||||
|
||||
/* Make sure valid drive number */
|
||||
if (unit != uptr->u3)
|
||||
return SCPE_NODEV;
|
||||
if (uptr->flags & UNIT_DIS)
|
||||
return SCPE_NODEV;
|
||||
|
||||
/* Check if drive is ready to recieve a command */
|
||||
if ((uptr->u5 & MT_RDY) == 0) {
|
||||
/* Return indication if not ready and doing TRS */
|
||||
if (cmd == IO_TRS) {
|
||||
return SCPE_IOERR;
|
||||
} else
|
||||
return SCPE_BUSY;
|
||||
}
|
||||
uptr->u5 &= ~(MT_CMDMSK | MT_RDY);
|
||||
switch (cmd) {
|
||||
case IO_RDS:
|
||||
if (dev & 020)
|
||||
uptr->u5 |= MT_RDSB;
|
||||
else
|
||||
uptr->u5 |= MT_RDS;
|
||||
time = 100;
|
||||
chan_set_sel(chan, 0);
|
||||
chan_clear_status(chan);
|
||||
uptr->u6 = 0;
|
||||
break;
|
||||
case IO_WRS:
|
||||
/* Can't write to it so return error */
|
||||
return SCPE_IOERR;
|
||||
|
||||
case IO_BSR: /* Nop, just set us back at begining */
|
||||
case IO_BSF: /* Nop, just set flag and leave */
|
||||
chan_set(chan, CHS_BOT);
|
||||
/* All nops, just return success */
|
||||
case IO_WEF:
|
||||
case IO_REW:
|
||||
case IO_RUN:
|
||||
case IO_SDL:
|
||||
case IO_SDH:
|
||||
case IO_TRS:
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_cancel(uptr);
|
||||
sim_activate(uptr, us_to_ticks(time));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Chronolog clock */
|
||||
|
||||
/* Convert number (0-99) to BCD */
|
||||
|
||||
static void
|
||||
bcd_2d(int n, uint8 * b2)
|
||||
{
|
||||
uint8 d1, d2;
|
||||
|
||||
d1 = n / 10;
|
||||
d2 = n % 10;
|
||||
*b2++ = d1;
|
||||
*b2 = d2;
|
||||
}
|
||||
|
||||
void
|
||||
chron_read_buff(UNIT * uptr, int cmd)
|
||||
{
|
||||
time_t curtim;
|
||||
struct tm *tptr;
|
||||
int ms;
|
||||
|
||||
uptr->u6 = 0; /* Set to no data */
|
||||
|
||||
curtim = time(NULL); /* get time */
|
||||
tptr = localtime(&curtim); /* decompose */
|
||||
if (tptr == NULL)
|
||||
return; /* error? */
|
||||
|
||||
ms = sim_os_msec() % 1000;
|
||||
ms /= 100;
|
||||
|
||||
/* Convert and fill buffer */
|
||||
bcd_2d(tptr->tm_mon + 1, &chron_buffer[0]);
|
||||
bcd_2d(tptr->tm_mday, &chron_buffer[2]);
|
||||
bcd_2d(tptr->tm_hour, &chron_buffer[4]);
|
||||
bcd_2d(tptr->tm_min, &chron_buffer[6]);
|
||||
bcd_2d(tptr->tm_sec, &chron_buffer[8]);
|
||||
bcd_2d(ms, &chron_buffer[10]);
|
||||
return;
|
||||
}
|
||||
|
||||
t_stat chron_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int cmd = uptr->u5 & MT_CMDMSK;
|
||||
|
||||
/* Channel has disconnected, abort current read. */
|
||||
if ((uptr->u5 & MT_RDY) == 0 && chan_stat(chan, DEV_DISCO)) {
|
||||
uptr->u5 &= ~MT_CMDMSK;
|
||||
if (cmd == MT_RDS || cmd == MT_RDSB) {
|
||||
uptr->u6 = 0;
|
||||
}
|
||||
uptr->u5 |= MT_RDY;
|
||||
chan_clear(chan, DEV_WEOR|DEV_SEL);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
switch (uptr->u5 & MT_CMDMSK) {
|
||||
case 0: /* No command, stop tape */
|
||||
uptr->u5 |= MT_RDY; /* Ready since command is done */
|
||||
break;
|
||||
|
||||
case MT_SKIP: /* Record skip done, enable tape drive */
|
||||
sim_activate(uptr, us_to_ticks(500));
|
||||
break;
|
||||
|
||||
case MT_RDS:
|
||||
case MT_RDSB:
|
||||
if (uptr->u6 == 0)
|
||||
chron_read_buff(uptr, cmd);
|
||||
switch (chan_write_char(chan, &chron_buffer[uptr->u6],
|
||||
(uptr->u6 == (BUFFSIZE-1)) ? DEV_REOR : 0)) {
|
||||
case DATA_OK:
|
||||
uptr->u6++;
|
||||
sim_activate(uptr, us_to_ticks(100));
|
||||
break;
|
||||
|
||||
case END_RECORD:
|
||||
case TIME_ERROR:
|
||||
uptr->u5 &= ~MT_CMDMSK;
|
||||
uptr->u5 |= MT_SKIP;
|
||||
sim_activate(uptr, us_to_ticks(100));
|
||||
uptr->u6 = 0; /* Force read next record */
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
chron_reset(DEVICE * dptr)
|
||||
{
|
||||
chron_unit[0].u5 = MT_RDY;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Sets the address of the chrono clock */
|
||||
t_stat
|
||||
set_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
return SCPE_ALATT;
|
||||
i = 0;
|
||||
while (*cptr != '\0') {
|
||||
if (*cptr < '0' || *cptr > '9')
|
||||
return SCPE_ARG;
|
||||
i = (i * 10) + (*cptr++) - '0';
|
||||
}
|
||||
if (i < 0 || i > 10)
|
||||
return SCPE_ARG;
|
||||
uptr->u3 = i;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
get_addr(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "Unit=%d", uptr->u3);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
chron_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "Chronoclock\n\n");
|
||||
fprintf (st, "The Chronoclock replaces one of your tape drives, and is\n");
|
||||
fprintf (st, "for CTSS operation\n\n");
|
||||
fprintf (st, " sim> SET %s ENABLE to enable chronoclock\n", dptr->name);
|
||||
fprintf (st, " sim> SET %s UNIT=# sets unit to override [0-9]\n\n", dptr->name);
|
||||
help_set_chan_type(st, dptr, "Chrono clock");
|
||||
fprintf (st, "You must disable the corrosponding tape drive in order for\n");
|
||||
fprintf (st, "the chronoclook to be seen. The chronoclock replaces one of\n");
|
||||
fprintf (st, "your tape drives, and by reading the tape drive, it will\n");
|
||||
fprintf (st, "return a short record with the current date and time, no year\n");
|
||||
fprintf (st, "is returned\n");
|
||||
|
||||
fprint_set_help (st, dptr) ;
|
||||
fprint_show_help (st, dptr) ;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
chron_description (DEVICE *dptr)
|
||||
{
|
||||
return "Chronoclock";
|
||||
}
|
||||
|
||||
|
||||
#endif
|
1317
I7000/i7000_com.c
Normal file
1317
I7000/i7000_com.c
Normal file
File diff suppressed because it is too large
Load diff
279
I7000/i7000_con.c
Normal file
279
I7000/i7000_con.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
/* i7000_con.c: IBM 7000 Inquiry Console.
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This is the standard inquiry or console interface.
|
||||
|
||||
These units each buffer one record in local memory and signal
|
||||
ready when the buffer is full or empty. The channel must be
|
||||
ready to recieve/transmit data when they are activated since
|
||||
they will transfer their block during chan_cmd. All data is
|
||||
transmitted as BCD characters.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7000_defs.h"
|
||||
#include "sim_card.h"
|
||||
#include "sim_defs.h"
|
||||
|
||||
#ifdef NUM_DEVS_CON
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* Device status information stored in u5 */
|
||||
|
||||
struct _con_data
|
||||
{
|
||||
uint8 ibuff[145]; /* Input line buffer */
|
||||
uint8 inptr;
|
||||
}
|
||||
con_data[NUM_DEVS_CON];
|
||||
|
||||
uint32 con_cmd(UNIT *, uint16, uint16);
|
||||
void con_ini(UNIT *, t_bool);
|
||||
t_stat con_srv(UNIT *);
|
||||
t_stat con_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *con_description(DEVICE *dptr);
|
||||
|
||||
extern char ascii_to_six[128];
|
||||
|
||||
UNIT con_unit[] = {
|
||||
{UDATA(con_srv, UNIT_S_CHAN(CHAN_CHUREC), 0), 0}, /* A */
|
||||
};
|
||||
|
||||
DEVICE con_dev = {
|
||||
"INQ", con_unit, NULL, NULL,
|
||||
NUM_DEVS_CON, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&con_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &con_help, NULL, NULL, &con_description
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*Console printer routines.
|
||||
*/
|
||||
void
|
||||
con_ini(UNIT *uptr, t_bool f) {
|
||||
int u = (uptr - con_unit);
|
||||
con_data[u].inptr = 0;
|
||||
uptr->u5 = 0;
|
||||
sim_activate(uptr, 1000);
|
||||
}
|
||||
|
||||
uint32
|
||||
con_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - con_unit);
|
||||
|
||||
/* Are we currently tranfering? */
|
||||
if (uptr->u5 & (URCSTA_READ|URCSTA_WRITE|URCSTA_BUSY))
|
||||
return SCPE_BUSY;
|
||||
|
||||
switch (cmd) {
|
||||
/* Test ready */
|
||||
case IO_TRS:
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd TRS\n", u);
|
||||
return SCPE_OK;
|
||||
|
||||
/* Get record from CPU */
|
||||
case IO_WRS:
|
||||
sim_putchar('R');
|
||||
sim_putchar(' ');
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd WRS\n", u);
|
||||
chan_set_sel(chan, 1);
|
||||
uptr->u5 |= URCSTA_WRITE;
|
||||
uptr->u3 = 0;
|
||||
return SCPE_OK;
|
||||
|
||||
/* Send record to CPU */
|
||||
case IO_RDS:
|
||||
if (uptr->u5 & URCSTA_INPUT)
|
||||
return SCPE_BUSY;
|
||||
if (con_data[u].inptr == 0) {
|
||||
/* Activate input so we can get response */
|
||||
uptr->u5 |= URCSTA_INPUT;
|
||||
sim_putchar('I');
|
||||
sim_putchar(' ');
|
||||
}
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd RDS\n", u);
|
||||
chan_set_sel(chan, 0);
|
||||
uptr->u5 |= URCSTA_READ;
|
||||
uptr->u3 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
chan_set_attn(chan);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
/* Handle transfer of data for printer */
|
||||
t_stat
|
||||
con_srv(UNIT *uptr) {
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
uint8 ch;
|
||||
int u = (uptr - con_unit);
|
||||
t_stat r;
|
||||
|
||||
/* Waiting for disconnect */
|
||||
if (uptr->u5 & URCSTA_WDISCO) {
|
||||
if (chan_stat(chan, DEV_DISCO)) {
|
||||
sim_debug(DEBUG_DETAIL, &con_dev, " Disco\n");
|
||||
chan_clear(chan, DEV_SEL|DEV_WEOR);
|
||||
uptr->u5 &= ~ URCSTA_WDISCO;
|
||||
sim_activate(uptr, 25);
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
/* No disco yet, try again in a bit */
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
uptr->u5 &= ~URCSTA_BUSY; /* Clear busy */
|
||||
|
||||
/* Copy next column over */
|
||||
if (uptr->u5 & URCSTA_WRITE) {
|
||||
switch(chan_read_char(chan, &ch, 0)) {
|
||||
case TIME_ERROR:
|
||||
case END_RECORD:
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
sim_debug(DEBUG_EXP, &con_dev, "\n\r");
|
||||
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY;
|
||||
uptr->u5 &= ~URCSTA_WRITE;
|
||||
break;
|
||||
case DATA_OK:
|
||||
ch &= 077;
|
||||
sim_debug(DEBUG_EXP, &con_dev, "%c", sim_six_to_ascii[ch]);
|
||||
sim_putchar(sim_six_to_ascii[ch]);
|
||||
break;
|
||||
}
|
||||
sim_activate(uptr, 100);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Copy next column over */
|
||||
if ((uptr->u5 & URCSTA_INPUT) == 0 && uptr->u5 & URCSTA_READ) {
|
||||
sim_debug(DEBUG_DATA, &con_dev, "%d: Char > %02o %x\n", u,
|
||||
con_data[u].ibuff[uptr->u3], chan_flags[chan]);
|
||||
switch(chan_write_char(chan, &con_data[u].ibuff[uptr->u3],
|
||||
((uptr->u3+1) == con_data[u].inptr)? DEV_REOR: 0)) {
|
||||
case TIME_ERROR:
|
||||
case END_RECORD:
|
||||
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY;
|
||||
uptr->u5 &= ~URCSTA_READ;
|
||||
sim_debug(DEBUG_EXP, &con_dev, "EOR");
|
||||
chan_clear_attn_inq(chan);
|
||||
con_data[u].inptr = 0;
|
||||
break;
|
||||
case DATA_OK:
|
||||
uptr->u3++;
|
||||
break;
|
||||
}
|
||||
sim_activate(uptr, 10);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
r = sim_poll_kbd();
|
||||
if (r & SCPE_KFLAG) {
|
||||
ch = r & 0377;
|
||||
if (uptr->u5 & URCSTA_INPUT) {
|
||||
/* Handle end of buffer */
|
||||
switch (ch) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
uptr->u5 &= ~URCSTA_INPUT;
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
chan_set_attn_inq(chan);
|
||||
break;
|
||||
case 033:
|
||||
uptr->u5 &= ~URCSTA_INPUT;
|
||||
con_data[u].inptr = 0;
|
||||
break;
|
||||
case '\b':
|
||||
if (con_data[u].inptr != 0) {
|
||||
con_data[u].inptr--;
|
||||
sim_putchar(ch);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (con_data[u].inptr < sizeof(con_data[u].ibuff)) {
|
||||
ch = sim_ascii_to_six[0177&ch];
|
||||
if (ch == 0xff) {
|
||||
sim_putchar('\007');
|
||||
break;
|
||||
}
|
||||
sim_putchar(sim_six_to_ascii[ch]);
|
||||
con_data[u].ibuff[con_data[u].inptr++] = ch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (ch == 033) {
|
||||
if (con_data[u].inptr != 0) {
|
||||
chan_clear_attn_inq(chan);
|
||||
} else {
|
||||
#ifdef I7070
|
||||
chan_set_attn_inq(chan);
|
||||
#endif
|
||||
sim_putchar('I');
|
||||
sim_putchar(' ');
|
||||
uptr->u5 |= URCSTA_INPUT;
|
||||
}
|
||||
con_data[u].inptr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
sim_activate(uptr, 500);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
con_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "Supervisory Printer\n\n");
|
||||
fprintf (st, "This is the interface from the operator to the system. The printer\n");
|
||||
fprintf (st, "operated in a half duplex mode. To request the system to accept input\n");
|
||||
fprintf (st, "press the <esc> key and wait until the system responds with a line with\n");
|
||||
fprintf (st, "I as the first character. When you have finished typing your line, press\n");
|
||||
fprintf (st, "return or enter key. Backspace will delete the last character.\n");
|
||||
fprintf (st, "All responses from the system are prefixed with a R and blank as the\n");
|
||||
fprintf (st, "first character\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
con_description(DEVICE *dptr)
|
||||
{
|
||||
return "Supervisory Printer";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
642
I7000/i7000_defs.h
Normal file
642
I7000/i7000_defs.h
Normal file
|
@ -0,0 +1,642 @@
|
|||
/* i7000_defs.h: IBM 70xx simulator definitions
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
Generic channel interface for all processors in IBM 700 and 7000 line.
|
||||
*/
|
||||
|
||||
#ifndef _I7000_H_
|
||||
#define _I7000_H_
|
||||
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
||||
/* Definitions for each supported CPU */
|
||||
|
||||
#ifdef I701
|
||||
#define NUM_CHAN 1
|
||||
#define NUM_DEVS_CDR 1
|
||||
#define NUM_DEVS_CDP 1
|
||||
#define NUM_DEVS_LPR 1
|
||||
#define NUM_DEVS_DR 1
|
||||
#define NUM_DEVS_MT 0
|
||||
#define MT_CHANNEL_ZERO
|
||||
#define NUM_UNITS_MT 5
|
||||
#define NUM_UNITS_DR 16
|
||||
#define MAXMEMSIZE 2048
|
||||
#define CHARSPERWORD 6
|
||||
extern t_uint64 M[];
|
||||
#endif
|
||||
#ifdef I7010 /* Includes 1410 and 7010 */
|
||||
#define NUM_CHAN 5
|
||||
#define NUM_DEVS_CDR 1
|
||||
#define NUM_DEVS_CDP 1
|
||||
#define STACK_DEV 1
|
||||
#define NUM_DEVS_LPR 1
|
||||
#define NUM_DEVS_CON 1
|
||||
#define NUM_DEVS_DSK 5
|
||||
#define NUM_DEVS_COM 1
|
||||
#define NUM_DEVS_MT 3
|
||||
#define CHAN_CHUREC 1
|
||||
#define NUM_UNITS_MT 10 /* A, B */
|
||||
#define MAXMEMSIZE (100000)
|
||||
#define CHARSPERWORD 1
|
||||
extern uint8 M[];
|
||||
#endif
|
||||
#ifdef I7030
|
||||
/* Not yet */
|
||||
#endif
|
||||
#ifdef I7070 /* Includes 7070, 7074 */
|
||||
#define NUM_CHAN 9
|
||||
#define NUM_DEVS_CDR 1
|
||||
#define NUM_DEVS_CDP 1
|
||||
#define NUM_DEVS_LPR 1
|
||||
#define NUM_DEVS_CON 1
|
||||
#define NUM_DEVS_MT 3
|
||||
#define NUM_DEVS_DSK 10
|
||||
#define NUM_DEVS_HT 0
|
||||
#define NUM_DEVS_COM 1
|
||||
#define NUM_UNITS_HT 10
|
||||
#define NUM_UNITS_MT 10 /* A, B */
|
||||
#define NUM_DEVS_CHRON 1
|
||||
#define MAXMEMSIZE (30000)
|
||||
#define CHARSPERWORD 5
|
||||
extern t_uint64 M[];
|
||||
#endif
|
||||
#ifdef I7080 /* Includes 702, 705-i/ii, 705-iii, 7080 */
|
||||
#define NUM_CHAN 11
|
||||
#define NUM_DEVS_CDR 1
|
||||
#define NUM_DEVS_CDP 1
|
||||
#define NUM_DEVS_LPR 1
|
||||
#define NUM_DEVS_CON 1
|
||||
#define NUM_DEVS_MT 4
|
||||
#define NUM_DEVS_CHRON 1
|
||||
#define NUM_DEVS_DR 1
|
||||
#define NUM_DEVS_DSK 5
|
||||
#define NUM_DEVS_HT 0
|
||||
#define NUM_DEVS_COM 1
|
||||
#define NUM_UNITS_MT 10
|
||||
#define MT_CHANNEL_ZERO
|
||||
#define NUM_UNITS_HT 10
|
||||
#define MAXMEMSIZE (160000)
|
||||
#define CHARSPERWORD 1
|
||||
extern uint8 M[];
|
||||
#endif
|
||||
#ifdef I704 /* Special build for 704 only */
|
||||
#define NUM_CHAN 1
|
||||
#define NUM_DEVS_CDR 1
|
||||
#define NUM_DEVS_CDP 1
|
||||
#define NUM_DEVS_LPR 1
|
||||
#define NUM_DEVS_DR 1
|
||||
#define NUM_DEVS_MT 0
|
||||
#define NUM_UNITS_MT 10
|
||||
#define MT_CHANNEL_ZERO
|
||||
#define NUM_UNITS_DR 16
|
||||
#define MAXMEMSIZE (32*1024)
|
||||
#define CHARSPERWORD 6
|
||||
extern t_uint64 M[];
|
||||
#endif
|
||||
#ifdef I7040 /* Includes 7040, 7044 */
|
||||
/* Not yet */
|
||||
#define NUM_CHAN 8
|
||||
#define NUM_DEVS_CDP 2
|
||||
#define NUM_DEVS_CDR 2
|
||||
#define NUM_DEVS_LPR 2
|
||||
#define NUM_DEVS_MT 4
|
||||
#define NUM_DEVS_CHRON 1
|
||||
#define NUM_DEVS_DSK 10
|
||||
#define NUM_DEVS_COM 1
|
||||
#define NUM_DEVS_HD 1
|
||||
#define NUM_DEVS_HT 0
|
||||
#define MT_CHANNEL_ZERO
|
||||
#define NUM_UNITS_HT 10
|
||||
#define NUM_UNITS_MT 10 /* A, B */
|
||||
#define NUM_UNITS_HD 8
|
||||
#define MAXMEMSIZE (32*1024)
|
||||
#define CHARSPERWORD 6
|
||||
extern t_uint64 M[];
|
||||
#endif
|
||||
#ifdef I7090 /* Includes 704, 709, 7090, 7094 */
|
||||
#define NUM_CHAN 9
|
||||
#define NUM_DEVS_CDP 4
|
||||
#define NUM_DEVS_CDR 4
|
||||
#define NUM_DEVS_LPR 4
|
||||
#define NUM_DEVS_MT 3
|
||||
#define NUM_DEVS_CHRON 1
|
||||
#define NUM_DEVS_DR 1
|
||||
#define NUM_DEVS_DSK 10
|
||||
#define NUM_DEVS_COM 1
|
||||
#define NUM_DEVS_HD 1
|
||||
#define NUM_DEVS_HT 0
|
||||
#define MT_CHANNEL_ZERO
|
||||
#define NUM_UNITS_HT 10
|
||||
#define NUM_UNITS_MT 10 /* A, B */
|
||||
#define NUM_UNITS_DR 16
|
||||
#define NUM_UNITS_HD 8
|
||||
#define MAXMEMSIZE (64*1024)
|
||||
#define CHARSPERWORD 6
|
||||
/*#define EXTRA_SL */ /* Remove comments to allow 4 extra sense lights */
|
||||
/*#define EXTRA_SW */ /* Remove comments to allow 6 extra switchs */
|
||||
extern t_uint64 M[];
|
||||
#endif
|
||||
|
||||
/* Simulation stop codes. */
|
||||
#define STOP_IONRDY 1 /* I/O dev not ready */
|
||||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
#define STOP_UUO 4 /* invalid opcode */
|
||||
#define STOP_INDLIM 5 /* indirect limit */
|
||||
#define STOP_XECLIM 6 /* XEC limit */
|
||||
#define STOP_IOCHECK 7 /* IOCHECK */
|
||||
#define STOP_MMTRP 8 /* mm in trap */
|
||||
#define STOP_INVLIN 9 /* 7750 invalid line number */
|
||||
#define STOP_INVMSG 10 /* 7750 invalid message */
|
||||
#define STOP_NOOFREE 11 /* 7750 No free output buffers */
|
||||
#define STOP_NOIFREE 12 /* 7750 No free input buffers */
|
||||
#define STOP_FIELD 13 /* Field overflow */
|
||||
#define STOP_ACOFL 13 /* AC Overflow - 7080 */
|
||||
#define STOP_SIGN 14 /* Sign change */
|
||||
#define STOP_DIV 15 /* Divide error */
|
||||
#define STOP_INDEX 16 /* 7070 Alpha index */
|
||||
#define STOP_NOWM 17 /* Stop if no word mark found */
|
||||
#define STOP_INVADDR 18 /* Stop on invalid address */
|
||||
#define STOP_INVLEN 19 /* Invalid length instruction */
|
||||
#define STOP_RECCHK 19 /* Record check - 7080 */
|
||||
#define STOP_PROG 20 /* Program fault */
|
||||
#define STOP_PROT 21 /* Protection fault */
|
||||
|
||||
/* Memory */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define MEMMASK (MEMSIZE - 1) /* Memory bits */
|
||||
|
||||
/* Globally visible flags */
|
||||
#define CHAN_PIO (0) /* Polled mode I/O */
|
||||
#define CHAN_UREC (1) /* Unit record devices */
|
||||
#define CHAN_7010 (1) /* Channel type for 7010 */
|
||||
#define CHAN_7604 (2) /* 7070 tape controller */
|
||||
#define CHAN_7607 (2) /* Generic 7090 channel */
|
||||
#define CHAN_7621 (2) /* 7080 tape controller */
|
||||
#define CHAN_7904 (3) /* 7040 generic channel */
|
||||
#define CHAN_7907 (3) /* Disk/Hyper/7750 channel for 7070 */
|
||||
#define CHAN_7908 (3) /* Disk/Hyper/7750 channel for 7080 */
|
||||
#define CHAN_7909 (3) /* Disk/Hyper/7750 channel for 7090 */
|
||||
#define CHAN_7289 (4) /* Special CTSS device for 7090 */
|
||||
#define CHAN_754 (4) /* 705 tape controller */
|
||||
|
||||
#define CH_TYP_PIO 01 /* Can be on PIO channel */
|
||||
#define CH_TYP_UREC 02 /* Can be on Unit record channel */
|
||||
#define CH_TYP_76XX 04 /* Can be on 76xx Channel */
|
||||
#define CH_TYP_79XX 010 /* Can be on a 79xx channel */
|
||||
#define CH_TYP_SPEC 020 /* Special channel */
|
||||
#define CH_TYP_754 020 /* 705 tape controller */
|
||||
|
||||
/* Device information block */
|
||||
struct dib {
|
||||
uint8 ctype; /* Type of channel */
|
||||
uint8 upc; /* Units per channel */
|
||||
uint16 addr; /* Unit address */
|
||||
uint16 mask; /* Channel mask type */
|
||||
uint32 (*cmd)(UNIT *up, uint16 cmd, uint16 dev);/* Issue command. */
|
||||
void (*ini)(UNIT *up, t_bool f);
|
||||
};
|
||||
|
||||
typedef struct dib DIB;
|
||||
|
||||
|
||||
/* Debuging controls */
|
||||
#define DEBUG_CHAN 0x0000001 /* Show channel fetchs */
|
||||
#define DEBUG_TRAP 0x0000002 /* Show CPU Traps */
|
||||
#define DEBUG_CMD 0x0000004 /* Show device commands */
|
||||
#define DEBUG_DATA 0x0000008 /* Show data transfers */
|
||||
#define DEBUG_DETAIL 0x0000020 /* Show details */
|
||||
#define DEBUG_EXP 0x0000040 /* Show error conditions */
|
||||
#define DEBUG_SNS 0x0000080 /* Shows sense data for 7909 devs */
|
||||
#define DEBUG_CTSS 0x0000100 /* Shows CTSS specail instructions */
|
||||
#define DEBUG_PRIO 0x0000100 /* Debug Priority mode on 7010 */
|
||||
#define DEBUG_PROT 0x0000200 /* Protection traps */
|
||||
|
||||
extern DEBTAB dev_debug[];
|
||||
extern DEBTAB crd_debug[];
|
||||
|
||||
/* Channels */
|
||||
#define CHAN_CHPIO 0 /* Puesdo access for 704 */
|
||||
#ifndef CHAN_CHUREC
|
||||
#define CHAN_CHUREC 0 /* Unit record devices */
|
||||
#endif
|
||||
#define CHAN_A 1
|
||||
#define CHAN_B 2
|
||||
#define CHAN_C 3
|
||||
#define CHAN_D 4
|
||||
#define CHAN_E 5
|
||||
#define CHAN_F 6
|
||||
#define CHAN_G 7
|
||||
#define CHAN_H 8
|
||||
|
||||
#define UNIT_V_SELECT (UNIT_V_UF + 9) /* 9 */
|
||||
#define UNIT_SELECT (1 << UNIT_V_SELECT)
|
||||
#define UNIT_V_CHAN (UNIT_V_SELECT + 1) /* 10 */
|
||||
#define UNIT_CHAN (017 << UNIT_V_CHAN) /* 10-14 */
|
||||
#define UNIT_S_CHAN(x) (UNIT_CHAN & ((x) << UNIT_V_CHAN))
|
||||
#define UNIT_G_CHAN(x) ((UNIT_CHAN & (x)) >> UNIT_V_CHAN)
|
||||
#define UNIT_V_LOCAL (UNIT_V_UF + 0) /* 0 */
|
||||
#define DEV_BUF_NUM(x) (((x) & 07) << DEV_V_UF)
|
||||
#define GET_DEV_BUF(x) (((x) >> DEV_V_UF) & 07)
|
||||
#define UNIT_V_MODE (UNIT_V_LOCAL + 1) /* 1 */
|
||||
|
||||
/* Specific to channel devices */
|
||||
#define UNIT_V_MODEL (UNIT_V_UF + 0)
|
||||
#define CHAN_MODEL (07 << UNIT_V_MODEL)
|
||||
#define CHAN_S_TYPE(x) (CHAN_MODEL & ((x) << UNIT_V_MODEL))
|
||||
#define CHAN_G_TYPE(x) ((CHAN_MODEL & (x)) >> UNIT_V_MODEL)
|
||||
#define UNIT_V_AUTO (UNIT_V_UF + 4)
|
||||
#define CHAN_AUTO (1 << UNIT_V_AUTO)
|
||||
#define UNIT_V_SET (UNIT_V_UF + 5)
|
||||
#define CHAN_SET (1 << UNIT_V_SET)
|
||||
|
||||
extern t_value assembly[NUM_CHAN]; /* Assembly register */
|
||||
/* I/O routine functions */
|
||||
/* Channel half of controls */
|
||||
/* Channel status */
|
||||
extern uint32 chan_flags[NUM_CHAN]; /* Channel flags */
|
||||
extern const char *chname[11]; /* Channel names */
|
||||
extern int num_devs[NUM_CHAN]; /* Number devices per channel*/
|
||||
extern uint8 lpr_chan9[NUM_CHAN];
|
||||
#ifdef I7010
|
||||
extern uint8 lpr_chan12[NUM_CHAN];
|
||||
#endif
|
||||
|
||||
/* Sense information for 7909 channels */
|
||||
#define SNS_IOCHECK 0x00000400 /* IO Check */
|
||||
#define SNS_SEQCHECK 0x00000200 /* Sequence check */
|
||||
#define SNS_UEND 0x00000100 /* Unusual end */
|
||||
#define SNS_ATTN1 0x00000080 /* Attention 1 */
|
||||
#define SNS_ATTN2 0x00000040 /* Attention 2 */
|
||||
#define SNS_ADCHECK 0x00000020 /* Adaptor check */
|
||||
#define CTL_PREAD 0x00000010 /* Prepare to read */
|
||||
#define CTL_PWRITE 0x00000008 /* Prepare to write */
|
||||
#define CTL_READ 0x00000004 /* Read Status */
|
||||
#define CTL_WRITE 0x00000002 /* Write Status */
|
||||
#define SNS_IRQ 0x00000001 /* IRQ */
|
||||
#define SNS_MASK 0x000007fe /* Mask of sense codes */
|
||||
#define SNS_IRQS 0x000007e0
|
||||
#define SNS_IMSK 0x00000620 /* Non maskable irqs */
|
||||
#define CTL_END 0x00000800 /* Transfer is done */
|
||||
#define CTL_INHB 0x00001000 /* Interupts inhibited */
|
||||
#define CTL_SEL 0x00002000 /* Device select */
|
||||
#define CTL_SNS 0x00004000 /* Sense transfer */
|
||||
#define CTL_CNTL 0x00008000 /* Control transfer */
|
||||
/* Channel status infomation */
|
||||
#define STA_PEND 0x00010000 /* Pending LCH instruct */
|
||||
#define STA_ACTIVE 0x00020000 /* Channel active */
|
||||
#define STA_WAIT 0x00040000 /* Channel waiting for EOR */
|
||||
#define STA_START 0x00080000 /* Channel was started, but not reset */
|
||||
#define STA_TWAIT 0x00100000 /* Channel waiting on IORT */
|
||||
/* Device error controls */
|
||||
#define CHS_EOT 0x00200000 /* Channel at EOT */
|
||||
#define CHS_BOT 0x00400000 /* Channel at BOT */
|
||||
#define CHS_EOF 0x00800000 /* Channel at EOF */
|
||||
#define CHS_ERR 0x01000000 /* Channel has Error */
|
||||
#define CHS_ATTN 0x02000000 /* Channel attention*/
|
||||
/* Device half of controls */
|
||||
#define DEV_SEL 0x04000000 /* Channel selected */
|
||||
#define DEV_WRITE 0x08000000 /* Device is writing to memory */
|
||||
#define DEV_FULL 0x10000000 /* Buffer full */
|
||||
#define DEV_REOR 0x20000000 /* Device at End of Record */
|
||||
#define DEV_DISCO 0x40000000 /* Channel is done with device */
|
||||
#define DEV_WEOR 0x80000000 /* Channel wants EOR written */
|
||||
|
||||
/* 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 */
|
||||
#define URCSTA_WDISCO 0020 /* Device is wait for disconnect */
|
||||
#define URCSTA_READ 0040 /* Device is reading channel */
|
||||
#define URCSTA_WRITE 0100 /* Device is reading channel */
|
||||
#define URCSTA_INPUT 0200 /* Console fill buffer from keyboard */
|
||||
#define URCSTA_ON 0200 /* 7090 Unit is on */
|
||||
#define URCSTA_IDLE 0400 /* 7090 Unit is idle */
|
||||
#define URCSTA_WMKS 0400 /* Printer print WM as 1 */
|
||||
#define URCSTA_SKIPAFT 01000 /* Skip to line after printing next line */
|
||||
#define URCSTA_NOXFER 01000 /* Don't set up to transfer after feed */
|
||||
#define URCSTA_LOAD 01000 /* Load flag for 7070 card reader */
|
||||
#define URCSTA_CMD 01000 /* 7090 Command recieved */
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat chan_boot(int32 unit_num, DEVICE *dptr);
|
||||
|
||||
/* Sets the device onto a given channel */
|
||||
t_stat chan_set_devs(DEVICE *dptr);
|
||||
t_stat set_chan(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat set_cchan(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat print_chan(FILE *st, UNIT *uptr, int32 v, CONST void *desc);
|
||||
t_stat get_chan(FILE *st, UNIT *uptr, int32 v, CONST void *desc);
|
||||
t_stat chan9_set_select(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat chan9_get_select(FILE *st, UNIT *uptr, int32 v, CONST void *desc);
|
||||
|
||||
/* Check channel for error */
|
||||
int chan_error(int chan);
|
||||
|
||||
/* Check channel for flags, clear flags if set */
|
||||
int chan_stat(int chan, uint32 flag);
|
||||
|
||||
/* Check channel for flags set */
|
||||
int chan_test(int chan, uint32 flag);
|
||||
|
||||
/* Check channel is active */
|
||||
int chan_active(int chan);
|
||||
|
||||
/* Check channel is selected */
|
||||
int chan_select(int chan);
|
||||
|
||||
/* Channel data handling char at a time */
|
||||
int chan_write_char(int chan, uint8 *data, int flags);
|
||||
int chan_read_char(int chan, uint8 *data, int flags);
|
||||
|
||||
/* Flag end of file on channel */
|
||||
void chan_set_eof(int chan);
|
||||
|
||||
/* Flag error on channel */
|
||||
void chan_set_error(int chan);
|
||||
|
||||
/* Flag attention on channel */
|
||||
void chan_set_attn(int chan);
|
||||
|
||||
/* Start a selection command on channel */
|
||||
void chan_set_sel(int chan, int need);
|
||||
void chan_clear_status(int chan);
|
||||
|
||||
/* Set or clear a flag */
|
||||
void chan_set(int chan, uint32 flag);
|
||||
void chan_clear(int chan, uint32 flag);
|
||||
|
||||
/* Channel 7909 special error posting */
|
||||
void chan9_clear_error(int chan, int sel);
|
||||
void chan9_set_attn(int chan, int sel);
|
||||
void chan9_set_error(int chan, uint32 mask);
|
||||
|
||||
void chan_proc();
|
||||
|
||||
#ifdef I7010
|
||||
/* Sets the device that will interrupt on the channel. */
|
||||
t_stat set_urec(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat get_urec(FILE * st, UNIT * uptr, int32 v, CONST void *desc);
|
||||
/* Execute the next channel instruction. */
|
||||
void chan_set_attn_urec(int chan, uint16 addr);
|
||||
void chan_set_attn_inq(int chan);
|
||||
void chan_clear_attn_inq(int chan);
|
||||
#endif
|
||||
|
||||
#ifdef I7070
|
||||
void chan_set_attn_a(int chan);
|
||||
void chan_set_attn_b(int chan);
|
||||
void chan_set_attn_inq(int chan);
|
||||
void chan_clear_attn_inq(int chan);
|
||||
void chan_set_load_mode(int chan);
|
||||
#endif
|
||||
|
||||
#ifdef I7080
|
||||
void chan_set_attn_inq(int chan);
|
||||
void chan_clear_attn_inq(int chan);
|
||||
#endif
|
||||
|
||||
/* Convert micro seconds to click ticks */
|
||||
#define us_to_ticks(us) (((us) * 10) / cycle_time)
|
||||
|
||||
/* Returns from chan_read/chan_write */
|
||||
#define DATA_OK 0 /* Data transfered ok */
|
||||
#define TIME_ERROR 1 /* Channel did not transfer last operation */
|
||||
#define END_RECORD 2 /* End of record */
|
||||
|
||||
/* Returns from device commands */
|
||||
#define SCPE_BUSY (1) /* Device is active */
|
||||
#define SCPE_NODEV (2) /* No device exists */
|
||||
|
||||
/* I/O Command codes */
|
||||
#define IO_RDS 1 /* Read record */
|
||||
#define IO_BSR 2 /* Backspace one record */
|
||||
#define IO_BSF 3 /* Backspace one file */
|
||||
#define IO_WRS 4 /* Write one record */
|
||||
#define IO_WEF 5 /* Write eof */
|
||||
#define IO_REW 6 /* Rewind */
|
||||
#define IO_DRS 7 /* Set unit offline */
|
||||
#define IO_SDL 8 /* Set density low */
|
||||
#define IO_SDH 9 /* Set density high */
|
||||
#define IO_RUN 10 /* Rewind and unload unit */
|
||||
#define IO_TRS 11 /* Check it unit ready */
|
||||
#define IO_CTL 12 /* Io control device specific */
|
||||
#define IO_RDB 13 /* Read backwards */
|
||||
#define IO_SKR 14 /* Skip record forward */
|
||||
#define IO_ERG 15 /* Erase next records from tape */
|
||||
|
||||
/* Global device definitions */
|
||||
#ifdef CPANEL
|
||||
extern DEVICE cp_dev;
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_TP
|
||||
extern DIB tp_dib;
|
||||
extern uint32 tp_cmd(UNIT *, uint16, uint16);
|
||||
extern DEVICE tpa_dev;
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_CDR
|
||||
extern DIB cdr_dib;
|
||||
extern DEVICE cdr_dev;
|
||||
extern uint32 cdr_cmd(UNIT *, uint16, uint16);
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_CDP
|
||||
extern DIB cdp_dib;
|
||||
extern DEVICE cdp_dev;
|
||||
extern uint32 cdp_cmd(UNIT *, uint16, uint16);
|
||||
extern void cdp_ini(UNIT *, t_bool);
|
||||
#endif
|
||||
|
||||
#ifdef STACK_DEV
|
||||
extern DEVICE stack_dev;
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_LPR
|
||||
extern DIB lpr_dib;
|
||||
extern DEVICE lpr_dev;
|
||||
extern uint32 lpr_cmd(UNIT *, uint16, uint16);
|
||||
extern void lpr_ini(UNIT *, t_bool);
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_CON
|
||||
extern DIB con_dib;
|
||||
extern DEVICE con_dev;
|
||||
extern uint32 con_cmd(UNIT *, uint16, uint16);
|
||||
extern void con_ini(UNIT *, t_bool);
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_CHRON
|
||||
extern DIB chron_dib;
|
||||
extern DEVICE chron_dev;
|
||||
extern uint32 chron_cmd(UNIT *, uint16, uint16);
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_COM
|
||||
extern uint32 com_cmd(UNIT *, uint16, uint16);
|
||||
extern DIB com_dib;
|
||||
extern DEVICE com_dev;
|
||||
extern DEVICE coml_dev;
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_DR
|
||||
extern uint32 drm_cmd(UNIT *, uint16, uint16);
|
||||
extern void drm_ini(UNIT *, t_bool);
|
||||
extern DIB drm_dib;
|
||||
extern DEVICE drm_dev;
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_DSK
|
||||
extern uint32 dsk_cmd(UNIT *, uint16, uint16);
|
||||
extern void dsk_ini(UNIT *, t_bool);
|
||||
extern DIB dsk_dib;
|
||||
extern DEVICE dsk_dev;
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_HD
|
||||
extern uint32 hsdrm_cmd(UNIT *, uint16, uint16);
|
||||
extern void hsdrm_ini(UNIT *, t_bool);
|
||||
extern DIB hsdrm_dib;
|
||||
extern DEVICE hsdrm_dev;
|
||||
#endif
|
||||
|
||||
#ifdef NUM_DEVS_HT
|
||||
extern DIB ht_dib;
|
||||
extern uint32 ht_cmd(UNIT *, uint16, uint16);
|
||||
extern DEVICE hta_dev;
|
||||
#if NUM_DEVS_HT > 1
|
||||
extern DEVICE htb_dev;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (NUM_DEVS_MT > 0) || defined(MT_CHANNEL_ZERO)
|
||||
extern DIB mt_dib;
|
||||
extern uint32 mt_cmd(UNIT *, uint16, uint16);
|
||||
extern void mt_ini(UNIT *, t_bool);
|
||||
#ifdef MT_CHANNEL_ZERO
|
||||
extern DEVICE mtz_dev;
|
||||
#endif
|
||||
#if NUM_DEVS_MT > 0
|
||||
extern DEVICE mta_dev;
|
||||
#if NUM_DEVS_MT > 1
|
||||
extern DEVICE mtb_dev;
|
||||
#if NUM_DEVS_MT > 2
|
||||
extern DEVICE mtc_dev;
|
||||
#if NUM_DEVS_MT > 3
|
||||
extern DEVICE mtd_dev;
|
||||
#if NUM_DEVS_MT > 4
|
||||
extern DEVICE mte_dev;
|
||||
#if NUM_DEVS_MT > 5
|
||||
extern DEVICE mtf_dev;
|
||||
#endif /* 5 */
|
||||
#endif /* 4 */
|
||||
#endif /* 3 */
|
||||
#endif /* 2 */
|
||||
#endif /* 1 */
|
||||
#endif /* 0 */
|
||||
#endif /* NUM_DEVS_MT */
|
||||
|
||||
/* Character codes */
|
||||
#define CHR_ABLANK 000
|
||||
#define CHR_MARK CHR_ABLANK
|
||||
#define CHR_1 001
|
||||
#define CHR_2 002
|
||||
#define CHR_3 003
|
||||
#define CHR_4 004
|
||||
#define CHR_5 005
|
||||
#define CHR_6 006
|
||||
#define CHR_7 007
|
||||
#define CHR_8 010
|
||||
#define CHR_9 011
|
||||
#define CHR_0 012
|
||||
#define CHR_EQ 013
|
||||
#define CHR_QUOT 014 /* Also @ */
|
||||
#define CHR_COL 015
|
||||
#define CHR_GT 016
|
||||
#define CHR_TRM 017
|
||||
#define CHR_BLANK 020
|
||||
#define CHR_SLSH 021
|
||||
#define CHR_S 022
|
||||
#define CHR_T 023
|
||||
#define CHR_U 024
|
||||
#define CHR_V 025
|
||||
#define CHR_W 026
|
||||
#define CHR_X 027
|
||||
#define CHR_Y 030
|
||||
#define CHR_Z 031
|
||||
#define CHR_RM 032
|
||||
#define CHR_COM 033
|
||||
#define CHR_RPARN 034 /* Also % */
|
||||
#define CHR_WM 035
|
||||
#define CHR_BSLSH 036
|
||||
#define CHR_UND 037
|
||||
#define CHR_MINUS 040
|
||||
#define CHR_J 041
|
||||
#define CHR_K 042
|
||||
#define CHR_L 043
|
||||
#define CHR_M 044
|
||||
#define CHR_N 045
|
||||
#define CHR_O 046
|
||||
#define CHR_P 047
|
||||
#define CHR_Q 050
|
||||
#define CHR_R 051
|
||||
#define CHR_EXPL 052
|
||||
#define CHR_DOL 053
|
||||
#define CHR_STAR 054
|
||||
#define CHR_LBRK 055
|
||||
#define CHR_SEMI 056
|
||||
#define CHR_CART 057
|
||||
#define CHR_PLUS 060
|
||||
#define CHR_A 061
|
||||
#define CHR_B 062
|
||||
#define CHR_C 063
|
||||
#define CHR_D 064
|
||||
#define CHR_E 065
|
||||
#define CHR_F 066
|
||||
#define CHR_G 067
|
||||
#define CHR_H 070
|
||||
#define CHR_I 071
|
||||
#define CHR_QUEST 072
|
||||
#define CHR_DOT 073
|
||||
#define CHR_LPARN 074 /* Also Square */
|
||||
#define CHR_RBRAK 075
|
||||
#define CHR_LESS 076
|
||||
#define CHR_GM 077
|
||||
|
||||
/* Generic devices common to all */
|
||||
extern DEVICE cpu_dev;
|
||||
extern UNIT cpu_unit;
|
||||
extern DEVICE chan_dev;
|
||||
extern UNIT chan_unit[NUM_CHAN];
|
||||
extern REG cpu_reg[];
|
||||
extern int cycle_time;
|
||||
|
||||
extern const char mem_to_ascii[64];
|
||||
|
||||
extern const char *cpu_description(DEVICE *dptr);
|
||||
extern const char *chan_type_name[];
|
||||
extern void help_set_chan_type(FILE *st, DEVICE *dptr, const char *name);
|
||||
|
||||
#endif /* _I7000_H_ */
|
1887
I7000/i7000_dsk.c
Normal file
1887
I7000/i7000_dsk.c
Normal file
File diff suppressed because it is too large
Load diff
992
I7000/i7000_ht.c
Normal file
992
I7000/i7000_ht.c
Normal file
|
@ -0,0 +1,992 @@
|
|||
/* i7090_ht.c: ibm 7090 hypertape
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
Support for 7640 hypertape
|
||||
|
||||
Magnetic tapes are represented as a series of variable records
|
||||
of the form:
|
||||
|
||||
32b byte count
|
||||
byte 0
|
||||
byte 1
|
||||
:
|
||||
byte n-2
|
||||
byte n-1
|
||||
32b byte count
|
||||
|
||||
If the byte count is odd, the record is padded with an extra byte
|
||||
of junk. File marks are represented by a byte count of 0.
|
||||
|
||||
Hypertape orders appear to be of the following formats. Since there
|
||||
is no documentation on them, I can going with what is shown in the
|
||||
IBSYS sources.
|
||||
|
||||
BCD translated:
|
||||
CTLW/CTLR 06u01 where u is unit numder
|
||||
CTLW/CTLR 07u01 Backwords reading, where u is unit numder
|
||||
CTL 06uoo01 Where u is unit number, and oo is order code
|
||||
3x or 42
|
||||
*/
|
||||
|
||||
#include "i7000_defs.h"
|
||||
#include "sim_tape.h"
|
||||
|
||||
#ifdef NUM_DEVS_HT
|
||||
#define BUFFSIZE (MAXMEMSIZE * CHARSPERWORD)
|
||||
|
||||
#define UNIT_HT(x) UNIT_ATTABLE|UNIT_DISABLE|UNIT_ROABLE|UNIT_S_CHAN(x)| \
|
||||
UNIT_SELECT
|
||||
|
||||
#if defined(HTSIZE)
|
||||
#undef HTSIZE
|
||||
#endif
|
||||
#define HTSIZE 31731000
|
||||
|
||||
/* in u3 is device address */
|
||||
/* in u4 is current buffer position */
|
||||
/* in u5 */
|
||||
#define HT_CMDMSK 00000077 /* Command being run */
|
||||
#define HT_NOTRDY 00000100 /* Devices is running a command */
|
||||
#define HT_IDLE 00000200 /* Tape still in motion */
|
||||
#define HT_MARK 00000400 /* Hit tape mark */
|
||||
#define HT_EOR 00001000 /* Hit end of record */
|
||||
#define HT_ERR 00002000 /* Device recieved error */
|
||||
#define HT_BOT 00004000 /* Unit at begining of tape */
|
||||
#define HT_EOT 00010000 /* Unit at end of tape */
|
||||
#define HT_ATTN 00020000 /* Unit requests attntion */
|
||||
#define HT_MOVE 00040000 /* Unit is moving to new record */
|
||||
#define HT_WRITE 00100000 /* Were we writing */
|
||||
#define HT_SNS 00200000 /* We were doing sense */
|
||||
#define HT_CMD 00400000 /* We are fetching a command */
|
||||
#define HT_PEND 01000000 /* Hold channel while command runs */
|
||||
|
||||
/* Hypertape commands */
|
||||
#define HNOP 0x00 /* Nop */
|
||||
#define HEOS 0x01 /* End of sequence */
|
||||
#define HRLF 0x02 /* Reserved Light Off */
|
||||
#define HRLN 0x03 /* Reserved Light On */
|
||||
#define HCLF 0x04 /* Check light off? Not documented by might
|
||||
be valid command */
|
||||
#define HCLN 0x05 /* Check light on */
|
||||
#define HSEL 0x06 /* Select */
|
||||
#define HSBR 0x07 /* Select for backwards reading */
|
||||
#define HCCR 0x28 /* Change cartridge and rewind */
|
||||
#define HRWD 0x30 /* Rewind */
|
||||
#define HRUN 0x31 /* Rewind and unload */
|
||||
#define HERG 0x32 /* Erase long gap */
|
||||
#define HWTM 0x33 /* Write tape mark */
|
||||
#define HBSR 0x34 /* Backspace */
|
||||
#define HBSF 0x35 /* Backspace file */
|
||||
#define HSKR 0x36 /* Space */
|
||||
#define HSKF 0x37 /* Space file */
|
||||
#define HCHC 0x38 /* Change Cartridge */
|
||||
#define HUNL 0x39 /* Unload Cartridge */
|
||||
#define HFPN 0x42 /* File Protect On */
|
||||
|
||||
/* Hypertape sense word 1 codes */
|
||||
/* 01234567 */
|
||||
#define SEL_MASK 0x0F000000 /* Selected unit mask */
|
||||
#define STAT_NOTRDY 0x80800000 /* Drive not ready */
|
||||
#define PROG_NOTLOAD 0x40400000 /* *Drive not loaded */
|
||||
#define PROG_FILEPROT 0x40200000 /* Drive write protected */
|
||||
#define PROG_INVCODE 0x40080000 /* Invalid code */
|
||||
#define PROG_BUSY 0x40040000 /* Drive Busy */
|
||||
#define PROG_BOT 0x40020000 /* Drive at BOT BSR/BSF requested */
|
||||
#define PROG_EOT 0x40010000 /* Drive at EOT forward motion requested. */
|
||||
#define DATA_CHECK 0x20008000 /* *Error corrected */
|
||||
#define DATA_PARITY 0x20004000 /* *Parity error */
|
||||
#define DATA_CODECHK 0x20002000 /* *Code check */
|
||||
#define DATA_ENVCHK 0x20001000 /* *Envelop error */
|
||||
#define DATA_RESPONSE 0x20000800 /* Response check */
|
||||
#define DATA_EXECSKEW 0x20000400 /* *Excessive skew check */
|
||||
#define DATA_TRACKSKEW 0x20000200 /* *Track skew check */
|
||||
#define EXP_MARK 0x10000080 /* Drive read a mark */
|
||||
#define EXP_EWA 0x10000040 /* *Drive near EOT */
|
||||
#define EXP_NODATA 0x10000020 /* *No data transfered */
|
||||
#define READ_BSY 0x00000008 /* *Controller reading */
|
||||
#define WRITE_BSY 0x00000004 /* *Controller writing */
|
||||
#define BACK_MODE 0x00000002 /* *Backwards mode */
|
||||
|
||||
uint32 ht_cmd(UNIT *, uint16, uint16);
|
||||
t_stat ht_srv(UNIT *);
|
||||
t_stat htc_srv(UNIT *);
|
||||
void ht_tape_cmd(DEVICE *, UNIT *);
|
||||
t_stat ht_error(UNIT *, int, t_stat);
|
||||
t_stat ht_boot(int32, DEVICE *);
|
||||
t_stat ht_reset(DEVICE *);
|
||||
t_stat ht_attach(UNIT *, CONST char *);
|
||||
t_stat ht_detach(UNIT *);
|
||||
t_stat ht_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *ht_description (DEVICE *dptr);
|
||||
void ht_tape_posterr(UNIT * uptr, uint32 error);
|
||||
|
||||
|
||||
|
||||
/* One buffer per channel */
|
||||
uint8 ht_unit[NUM_CHAN * 2]; /* Currently selected unit */
|
||||
uint8 ht_buffer[NUM_DEVS_HT+1][BUFFSIZE];
|
||||
int ht_cmdbuffer[NUM_CHAN]; /* Buffer holding command ids */
|
||||
int ht_cmdcount[NUM_CHAN]; /* Count of command digits recieved */
|
||||
uint32 ht_sense[NUM_CHAN * 2]; /* Sense data for unit */
|
||||
|
||||
UNIT hta_unit[] = {
|
||||
/* Controller 1 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 0 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 1 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 2 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 3 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 4 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 5 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 6 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 7 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 8 */
|
||||
{UDATA(&ht_srv, UNIT_HT(5), HTSIZE)}, /* 9 */
|
||||
{UDATA(&htc_srv, UNIT_S_CHAN(5)|UNIT_DISABLE|UNIT_DIS, 0)}, /* Controller */
|
||||
#if NUM_DEVS_HT > 1
|
||||
/* Controller 2 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 0 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 1 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 2 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 3 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 4 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 5 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 6 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 7 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 8 */
|
||||
{UDATA(&ht_srv, UNIT_HT(8), HTSIZE)}, /* 9 */
|
||||
{UDATA(&htc_srv, UNIT_S_CHAN(8)|UNIT_DISABLE|UNIT_DIS, 0)}, /* Controller */
|
||||
#endif
|
||||
};
|
||||
|
||||
MTAB ht_mod[] = {
|
||||
{MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL, NULL, NULL,
|
||||
"Write ring in place"},
|
||||
{MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL, NULL, NULL,
|
||||
"no Write ring in place"},
|
||||
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL,
|
||||
"Set/Display tape format (SIMH, E11, TPC, P7B)" },
|
||||
{MTAB_XTD | MTAB_VUN, 0, "LENGTH", "LENGTH",
|
||||
NULL, &sim_tape_show_capac, NULL,
|
||||
"Set unit n capacity to arg MB (0 = unlimited)" },
|
||||
{MTAB_XTD | MTAB_VDV | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan, &get_chan,
|
||||
NULL, "Set Channel for device"},
|
||||
#ifndef I7010 /* Not sure 7010 ever supported hypertapes */
|
||||
{MTAB_XTD | MTAB_VDV | MTAB_VALR, 0, "SELECT", "SELECT",
|
||||
&chan9_set_select, &chan9_get_select, NULL,
|
||||
"Set unit number"},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE hta_dev = {
|
||||
"HTA", hta_unit, NULL, ht_mod,
|
||||
NUM_UNITS_HT + 1, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, &ht_reset, &ht_boot, &ht_attach, &ht_detach,
|
||||
&ht_dib, DEV_BUF_NUM(0) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &ht_help, NULL, NULL, &ht_description
|
||||
};
|
||||
|
||||
#if NUM_DEVS_HT > 1
|
||||
DEVICE htb_dev = {
|
||||
"HTB", &hta_unit[NUM_UNITS_HT + 1], NULL, ht_mod,
|
||||
NUM_UNITS_HT + 1, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, &ht_reset, &ht_boot, &ht_attach, &ht_detach,
|
||||
&ht_dib, DEV_BUF_NUM(1) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &ht_help, NULL, NULL, &ht_description
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
uint32 ht_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int chan = UNIT_G_CHAN(dptr->units[0].flags);
|
||||
UNIT *u = &dptr->units[NUM_UNITS_HT];
|
||||
|
||||
/* Activate the device to start doing something */
|
||||
ht_cmdbuffer[chan] = 0;
|
||||
ht_cmdcount[chan] = 0;
|
||||
sim_activate(u, 10);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat htc_srv(UNIT * uptr)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int chan = UNIT_G_CHAN(dptr->units[0].flags);
|
||||
int sel;
|
||||
int schan;
|
||||
|
||||
sel = (dptr->units[0].flags & UNIT_SELECT) ? 1 : 0;
|
||||
if (sel != chan_test(chan, CTL_SEL))
|
||||
return SCPE_OK;
|
||||
schan = (chan * 2) + sel;
|
||||
/* Drive is busy */
|
||||
if (uptr->u5 & HT_NOTRDY) {
|
||||
sim_debug(DEBUG_EXP, dptr, "Controller busy\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Handle sense on unit */
|
||||
if (chan_test(chan, CTL_SNS)) {
|
||||
uint8 ch = 0;
|
||||
int eor = 0;
|
||||
int i;
|
||||
UNIT *up;
|
||||
switch(ht_cmdcount[chan]) {
|
||||
case 0: ch = (ht_sense[schan] >> 24) & 0xF;
|
||||
uptr->u5 |= HT_SNS;
|
||||
chan9_clear_error(chan, sel);
|
||||
sim_debug(DEBUG_SNS, dptr, "Sense %08x\n", ht_sense[schan]);
|
||||
break;
|
||||
case 1: ch = ht_unit[schan];
|
||||
break;
|
||||
case 2: case 3: case 4: case 5: case 6: case 7:
|
||||
ch = (ht_sense[schan] >> (4 * (7 - ht_cmdcount[chan]))) & 0xF;
|
||||
break;
|
||||
case 10:
|
||||
eor = DEV_REOR;
|
||||
/* Fall through */
|
||||
case 9:
|
||||
case 8:
|
||||
i = 4 * (ht_cmdcount[chan] - 8);
|
||||
up = &dptr->units[i];
|
||||
ch = 0;
|
||||
for (i = 3; i >= 0; i--, up++) {
|
||||
if (up->u5 & HT_ATTN)
|
||||
ch |= 1 << i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Fix out of align bit */
|
||||
if (ch & 010)
|
||||
ch ^= 030;
|
||||
|
||||
sim_debug(DEBUG_DATA, dptr, "sense %d %02o ", ht_cmdcount[chan], ch);
|
||||
ht_cmdcount[chan]++;
|
||||
switch(chan_write_char(chan, &ch, eor)) {
|
||||
case TIME_ERROR:
|
||||
case END_RECORD:
|
||||
ht_sense[schan] = 0;
|
||||
/* Fall through */
|
||||
case DATA_OK:
|
||||
uptr->u5 |= HT_SNS; /* So we catch disconnect */
|
||||
if (eor) {
|
||||
ht_sense[schan] = 0;
|
||||
for (up = dptr->units, i = NUM_UNITS_HT; i >= 0; i--, up++)
|
||||
up->u5 &= ~HT_ATTN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sim_activate(uptr, us_to_ticks(50));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* If control, go collect it */
|
||||
if (chan_test(chan, CTL_CNTL)) {
|
||||
uptr->u5 |= HT_CMD;
|
||||
ht_tape_cmd(dptr, uptr);
|
||||
sim_activate(uptr, us_to_ticks(50));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Channel has disconnected, abort current operation. */
|
||||
if (uptr->u5 & (HT_SNS|HT_CMD) && chan_stat(chan, DEV_DISCO)) {
|
||||
uptr->u5 &= ~(HT_SNS|HT_CMD);
|
||||
chan_clear(chan, DEV_WEOR|DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, dptr, "control disconnecting\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat ht_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
UNIT *ctlr = &dptr->units[NUM_UNITS_HT];
|
||||
int sel;
|
||||
int schan;
|
||||
t_stat r;
|
||||
t_mtrlnt reclen;
|
||||
|
||||
sel = (uptr->flags & UNIT_SELECT) ? 1 : 0;
|
||||
schan = (chan * 2) + sel;
|
||||
|
||||
/* Handle seeking */
|
||||
if (uptr->wait > 0) {
|
||||
uptr->wait--;
|
||||
if (uptr->wait == 0) {
|
||||
if (uptr->u5 & HT_PEND) {
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
ctlr->u5 &= ~(HT_NOTRDY);
|
||||
sim_activate(ctlr, us_to_ticks(50)); /* Schedule control to disco */
|
||||
} else {
|
||||
uptr->u5 |= HT_ATTN;
|
||||
chan9_set_attn(chan, sel);
|
||||
}
|
||||
uptr->u5 &= ~(HT_PEND | HT_NOTRDY | HT_CMDMSK);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d Seek done\n", unit);
|
||||
} else
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (sel != chan_test(chan, CTL_SEL))
|
||||
return SCPE_OK;
|
||||
|
||||
/* Channel has disconnected, abort current operation. */
|
||||
if ((uptr->u5 & HT_CMDMSK) == HSEL && chan_stat(chan, DEV_DISCO)) {
|
||||
if (uptr->u5 & HT_WRITE) {
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
"Write flush Block %d chars %d words\n", uptr->u6,
|
||||
uptr->u6 / 6);
|
||||
r = sim_tape_wrrecf(uptr, &ht_buffer[GET_DEV_BUF(dptr->flags)][0],
|
||||
uptr->u6);
|
||||
uptr->u5 &= ~HT_WRITE;
|
||||
if (r != MTSE_OK) {
|
||||
ht_error(uptr, schan, r);
|
||||
chan9_set_attn(chan, sel);
|
||||
}
|
||||
uptr->u6 = 0;
|
||||
}
|
||||
uptr->u5 &= ~(HT_NOTRDY | HT_CMDMSK);
|
||||
ctlr->u5 &= ~(HT_NOTRDY);
|
||||
chan_clear(chan, DEV_WEOR|DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, dptr, "disconnecting\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Handle writing of data */
|
||||
if (chan_test(chan, CTL_WRITE) && (uptr->u5 & HT_CMDMSK) == HSEL) {
|
||||
uint8 ch;
|
||||
|
||||
if (uptr->u6 == 0 && sim_tape_wrp(uptr)) {
|
||||
ctlr->u5 &= ~(HT_NOTRDY);
|
||||
ht_tape_posterr(uptr, PROG_FILEPROT);
|
||||
sim_activate(uptr, us_to_ticks(50));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
switch(chan_read_char(chan, &ch, 0)) {
|
||||
case TIME_ERROR:
|
||||
ht_tape_posterr(uptr, DATA_RESPONSE);
|
||||
break;
|
||||
case DATA_OK:
|
||||
uptr->u5 |= HT_WRITE|HT_NOTRDY;
|
||||
ctlr->u5 |= HT_NOTRDY;
|
||||
ht_buffer[GET_DEV_BUF(dptr->flags)][uptr->u6++] = ch;
|
||||
sim_debug(DEBUG_DATA, dptr, " write %d \n", ch);
|
||||
if (uptr->u6 < BUFFSIZE)
|
||||
break;
|
||||
/* Overran tape buffer, give error */
|
||||
ht_tape_posterr(uptr, DATA_TRACKSKEW);
|
||||
case END_RECORD:
|
||||
if (uptr->u6 != 0) {
|
||||
sim_debug(DEBUG_CMD, dptr,
|
||||
" Write Block %d chars %d words\n", uptr->u6,
|
||||
uptr->u6 / 6);
|
||||
r = sim_tape_wrrecf(uptr,
|
||||
&ht_buffer[GET_DEV_BUF(dptr->flags)][0],
|
||||
uptr->u6);
|
||||
uptr->u5 &= ~HT_WRITE;
|
||||
uptr->u6 = 0;
|
||||
if (r != MTSE_OK) {
|
||||
ht_error(uptr, schan, r);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
}
|
||||
}
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
}
|
||||
sim_activate(uptr, us_to_ticks(20));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Handle reading of data */
|
||||
if (chan_test(chan, CTL_READ) && (uptr->u5 & HT_CMDMSK) == (HSEL)) {
|
||||
uint8 ch;
|
||||
|
||||
if (uptr->u6 == 0) {
|
||||
if (ht_sense[schan] & BACK_MODE)
|
||||
r = sim_tape_rdrecr(uptr,
|
||||
&ht_buffer[GET_DEV_BUF(dptr->flags)][0],
|
||||
&reclen, BUFFSIZE);
|
||||
else
|
||||
r = sim_tape_rdrecf(uptr,
|
||||
&ht_buffer[GET_DEV_BUF(dptr->flags)][0],
|
||||
&reclen, BUFFSIZE);
|
||||
if (r == MTSE_TMK)
|
||||
sim_debug(DEBUG_CMD, dptr, "Read Mark\n");
|
||||
else
|
||||
sim_debug(DEBUG_CMD, dptr, "Read %d bytes\n", reclen);
|
||||
/* Handle EOM special */
|
||||
if (r == MTSE_EOM && (uptr->u5 & HT_EOT) == 0) {
|
||||
uptr->u5 |= HT_EOT;
|
||||
ht_sense[schan] |= EXP_NODATA;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
ctlr->u5 &= ~HT_NOTRDY;
|
||||
sim_activate(uptr, us_to_ticks(20));
|
||||
return SCPE_OK;
|
||||
} else
|
||||
/* Not read ok, return error */
|
||||
if (r != MTSE_OK) {
|
||||
ht_error(uptr, schan, r);
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
ctlr->u5 &= ~HT_NOTRDY;
|
||||
uptr->wait = 0;
|
||||
sim_activate(uptr, us_to_ticks(50));
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->hwmark = reclen;
|
||||
uptr->u5 |= HT_NOTRDY;
|
||||
ctlr->u5 |= HT_NOTRDY;
|
||||
}
|
||||
|
||||
if (uptr->u6 > (int32)uptr->hwmark) {
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
sim_activate(uptr, us_to_ticks(50));
|
||||
return SCPE_OK;
|
||||
}
|
||||
ch = ht_buffer[GET_DEV_BUF(dptr->flags)][uptr->u6++];
|
||||
sim_debug(DEBUG_DATA, dptr, "data %02o\n", ch);
|
||||
switch(chan_write_char(chan, &ch,
|
||||
(uptr->u6 > (int32)uptr->hwmark)?DEV_REOR:0)) {
|
||||
case TIME_ERROR:
|
||||
/* Nop flag as timming error */
|
||||
ht_tape_posterr(uptr, DATA_RESPONSE);
|
||||
break;
|
||||
case END_RECORD:
|
||||
sim_debug(DEBUG_DATA, dptr, "eor\n");
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
case DATA_OK:
|
||||
break;
|
||||
}
|
||||
sim_activate(uptr, us_to_ticks(20));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* If we have a command, keep scheduling us. */
|
||||
if ((uptr->u5 & HT_CMDMSK) == (HSEL))
|
||||
sim_activate(uptr, us_to_ticks(50));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Post a error on a given unit. */
|
||||
void
|
||||
ht_tape_posterr(UNIT * uptr, uint32 error)
|
||||
{
|
||||
int chan;
|
||||
int schan;
|
||||
int sel;
|
||||
|
||||
chan = UNIT_G_CHAN(uptr->flags);
|
||||
sel = (uptr->flags & UNIT_SELECT) ? 1 : 0;
|
||||
schan = (chan * 2) + sel;
|
||||
uptr->u5 |= HT_ATTN;
|
||||
ht_sense[schan] = error;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_attn(chan, sel);
|
||||
if (error != 0)
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
}
|
||||
|
||||
/* Convert error codes to sense codes */
|
||||
t_stat ht_error(UNIT * uptr, int schan, t_stat r)
|
||||
{
|
||||
switch (r) {
|
||||
case MTSE_OK: /* no error */
|
||||
break;
|
||||
|
||||
case MTSE_TMK: /* tape mark */
|
||||
uptr->u5 |= HT_MARK;
|
||||
ht_sense[schan] |= EXP_MARK;
|
||||
break;
|
||||
|
||||
case MTSE_WRP: /* write protected */
|
||||
uptr->u5 |= HT_ATTN;
|
||||
ht_sense[schan] |= PROG_FILEPROT;
|
||||
break;
|
||||
|
||||
case MTSE_UNATT: /* unattached */
|
||||
uptr->u5 |= HT_ATTN;
|
||||
ht_sense[schan] = PROG_NOTLOAD;
|
||||
break;
|
||||
|
||||
case MTSE_IOERR: /* IO error */
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
case MTSE_FMT: /* invalid format */
|
||||
case MTSE_RECE: /* error in record */
|
||||
uptr->u5 |= HT_ERR;
|
||||
ht_sense[schan] |= DATA_CODECHK;
|
||||
break;
|
||||
case MTSE_BOT: /* beginning of tape */
|
||||
uptr->u5 |= HT_BOT;
|
||||
ht_sense[schan] |= PROG_BOT;
|
||||
break;
|
||||
case MTSE_EOM: /* end of medium */
|
||||
uptr->u5 |= HT_EOT;
|
||||
ht_sense[schan] |= PROG_EOT;
|
||||
break;
|
||||
default: /* Anything else if error */
|
||||
ht_sense[schan] = PROG_INVCODE;
|
||||
break;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Process command */
|
||||
void
|
||||
ht_tape_cmd(DEVICE * dptr, UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int sel = (uptr->flags & UNIT_SELECT) ? 1 : 0;
|
||||
int schan = (chan * 2) + sel;
|
||||
UNIT *up;
|
||||
uint8 c;
|
||||
int i;
|
||||
int t;
|
||||
int cmd;
|
||||
int unit;
|
||||
t_stat r;
|
||||
t_mtrlnt reclen;
|
||||
|
||||
/* Get information on unit */
|
||||
|
||||
/* Check if we have a command yet */
|
||||
switch(chan_read_char(chan, &c, 0)) {
|
||||
case END_RECORD:
|
||||
case TIME_ERROR:
|
||||
return;
|
||||
case DATA_OK:
|
||||
break;
|
||||
}
|
||||
|
||||
c &= 017;
|
||||
if (c == 012)
|
||||
c = 0;
|
||||
ht_cmdbuffer[chan] <<= 4;
|
||||
ht_cmdbuffer[chan] |= c;
|
||||
ht_cmdcount[chan]++;
|
||||
/* If did not find end of sequence, request more */
|
||||
if ((ht_cmdbuffer[chan] & 0xff) != HEOS) {
|
||||
if (ht_cmdcount[chan] >= 8) {
|
||||
/* command error */
|
||||
ht_cmdcount[chan] = 0;
|
||||
ht_sense[schan] = PROG_INVCODE;
|
||||
ht_unit[schan] = 0;
|
||||
chan_set(chan, DEV_REOR|SNS_UEND);
|
||||
uptr->u5 &= ~HT_CMD;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_DETAIL, dptr, " cmd = %08x %d nybbles ",
|
||||
ht_cmdbuffer[chan], ht_cmdcount[chan]);
|
||||
|
||||
/* See if we have a whole command string yet */
|
||||
uptr->u5 &= ~HT_CMD;
|
||||
cmd = 0xff;
|
||||
unit = NUM_UNITS_HT + 1;
|
||||
for (i = ht_cmdcount[chan] - 2; i >= 2; i -= 2) {
|
||||
t = (ht_cmdbuffer[chan] >> (i * 4)) & 0xff;
|
||||
switch (t) {
|
||||
case HSEL: /* Select */
|
||||
case HSBR: /* Select for backwards reading */
|
||||
i--;
|
||||
unit = (ht_cmdbuffer[chan] >> (i * 4)) & 0xf;
|
||||
ht_sense[schan] = 0; /* Clear sense codes */
|
||||
cmd = t;
|
||||
break;
|
||||
case HEOS: /* End of sequence */
|
||||
break;
|
||||
case HRLF: /* Reserved Light Off */
|
||||
case HRLN: /* Reserved Light On */
|
||||
case HCLF: /* Check light off */
|
||||
case HCLN: /* Check light on */
|
||||
case HNOP: /* Nop */
|
||||
case HCCR: /* Change cartridge and rewind */
|
||||
case HRWD: /* Rewind */
|
||||
case HRUN: /* Rewind and unload */
|
||||
case HERG: /* Erase long gap */
|
||||
case HWTM: /* Write tape mark */
|
||||
case HBSR: /* Backspace */
|
||||
case HBSF: /* Backspace file */
|
||||
case HSKR: /* Space */
|
||||
case HSKF: /* Space file */
|
||||
case HCHC: /* Change Cartridge */
|
||||
case HUNL: /* Unload Cartridge */
|
||||
case HFPN: /* File Protect On */
|
||||
if (cmd != HSEL)
|
||||
cmd = 0xff;
|
||||
else
|
||||
cmd = t;
|
||||
break;
|
||||
default:
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "Invalid command %x\n",
|
||||
cmd);
|
||||
ht_sense[schan] = PROG_INVCODE;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ok got a full command */
|
||||
ht_cmdcount[chan] = 0;
|
||||
|
||||
/* Make sure we got a unit and command */
|
||||
if (unit <= NUM_UNITS_HT)
|
||||
ht_unit[schan] = unit;
|
||||
else {
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr,
|
||||
"Invalid unit %d cmd=%x\n", unit, cmd);
|
||||
ht_sense[schan] = STAT_NOTRDY;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0xff) {
|
||||
/* command error */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "Invalid command %x\n",
|
||||
cmd);
|
||||
ht_sense[schan] = PROG_INVCODE;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find real device this command is for */
|
||||
up = &dptr->units[unit];
|
||||
if ((up->flags & UNIT_ATT) == 0) {
|
||||
/* Not attached! */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "Not ready %d cmd=%x\n",
|
||||
unit, cmd);
|
||||
ht_sense[schan] = STAT_NOTRDY;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (up->u5 & HT_NOTRDY || up->wait > 0) {
|
||||
/* Unit busy */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "Busy unit %d cmd=%x\n", unit,
|
||||
cmd);
|
||||
ht_sense[schan] = PROG_BUSY;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
return;
|
||||
}
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "Execute unit %d cmd=%x ",
|
||||
unit, cmd);
|
||||
|
||||
/* Ok, unit is ready and not in motion, set up to run command */
|
||||
up->u5 &= ~(HT_PEND | HT_MARK | HT_ERR | HT_CMDMSK);
|
||||
up->wait = 0;
|
||||
up->u5 |= cmd;
|
||||
ht_sense[schan] &= ~BACK_MODE;
|
||||
r = MTSE_OK;
|
||||
switch (cmd) {
|
||||
case HSBR: /* Select for backwards reading */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "HSBR\n");
|
||||
up->hwmark = -1;
|
||||
up->u6 = 0;
|
||||
ht_sense[schan] |= BACK_MODE;
|
||||
up->u5 &= ~(HT_CMDMSK);
|
||||
up->u5 |= HSEL;
|
||||
chan_set(chan, DEV_REOR|DEV_SEL);
|
||||
break;
|
||||
|
||||
case HSEL: /* Select */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "HSEL\n");
|
||||
up->hwmark = -1;
|
||||
up->u6 = 0;
|
||||
chan_set(chan, DEV_REOR|DEV_SEL);
|
||||
break;
|
||||
|
||||
case HRLF: /* Reserved Light Off */
|
||||
case HRLN: /* Reserved Light On */
|
||||
case HCLF: /* Check light off */
|
||||
case HCLN: /* Check light on */
|
||||
case HFPN: /* File Protect On (Nop for now ) */
|
||||
case HEOS: /* End of sequence */
|
||||
case HNOP: /* Nop */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "NOP\n");
|
||||
up->u5 &= ~(HT_NOTRDY | HT_CMDMSK);
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
return;
|
||||
|
||||
case HRWD: /* Rewind */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "REW\n");
|
||||
if (up->u5 & HT_BOT) {
|
||||
r = MTSE_OK;
|
||||
up->wait = 1;
|
||||
} else {
|
||||
r = sim_tape_rewind(up);
|
||||
up->u5 &= ~HT_EOT;
|
||||
up->wait = 500;
|
||||
}
|
||||
up->u5 |= HT_BOT|HT_NOTRDY;
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
break;
|
||||
|
||||
case HERG: /* Erase long gap */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "ERG\n");
|
||||
if (sim_tape_wrp(up)) {
|
||||
r = MTSE_WRP;
|
||||
} else {
|
||||
up->wait = 10;
|
||||
up->u5 |= HT_PEND|HT_NOTRDY;
|
||||
uptr->u5 |= HT_NOTRDY;
|
||||
up->u5 &= ~HT_BOT;
|
||||
}
|
||||
break;
|
||||
|
||||
case HWTM: /* Write tape mark */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "WTM\n");
|
||||
if (sim_tape_wrp(up)) {
|
||||
r = MTSE_WRP;
|
||||
} else {
|
||||
r = sim_tape_wrtmk(up);
|
||||
up->wait = 5;
|
||||
up->u5 |= HT_PEND|HT_NOTRDY;
|
||||
up->u5 &= ~(HT_BOT|HT_EOT);
|
||||
uptr->u5 |= HT_NOTRDY;
|
||||
}
|
||||
break;
|
||||
|
||||
case HBSR: /* Backspace */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "BSR\n");
|
||||
if (sim_tape_bot(up)) {
|
||||
r = MTSE_BOT;
|
||||
break;
|
||||
}
|
||||
r = sim_tape_sprecr(up, &reclen);
|
||||
up->wait = reclen / 100;
|
||||
up->wait += 2;
|
||||
up->u5 |= HT_PEND|HT_NOTRDY;
|
||||
up->u5 &= ~(HT_BOT|HT_EOT);
|
||||
uptr->u5 |= HT_NOTRDY;
|
||||
if (r == MTSE_TMK) {
|
||||
r = MTSE_OK;
|
||||
up->u5 |= HT_MARK;
|
||||
}
|
||||
if (sim_tape_bot(up))
|
||||
up->u5 |= HT_BOT;
|
||||
else
|
||||
up->u5 &= ~HT_BOT;
|
||||
break;
|
||||
|
||||
case HBSF: /* Backspace file */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "BSF\n");
|
||||
if (sim_tape_bot(up)) {
|
||||
r = MTSE_BOT;
|
||||
break;
|
||||
}
|
||||
while ((r = sim_tape_sprecr(up, &reclen)) == MTSE_OK) {
|
||||
up->wait += reclen;
|
||||
}
|
||||
up->wait /= 100;
|
||||
up->wait += 2;
|
||||
up->u5 |= HT_PEND|HT_NOTRDY;
|
||||
up->u5 &= ~(HT_BOT|HT_EOT);
|
||||
uptr->u5 |= HT_NOTRDY;
|
||||
if (r == MTSE_TMK) {
|
||||
r = MTSE_OK;
|
||||
up->u5 |= HT_MARK;
|
||||
}
|
||||
if (sim_tape_bot(up))
|
||||
up->u5 |= HT_BOT;
|
||||
else
|
||||
up->u5 &= ~HT_BOT;
|
||||
break;
|
||||
|
||||
case HSKR: /* Space */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "SKR\n");
|
||||
r = sim_tape_sprecf(up, &reclen);
|
||||
up->u5 |= HT_PEND|HT_NOTRDY;
|
||||
uptr->u5 |= HT_NOTRDY;
|
||||
if (r == MTSE_TMK) {
|
||||
r = MTSE_OK;
|
||||
up->u5 |= HT_MARK;
|
||||
}
|
||||
up->wait = reclen / 100;
|
||||
up->wait += 2;
|
||||
up->u5 &= ~HT_BOT;
|
||||
break;
|
||||
|
||||
case HSKF: /* Space file */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "SKF\n");
|
||||
while ((r = sim_tape_sprecf(up, &reclen)) == MTSE_OK) {
|
||||
up->wait += reclen;
|
||||
}
|
||||
up->wait /= 100;
|
||||
up->wait += 2;
|
||||
up->u5 |= HT_PEND|HT_NOTRDY;
|
||||
uptr->u5 |= HT_NOTRDY;
|
||||
if (r == MTSE_TMK) {
|
||||
r = MTSE_OK;
|
||||
up->u5 |= HT_MARK;
|
||||
}
|
||||
up->u5 &= ~HT_BOT;
|
||||
break;
|
||||
|
||||
case HCCR: /* Change cartridge and rewind */
|
||||
case HRUN: /* Rewind and unload */
|
||||
case HCHC: /* Change Cartridge */
|
||||
case HUNL: /* Unload Cartridge */
|
||||
sim_debug((DEBUG_DETAIL | DEBUG_CMD), dptr, "RUN\n");
|
||||
r = sim_tape_detach(up);
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
up->u5 |= HT_NOTRDY;
|
||||
up->wait = 100;
|
||||
break;
|
||||
}
|
||||
|
||||
if (r != MTSE_OK) {
|
||||
ht_error(up, schan, r);
|
||||
chan9_set_error(chan, SNS_UEND);
|
||||
chan9_set_attn(chan, sel);
|
||||
chan_set(chan, DEV_REOR|CTL_END);
|
||||
up->u5 &= ~(HT_NOTRDY | HT_CMDMSK);
|
||||
uptr->u5 &= ~HT_NOTRDY;
|
||||
up->wait = 0;
|
||||
} else if (up->u5 & HT_CMDMSK) {
|
||||
sim_activate(up, us_to_ticks(1000));
|
||||
} else {
|
||||
chan9_set_attn(chan, sel);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Boot Hypertape. Build boot card loader in memory and transfer to it */
|
||||
t_stat
|
||||
ht_boot(int unit_num, DEVICE * dptr)
|
||||
{
|
||||
#ifdef I7090
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
int chan = UNIT_G_CHAN(uptr->flags) - 1;
|
||||
int sel = (uptr->flags & UNIT_SELECT) ? 1 : 0;
|
||||
int dev = uptr->u3;
|
||||
int msk = (chan / 2) | ((chan & 1) << 11);
|
||||
extern uint16 IC;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
|
||||
if (dev == 0)
|
||||
dev = 012;
|
||||
/* Build Boot program in memory */
|
||||
M[0] = 0000025000101LL; /* IOCD RSCQ,,21 */
|
||||
M[1] = 0006000000001LL; /* TCOA * */
|
||||
M[2] = 0002000000101LL; /* TRA RSCQ */
|
||||
|
||||
M[0101] = 0054000000113LL; /* RSCQ RSCC SMSQ Mod */
|
||||
M[0101] |= ((t_uint64) (msk)) << 24;
|
||||
M[0102] = 0064500000000LL; /* SCDQ SCDC 0 Mod */
|
||||
M[0102] |= ((t_uint64) (msk)) << 24;
|
||||
M[0103] = 0044100000000LL; /* LDI 0 */
|
||||
M[0104] = 0405400001700LL; /* LFT 1700 */
|
||||
M[0105] = 0002000000122LL; /* TRA HYP7 */
|
||||
M[0106] = 0006000000102LL; /* TCOQ TCOC SCDQ Mod */
|
||||
M[0106] |= ((t_uint64) (chan)) << 24;
|
||||
M[0107] = 0002000000003LL; /* TRA 3 Enter IBSYS */
|
||||
M[0110] = 0120600120112LL;
|
||||
M[0110] |= ((t_uint64) (dev)) << 18;
|
||||
M[0111] = 0120600030412LL; /*LDVCY DVCY Mod */
|
||||
M[0111] |= ((t_uint64) (dev)) << 18;
|
||||
M[0112] = 0010000000000LL; /* * */
|
||||
M[0113] = 0700000000012LL; /* HYP6 SMS 10 */
|
||||
M[0113] |= sel;
|
||||
M[0114] = 0200000200110LL; /* CTLR *-4 */
|
||||
M[0115] = 0400001000116LL; /* CPYP *+1,,1 */
|
||||
M[0116] = 0000000000116LL; /* WTR * */
|
||||
M[0117] = 0100000000115LL; /* TCH *-2 */
|
||||
M[0120] = 0700000400113LL; /* SMS* HYP6 */
|
||||
M[0121] = 0200000000111LL; /* CTL HYP6-2 */
|
||||
M[0122] = 0076000000350LL; /* HYP7 RICC ** */
|
||||
M[0122] |= ((t_uint64) (chan)) << 9;
|
||||
M[0123] = 0054000000120LL; /* RSCC *-3 Mod */
|
||||
M[0123] |= ((t_uint64) (msk)) << 24;
|
||||
M[0124] = 0500000000000LL; /* CPYD 0,,0 */
|
||||
M[0125] = 0340000000125LL; /* TWT * */
|
||||
IC = 0101;
|
||||
return SCPE_OK;
|
||||
#else
|
||||
return SCPE_NOFNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
t_stat
|
||||
ht_reset(DEVICE * dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CHAN; i++) {
|
||||
ht_cmdbuffer[i] = ht_cmdcount[i] = 0;
|
||||
ht_sense[i] = 0;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
t_stat
|
||||
ht_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = sim_tape_attach(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u5 = HT_BOT /*|HT_ATTN */ ;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
ht_detach(UNIT * uptr)
|
||||
{
|
||||
uptr->u5 = 0;
|
||||
if (uptr->flags & UNIT_DIS) return SCPE_OK;
|
||||
return sim_tape_detach(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
ht_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "IBM 7340 Hypertape unit\n\n");
|
||||
help_set_chan_type(st, dptr, "IBM 7340 Hypertape");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
ht_description(DEVICE *dptr)
|
||||
{
|
||||
return "IBM 7340 Hypertape unit";
|
||||
}
|
||||
|
||||
#endif
|
529
I7000/i7000_lpr.c
Normal file
529
I7000/i7000_lpr.c
Normal file
|
@ -0,0 +1,529 @@
|
|||
/* i7000_lpr.c: IBM 7000 Line Printer.
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This is the standard line printer.
|
||||
|
||||
These units each buffer one record in local memory and signal
|
||||
ready when the buffer is full or empty. The channel must be
|
||||
ready to recieve/transmit data when they are activated since
|
||||
they will transfer their block during chan_cmd. All data is
|
||||
transmitted as BCD characters.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7000_defs.h"
|
||||
#include "sim_card.h"
|
||||
#include "sim_defs.h"
|
||||
#ifdef NUM_DEVS_LPR
|
||||
|
||||
#define UNIT_LPR UNIT_ATTABLE | UNIT_DISABLE
|
||||
|
||||
|
||||
/* Flags for line printer. */
|
||||
#define ECHO (1 << (UNIT_V_UF+0))
|
||||
#ifdef I7070
|
||||
#define ATTENA (1 << (UNIT_V_UF+1))
|
||||
#define ATTENB (1 << (UNIT_V_UF+2))
|
||||
#endif
|
||||
#ifdef I7080
|
||||
#define DOUBLE (1 << (UNIT_V_UF+1))
|
||||
#define PROGRAM (1 << (UNIT_V_UF+2))
|
||||
#endif
|
||||
|
||||
|
||||
/* std devices. data structures
|
||||
|
||||
lpr_dev Line Printer device descriptor
|
||||
lpr_unit Line Printer unit descriptor
|
||||
lpr_reg Line Printer register list
|
||||
lpr_mod Line Printer modifiers list
|
||||
*/
|
||||
|
||||
|
||||
struct _lpr_data
|
||||
{
|
||||
uint8 lbuff[145]; /* Output line buffer */
|
||||
}
|
||||
lpr_data[NUM_DEVS_LPR];
|
||||
|
||||
uint32 lpr_cmd(UNIT *, uint16, uint16);
|
||||
void lpr_ini(UNIT *, t_bool);
|
||||
t_stat lpr_srv(UNIT *);
|
||||
t_stat lpr_reset(DEVICE *);
|
||||
t_stat lpr_attach(UNIT *, CONST char *);
|
||||
t_stat lpr_detach(UNIT *);
|
||||
t_stat lpr_setlpp(UNIT *, int32, CONST char *, void *);
|
||||
t_stat lpr_getlpp(FILE *, UNIT *, int32, CONST void *);
|
||||
t_stat lpr_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *lpr_description(DEVICE *dptr);
|
||||
|
||||
UNIT lpr_unit[] = {
|
||||
{UDATA(lpr_srv, UNIT_S_CHAN(CHAN_CHUREC) | UNIT_LPR, 55), 300}, /* A */
|
||||
#if NUM_DEVS_LPR > 1
|
||||
{UDATA(lpr_srv, UNIT_S_CHAN(CHAN_CHUREC+1) | UNIT_LPR, 55), 300}, /* B */
|
||||
#endif
|
||||
};
|
||||
|
||||
MTAB lpr_mod[] = {
|
||||
{ECHO, 0, NULL, "NOECHO", NULL, NULL, NULL, "Don't echo to console"},
|
||||
{ECHO, ECHO, "ECHO", "ECHO", NULL, NULL, NULL, "Echo to console"},
|
||||
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LINESPERPAGE", "LINESPERPAGE",
|
||||
&lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"},
|
||||
#ifdef I7080
|
||||
{DOUBLE|PROGRAM, 0, "SINGLE", "SINGLE", NULL, NULL, NULL, "Single space output"},
|
||||
{DOUBLE|PROGRAM, DOUBLE, "DOUBLE", "DOUBLE", NULL, NULL, NULL, "Double space output"},
|
||||
{DOUBLE|PROGRAM, PROGRAM, "PROGRAM", "PROGRAM", NULL, NULL, NULL, "Programatic spacing"},
|
||||
#endif
|
||||
#ifdef I7070
|
||||
{ATTENA|ATTENB, 0, NULL, "NOATTEN", NULL, NULL, NULL, "No attention signal"},
|
||||
{ATTENA|ATTENB, ATTENA, "ATTENA", "ATTENA", NULL, NULL, NULL, "Signal Attention A"},
|
||||
{ATTENA|ATTENB, ATTENB, "ATTENB", "ATTENB", NULL, NULL, NULL, "Signal Attention B"},
|
||||
#endif
|
||||
#ifdef I7010
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
||||
&get_chan, NULL, "Set device channel"},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE lpr_dev = {
|
||||
"LP", lpr_unit, NULL, lpr_mod,
|
||||
NUM_DEVS_LPR, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, NULL, NULL, &lpr_attach, &lpr_detach,
|
||||
&lpr_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &lpr_help, NULL, NULL, &lpr_description
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Line printer routines
|
||||
*/
|
||||
|
||||
t_stat
|
||||
lpr_setlpp(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int i;
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
i = 0;
|
||||
while(*cptr != '\0') {
|
||||
if (*cptr < '0' || *cptr > '9')
|
||||
return SCPE_ARG;
|
||||
i = (i * 10) + (*cptr++) - '0';
|
||||
}
|
||||
if (i < 20 || i > 100)
|
||||
return SCPE_ARG;
|
||||
uptr->capac = i;
|
||||
uptr->u4 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_getlpp(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "linesperpage=%d", uptr->capac);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
print_line(UNIT * uptr, int chan, int unit)
|
||||
{
|
||||
/* Convert word record into column image */
|
||||
/* Check output type, if auto or text, try and convert record to bcd first */
|
||||
/* If failed and text report error and dump what we have */
|
||||
/* Else if binary or not convertable, dump as image */
|
||||
|
||||
char out[150]; /* Temp conversion buffer */
|
||||
int i;
|
||||
|
||||
if ((uptr->flags & (UNIT_ATT | ECHO)) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
|
||||
/* Try to convert to text */
|
||||
memset(out, 0, sizeof(out));
|
||||
|
||||
#ifdef I7080
|
||||
if (uptr->flags & PROGRAM) {
|
||||
switch(lpr_data[unit].lbuff[0] & 077) {
|
||||
case 060: /* suppress space */
|
||||
uptr->u5 |= URCSTA_SKIPAFT | (0 << 12);
|
||||
break;
|
||||
case 020: /* single space */
|
||||
break;
|
||||
case 012: /* double space */
|
||||
uptr->u5 |= URCSTA_SKIPAFT | (1 << 12);
|
||||
break;
|
||||
default:
|
||||
/* Skip channel */
|
||||
i = 0;
|
||||
switch(lpr_data[unit].lbuff[0] & 017) {
|
||||
case 3: i = 5 - (uptr->u4 % 5); break;
|
||||
case 2: i = 8 - (uptr->u4 % 8); break;
|
||||
case 1:
|
||||
case 9: if (uptr->u4 == 1)
|
||||
break;
|
||||
i = uptr->capac - uptr->u4 + 1; break;
|
||||
}
|
||||
if (i == 0)
|
||||
break;
|
||||
uptr->u5 |= URCSTA_SKIPAFT | (i << 12);
|
||||
}
|
||||
/* Scan each column */
|
||||
for (i = 0; i < 143; i++) {
|
||||
int bcd = lpr_data[unit].lbuff[i+1] & 077;
|
||||
|
||||
out[i] = sim_six_to_ascii[bcd];
|
||||
}
|
||||
} else {
|
||||
if (uptr->flags & DOUBLE)
|
||||
uptr->u5 |= URCSTA_SKIPAFT | (1 << 12);
|
||||
#endif
|
||||
/* Scan each column */
|
||||
for (i = 0; i < 144; i++) {
|
||||
int bcd = lpr_data[unit].lbuff[i] & 077;
|
||||
|
||||
out[i] = sim_six_to_ascii[bcd];
|
||||
}
|
||||
|
||||
#ifdef I7080
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Trim trailing spaces */
|
||||
for (--i; i > 0 && out[i] == ' '; i--) ;
|
||||
out[++i] = '\r';
|
||||
out[++i] = '\n';
|
||||
out[++i] = '\0';
|
||||
sim_debug(DEBUG_DETAIL, &lpr_dev, "WRS unit=%d [%s]\n", unit, &out[0]);
|
||||
|
||||
/* Print out buffer */
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite(&out, 1, i, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
int j = 0;
|
||||
|
||||
while (j <= i)
|
||||
sim_putchar(out[j++]);
|
||||
}
|
||||
uptr->u4++;
|
||||
if (uptr->u4 > (int32)uptr->capac) {
|
||||
uptr->u4 = 1;
|
||||
}
|
||||
|
||||
if (uptr->u5 & URCSTA_SKIPAFT) {
|
||||
i = (uptr->u5 >> 12) & 0x7f;
|
||||
if (i == 0) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO)
|
||||
sim_putchar('\r');
|
||||
} else {
|
||||
for (; i > 1; i--) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO)
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
uptr->u4++;
|
||||
if (uptr->u4 > (int32)uptr->capac) {
|
||||
uptr->u4 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
uptr->u5 &= ~(URCSTA_SKIPAFT|(0x7f << 12));
|
||||
}
|
||||
|
||||
if (uptr->u4 == 1)
|
||||
lpr_chan9[chan] = 1;
|
||||
#ifdef I7010
|
||||
if (uptr->u4 == uptr->capac)
|
||||
lpr_chan12[chan] = 1;
|
||||
#endif
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
uint32 lpr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - lpr_unit);
|
||||
#ifdef I7010
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* Are we currently tranfering? */
|
||||
if (uptr->u5 & URCSTA_WRITE)
|
||||
return SCPE_BUSY;
|
||||
|
||||
switch(cmd) {
|
||||
/* Test ready */
|
||||
case IO_TRS:
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
return SCPE_OK;
|
||||
break;
|
||||
|
||||
/* Suppress punch */
|
||||
case IO_RUN:
|
||||
sim_debug(DEBUG_CMD, &lpr_dev, "%d: Cmd RUN\n", u);
|
||||
uptr->u5 &= ~URCSTA_FULL;
|
||||
return SCPE_OK;
|
||||
|
||||
/* Get record from CPU */
|
||||
case IO_WRS:
|
||||
sim_debug(DEBUG_CMD, &lpr_dev, "%d: Cmd WRS\n", u);
|
||||
lpr_chan9[chan] = 0;
|
||||
#ifdef I7010
|
||||
lpr_chan12[chan] = 0;
|
||||
switch (dev & 017) {
|
||||
case 01:
|
||||
uptr->u5 |= URCSTA_WMKS;
|
||||
break;
|
||||
case 012:
|
||||
uptr->u5 &= ~URCSTA_WMKS;
|
||||
break;
|
||||
default:
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
#endif
|
||||
chan_set_sel(chan, 1);
|
||||
uptr->u5 |= URCSTA_WRITE;
|
||||
uptr->u3 = 0;
|
||||
if ((uptr->u5 & URCSTA_BUSY) == 0)
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
|
||||
case IO_CTL:
|
||||
sim_debug(DEBUG_CMD, &lpr_dev, "%d: Cmd CTL %02o\n", u, dev & 077);
|
||||
#ifdef I7010
|
||||
/* 1-0 immediate skip to channel */
|
||||
/* 00xxxx skip to channel immediate */
|
||||
/* 11xxxx skip to channel after */
|
||||
/* 1000xx space before */
|
||||
/* 0100xx space after */
|
||||
switch(dev & 060) {
|
||||
case 020: /* Space after */
|
||||
uptr->u5 |= URCSTA_SKIPAFT | ((dev & 03) << 12);
|
||||
break;
|
||||
case 040: /* Space before */
|
||||
for (i = dev & 03; i > 1; i--) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0: /* Skip channel immediate */
|
||||
case 060: /* Skip channel after */
|
||||
i = 0;
|
||||
switch(dev & 017) {
|
||||
case 3: i = 5 - (uptr->u4 % 5); break;
|
||||
case 2: i = 8 - (uptr->u4 % 8); break;
|
||||
case 1:
|
||||
case 9: if (uptr->u4 == 1)
|
||||
break;
|
||||
i = uptr->capac - uptr->u4 + 1; break;
|
||||
case 12: i = (uptr->capac/2) - uptr->u4; break;
|
||||
}
|
||||
if (i == 0)
|
||||
break;
|
||||
if (dev & 060) {
|
||||
uptr->u5 |= URCSTA_SKIPAFT | (i << 12);
|
||||
break;
|
||||
}
|
||||
for (; i > 0; i--) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (uptr->u4 == uptr->capac)
|
||||
lpr_chan12[chan] = 1;
|
||||
#endif
|
||||
if (uptr->u4 == 1)
|
||||
lpr_chan9[chan] = 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
chan_set_attn(chan);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
/* Handle transfer of data for printer */
|
||||
t_stat
|
||||
lpr_srv(UNIT *uptr) {
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - lpr_unit);
|
||||
/* Waiting for disconnect */
|
||||
if (uptr->u5 & URCSTA_WDISCO) {
|
||||
if (chan_stat(chan, DEV_DISCO)) {
|
||||
chan_clear(chan, DEV_SEL|DEV_WEOR);
|
||||
uptr->u5 &= ~ URCSTA_WDISCO;
|
||||
} else {
|
||||
/* No disco yet, try again in a bit */
|
||||
sim_activate(uptr, 50);
|
||||
return SCPE_OK;
|
||||
}
|
||||
/* If still busy, schedule another wait */
|
||||
if (uptr->u5 & URCSTA_BUSY)
|
||||
sim_activate(uptr, uptr->wait);
|
||||
}
|
||||
|
||||
if (uptr->u5 & URCSTA_BUSY) {
|
||||
/* Done waiting, print line */
|
||||
if (uptr->u5 & URCSTA_FULL) {
|
||||
uptr->u5 &= ~URCSTA_FULL;
|
||||
switch(print_line(uptr, chan, u)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
memset(&lpr_data[u].lbuff[0], 0, 144);
|
||||
uptr->u5 &= ~URCSTA_BUSY;
|
||||
#ifdef I7070
|
||||
switch(uptr->flags & (ATTENA|ATTENB)) {
|
||||
case ATTENA: chan_set_attn_a(chan); break;
|
||||
case ATTENB: chan_set_attn_b(chan); break;
|
||||
}
|
||||
#endif
|
||||
#ifdef I7010
|
||||
chan_set_attn_urec(chan, lpr_dib.addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Copy next column over */
|
||||
if (uptr->u5 & URCSTA_WRITE && uptr->u3 < 144) {
|
||||
switch(chan_read_char(chan, &lpr_data[u].lbuff[uptr->u3],
|
||||
(uptr->u3 == 143)?DEV_REOR: 0)) {
|
||||
case TIME_ERROR:
|
||||
case END_RECORD:
|
||||
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
|
||||
uptr->u5 &= ~URCSTA_WRITE;
|
||||
break;
|
||||
case DATA_OK:
|
||||
sim_debug(DEBUG_DATA, &lpr_dev, "%d: Char < %02o\n", u,
|
||||
lpr_data[u].lbuff[uptr->u3]);
|
||||
#ifdef I7010
|
||||
if (uptr->u5 & URCSTA_WMKS) {
|
||||
if (lpr_data[u].lbuff[uptr->u3] & 0200)
|
||||
lpr_data[u].lbuff[uptr->u3] = 1;
|
||||
else
|
||||
lpr_data[u].lbuff[uptr->u3] = 012;
|
||||
}
|
||||
#endif
|
||||
uptr->u3++;
|
||||
break;
|
||||
}
|
||||
sim_activate(uptr, 10);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void
|
||||
lpr_ini(UNIT *uptr, t_bool f) {
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = attach_unit(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u5 = 0;
|
||||
uptr->u4 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_detach(UNIT * uptr)
|
||||
{
|
||||
if (uptr->u5 & URCSTA_FULL)
|
||||
print_line(uptr, UNIT_G_CHAN(uptr->flags), uptr - lpr_unit);
|
||||
return detach_unit(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
|
||||
fprintf (st, "%s\n\n", lpr_description(dptr));
|
||||
fprintf (st, "The line printer output can be echoed to the console to check");
|
||||
fprintf (st, "the \nprogress of jobs being run. This can be done with the\n");
|
||||
fprintf (st, " sim> SET %s ECHO set echo to console\n\n", dptr->name);
|
||||
fprintf (st, "The Line printer can be configured to any number of lines per page with the:\n");
|
||||
fprintf (st, " sim> SET %s LINESPERPAGE=n\n\n", dptr->name);
|
||||
fprintf (st, "The default is 59 lines per page.\n\n");
|
||||
#ifdef I7080
|
||||
fprintf (st, "The 716 printer can operate in one of three spacing modes\n");
|
||||
fprintf (st, " sim> SET %s SINGLE for single spacing\n", dptr->name);
|
||||
fprintf (st, " sim> SET %s DOUBLE for double spacing\n", dptr->name);
|
||||
fprintf (st, " sim> SET %s PROGRAM for program control of spacing\n\n", dptr->name);
|
||||
#endif
|
||||
#ifdef I7070
|
||||
fprintf (st, "Unit record devices can be configured to interrupt the CPU on\n");
|
||||
fprintf (st, "one of two priority channels A or B, to set this\n\n");
|
||||
fprintf (st, " sim> SET %s ATTENA to set device to raise Atten A\n", dptr->name);
|
||||
fprintf (st, " sim> SET %s ATTENB to set device to raise Atten B\n\n", dptr->name);
|
||||
#endif
|
||||
#ifdef I7010
|
||||
help_set_chan_type(st, dptr, "Line printer");
|
||||
#endif
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
lpr_description(DEVICE *dptr)
|
||||
{
|
||||
#ifdef I7010
|
||||
return "1403 Line Printer";
|
||||
#endif
|
||||
#ifdef I7070
|
||||
return "7400 Line Printer";
|
||||
#endif
|
||||
#ifdef I7080
|
||||
return "716 Line Printer";
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
1398
I7000/i7000_mt.c
Normal file
1398
I7000/i7000_mt.c
Normal file
File diff suppressed because it is too large
Load diff
727
I7000/i7010_chan.c
Normal file
727
I7000/i7010_chan.c
Normal file
|
@ -0,0 +1,727 @@
|
|||
/* i7010_chan.c: IBM 7010 Channel simulator
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
channel
|
||||
|
||||
The system state for the IBM 7010 channel is:
|
||||
There is only one type of channel on 7010, and it will talk to
|
||||
All type devices.
|
||||
|
||||
Common registers to all but PIO channels.
|
||||
ADDR<0:16> Address of next command.
|
||||
CMD<0:6> Channel command.
|
||||
ASM<0:32> Assembled data from devices.
|
||||
|
||||
Simulation registers to handle device handshake.
|
||||
STATUS<0:16> Simulated register for basic channel status.
|
||||
SENSE<0:16> Additional flags for 7907 channels.
|
||||
*/
|
||||
|
||||
#include "i7010_defs.h"
|
||||
|
||||
extern UNIT cpu_unit;
|
||||
extern uint8 chan_seek_done[NUM_CHAN]; /* Channel seek finished */
|
||||
|
||||
#define CHAN_DEF UNIT_DISABLE|CHAN_SET
|
||||
|
||||
t_stat set_urec(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat get_urec(FILE * st, UNIT * uptr, int32 v, CONST void *desc);
|
||||
t_stat chan_reset(DEVICE * dptr);
|
||||
t_stat chan_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *chan_description (DEVICE *dptr);
|
||||
|
||||
|
||||
/* Channel data structures
|
||||
|
||||
chan_dev Channel device descriptor
|
||||
chan_unit Channel unit descriptor
|
||||
chan_reg Channel register list
|
||||
chan_mod Channel modifiers list
|
||||
*/
|
||||
|
||||
uint32 caddr[NUM_CHAN]; /* Channel memory address */
|
||||
uint8 bcnt[NUM_CHAN]; /* Channel character count */
|
||||
uint8 cmd[NUM_CHAN]; /* Current command */
|
||||
uint16 irqdev[NUM_CHAN]; /* Device to generate interupts
|
||||
for channel */
|
||||
uint32 chunit[NUM_CHAN]; /* Channel unit */
|
||||
uint32 assembly[NUM_CHAN]; /* Assembly register */
|
||||
uint32 chan_flags[NUM_CHAN]; /* Unit status */
|
||||
extern uint8 chan_io_status[NUM_CHAN];
|
||||
extern uint8 inquiry;
|
||||
extern uint8 urec_irq[NUM_CHAN];
|
||||
|
||||
#define CHAN_LOAD 0001 /* Channel in load mode */
|
||||
#define CHAN_NOREC 0002 /* Don't stop at record */
|
||||
#define CHAN_WM 0004 /* Sent word mark char */
|
||||
#define CHAN_6BIT 0010 /* Send 6-8 bit command */
|
||||
#define CHAN_DSK_SEEK 0020 /* Seek Command */
|
||||
#define CHAN_DSK_DATA 0040 /* Command needs data */
|
||||
#define CHAN_DSK_RD 0100 /* Command is read command */
|
||||
#define CHAN_OVLP 0200 /* Channel ran overlaped */
|
||||
|
||||
const char *chan_type_name[] = {
|
||||
"Polled", "Unit Record", "7010", "7010", "7010"};
|
||||
|
||||
|
||||
/* Map commands to channel commands */
|
||||
/* Commands are reversed to be way they are sent out */
|
||||
uint8 disk_cmdmap[16] = { 0xff, 0x82, 0x84, 0x86, 0x00, 0x89, 0x88, 0x83,
|
||||
0x87, 0x04, 0x80, 0xff, 0x85, 0xff, 0xff, 0xff};
|
||||
|
||||
UNIT chan_unit[] = {
|
||||
{UDATA(NULL, CHAN_SET|UNIT_DIS, 0)}, /* Place holder channel */
|
||||
{UDATA(NULL, CHAN_SET|CHAN_S_TYPE(CHAN_7010)|UNIT_S_CHAN(1),0)},
|
||||
{UDATA(NULL, CHAN_SET|CHAN_S_TYPE(CHAN_7010)|UNIT_S_CHAN(2),0)},
|
||||
{UDATA(NULL, CHAN_SET|CHAN_S_TYPE(CHAN_7010)|UNIT_S_CHAN(3),0)},
|
||||
{UDATA(NULL, CHAN_SET|CHAN_S_TYPE(CHAN_7010)|UNIT_S_CHAN(4),0)},
|
||||
};
|
||||
|
||||
REG chan_reg[] = {
|
||||
{BRDATA(ADDR, caddr, 10, 18, NUM_CHAN), REG_RO|REG_FIT},
|
||||
{BRDATA(CMD, cmd, 8, 6, NUM_CHAN), REG_RO|REG_FIT},
|
||||
{BRDATA(FLAGS, chan_flags, 2, 32, NUM_CHAN), REG_RO|REG_FIT},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
MTAB chan_mod[] = {
|
||||
{CHAN_MODEL, CHAN_S_TYPE(CHAN_7010), "7010", NULL, NULL,NULL,NULL},
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "UREC", "UREC", &set_urec, &get_urec,
|
||||
NULL},
|
||||
{MTAB_VUN, 0, "UNITS", NULL, NULL, &print_chan, NULL},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* Simulator debug controls */
|
||||
DEBTAB chn_debug[] = {
|
||||
{"CHANNEL", DEBUG_CHAN},
|
||||
{"TRAP", DEBUG_TRAP},
|
||||
{"CMD", DEBUG_CMD},
|
||||
{"DATA", DEBUG_DATA},
|
||||
{"DETAIL", DEBUG_DETAIL},
|
||||
{"EXP", DEBUG_EXP},
|
||||
{"SENSE", DEBUG_SNS},
|
||||
{"CH1", 0x0100 << 1},
|
||||
{"CH2", 0x0100 << 2},
|
||||
{"CH3", 0x0100 << 3},
|
||||
{"CH4", 0x0100 << 4},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
DEVICE chan_dev = {
|
||||
"CH", chan_unit, chan_reg, chan_mod,
|
||||
NUM_CHAN, 10, 18, 1, 8, 8,
|
||||
NULL, NULL, &chan_reset, NULL, NULL, NULL,
|
||||
NULL, DEV_DEBUG, 0, chn_debug,
|
||||
NULL, NULL, &chan_help, NULL, NULL, &chan_description
|
||||
};
|
||||
|
||||
struct urec_t {
|
||||
uint16 addr;
|
||||
const char *name;
|
||||
} urec_devs[] = {
|
||||
{0100, "CR"},
|
||||
{0200, "LP"},
|
||||
{0400, "CP"},
|
||||
{0000, "NONE"},
|
||||
{0000, NULL}
|
||||
};
|
||||
|
||||
|
||||
/* Sets the device that will interrupt on the channel. */
|
||||
t_stat
|
||||
set_urec(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int chan;
|
||||
int i;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_IERR;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
|
||||
chan = UNIT_G_CHAN(uptr->flags);
|
||||
for(i = 0; urec_devs[i].name != NULL; i++)
|
||||
if (strcmp(cptr, urec_devs[i].name) == 0)
|
||||
break;
|
||||
if (urec_devs[i].name == NULL)
|
||||
return SCPE_ARG;
|
||||
|
||||
irqdev[chan] = urec_devs[i].addr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
get_urec(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
int chan;
|
||||
int i;
|
||||
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
chan = UNIT_G_CHAN(uptr->flags);
|
||||
if (irqdev[chan] == 0) {
|
||||
fprintf(st, "UREC=NONE");
|
||||
return SCPE_OK;
|
||||
}
|
||||
for(i = 0; urec_devs[i].name != NULL; i++) {
|
||||
if (urec_devs[i].addr == irqdev[chan]) {
|
||||
fprintf(st, "UREC=%s", urec_devs[i].name);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
fprintf(st, "UREC=%o", irqdev[chan]);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
chan_reset(DEVICE * dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear channel assignment */
|
||||
for (i = 0; i < NUM_CHAN; i++) {
|
||||
chan_flags[i] = 0;
|
||||
chunit[i] = 0;
|
||||
caddr[i] = 0;
|
||||
cmd[i] = 0;
|
||||
bcnt[i] = 0;
|
||||
}
|
||||
return chan_set_devs(dptr);
|
||||
}
|
||||
|
||||
/* Channel selector characters */
|
||||
uint8 chan_char[NUM_CHAN] = {0, CHR_RPARN, CHR_LPARN, CHR_QUEST, CHR_EXPL};
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat
|
||||
chan_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
/* Set IAR = 1 (done by reset), channel to read one
|
||||
record to location 1 */
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
extern int chwait;
|
||||
|
||||
chwait = chan; /* Force wait for channel */
|
||||
/* Set up channel to load into location 1 */
|
||||
caddr[chan] = 1;
|
||||
assembly[chan] = 0;
|
||||
cmd[chan] = CHAN_NOREC|CHAN_LOAD;
|
||||
chunit[chan] = unit_num;
|
||||
chan_flags[chan] |= STA_ACTIVE;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
chan_issue_cmd(uint16 chan, uint16 dcmd, uint16 dev) {
|
||||
DEVICE **dptr;
|
||||
DIB *dibp;
|
||||
uint32 j;
|
||||
UNIT *uptr;
|
||||
|
||||
for (dptr = sim_devices; *dptr != NULL; dptr++) {
|
||||
int r;
|
||||
|
||||
dibp = (DIB *) (*dptr)->ctxt;
|
||||
/* If no DIB, not channel device */
|
||||
if (dibp == 0)
|
||||
continue;
|
||||
uptr = (*dptr)->units;
|
||||
/* If this is a 7907 device, check it */
|
||||
if (dibp->ctype & CH_TYP_79XX) {
|
||||
for (j = 0; j < (*dptr)->numunits; j++, uptr++) {
|
||||
if (UNIT_G_CHAN(uptr->flags) == chan &&
|
||||
(UNIT_SELECT & uptr->flags) == 0 &&
|
||||
(dibp->addr & dibp->mask) == (dev & dibp->mask)) {
|
||||
r = dibp->cmd(uptr, dcmd, dev);
|
||||
if (r != SCPE_NODEV)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
} else if ((dibp->addr & dibp->mask) == (dev & dibp->mask)) {
|
||||
if (dibp->upc == 1) {
|
||||
for (j = 0; j < (*dptr)->numunits; j++) {
|
||||
if (UNIT_G_CHAN(uptr->flags) == chan) {
|
||||
r = dibp->cmd(uptr, dcmd, dev);
|
||||
if (r != SCPE_NODEV)
|
||||
return r;
|
||||
}
|
||||
uptr++;
|
||||
}
|
||||
} else {
|
||||
if (UNIT_G_CHAN(uptr->flags) == chan) {
|
||||
r = dibp->cmd(uptr, dcmd, dev);
|
||||
if (r != SCPE_NODEV)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_NODEV;
|
||||
}
|
||||
|
||||
/* Execute the next channel instruction. */
|
||||
void
|
||||
chan_proc()
|
||||
{
|
||||
int chan;
|
||||
int cmask;
|
||||
|
||||
/* Scan channels looking for work */
|
||||
for (chan = 0; chan < NUM_CHAN; chan++) {
|
||||
|
||||
/* Skip if channel is disabled */
|
||||
if (chan_unit[chan].flags & UNIT_DIS)
|
||||
continue;
|
||||
|
||||
cmask = 0x0100 << chan;
|
||||
/* If channel is disconnecting, do nothing */
|
||||
if (chan_flags[chan] & DEV_DISCO)
|
||||
continue;
|
||||
|
||||
if (chan_flags[chan] & CHS_EOF) {
|
||||
chan_io_status[chan] |= IO_CHS_COND;
|
||||
chan_flags[chan] &= ~CHS_EOF;
|
||||
}
|
||||
|
||||
if (chan_flags[chan] & CHS_ERR) {
|
||||
chan_io_status[chan] |= IO_CHS_CHECK;
|
||||
chan_flags[chan] &= ~CHS_ERR;
|
||||
}
|
||||
|
||||
if (cmd[chan] & CHAN_DSK_DATA) {
|
||||
if (chan_flags[chan] & DEV_REOR) {
|
||||
/* Find end of command */
|
||||
while(MEM_ADDR_OK(caddr[chan]) && M[caddr[chan]] != (WM|077)) {
|
||||
|
||||
if (chan_dev.dctrl & cmask)
|
||||
sim_debug(DEBUG_CHAN, &chan_dev, "%02o,", M[caddr[chan]]);
|
||||
caddr[chan]++;
|
||||
}
|
||||
caddr[chan]++;
|
||||
if (chan_dev.dctrl & cmask)
|
||||
sim_debug(DEBUG_CHAN, &chan_dev, "chan %d fin\n", chan);
|
||||
/* Configure channel for data transfer */
|
||||
cmd[chan] &= ~CHAN_DSK_DATA;
|
||||
chan_flags[chan] |= (chan_flags[chan]&
|
||||
(CTL_PREAD|CTL_PWRITE))>>2;
|
||||
chan_flags[chan] &= ~(DEV_REOR|CTL_PREAD|CTL_PWRITE|CTL_CNTL);
|
||||
/* If no select, all done */
|
||||
if ((chan_flags[chan] & DEV_SEL) == 0)
|
||||
chan_flags[chan] &= ~(CTL_READ|CTL_WRITE);
|
||||
/* Set direction if reading */
|
||||
if (chan_flags[chan] & CTL_READ)
|
||||
chan_flags[chan] |= DEV_WRITE;
|
||||
/* Check if we should finish now */
|
||||
if ((chan_flags[chan] & (CTL_READ|CTL_WRITE)) == 0
|
||||
|| chan_flags[chan] & (SNS_UEND|CTL_END)) {
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= DEV_WEOR|DEV_DISCO;
|
||||
if (cmd[chan] & CHAN_DSK_SEEK)
|
||||
chan_flags[chan] &= ~(CTL_END);
|
||||
else
|
||||
chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END);
|
||||
chan_io_status[chan] |= IO_CHS_DONE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd[chan] & CHAN_DSK_SEEK) {
|
||||
if (chan_seek_done[chan] || chan_flags[chan] & SNS_UEND) {
|
||||
if (chan_dev.dctrl & cmask)
|
||||
sim_debug(DEBUG_CHAN, &chan_dev, "chan %d seek done\n", chan);
|
||||
chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND);
|
||||
cmd[chan] &= ~CHAN_DSK_SEEK;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((chan_flags[chan] & (CTL_READ|CTL_WRITE)) &&
|
||||
(chan_flags[chan] & (CTL_END|SNS_UEND))) {
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= DEV_WEOR|DEV_DISCO;
|
||||
chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END|CTL_READ
|
||||
|CTL_WRITE);
|
||||
if (chan_dev.dctrl & cmask)
|
||||
sim_debug(DEBUG_CHAN, &chan_dev, "chan %d end\n", chan);
|
||||
cmd[chan] &= ~CHAN_DSK_SEEK;
|
||||
chan_io_status[chan] |= IO_CHS_DONE;
|
||||
}
|
||||
|
||||
/* If device put up EOR, terminate transfer. */
|
||||
if (chan_flags[chan] & DEV_REOR) {
|
||||
if (chan_flags[chan] & DEV_WRITE) {
|
||||
if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD))
|
||||
M[caddr[chan]++] = 035;
|
||||
caddr[chan]++;
|
||||
} else {
|
||||
if ((cmd[chan] & CHAN_NOREC) == 0 &&
|
||||
(chan_flags[chan] & STA_WAIT) == 0) {
|
||||
if (MEM_ADDR_OK(caddr[chan])) {
|
||||
if (M[caddr[chan]++] != (WM|077)) {
|
||||
if (MEM_ADDR_OK(caddr[chan])) {
|
||||
chan_io_status[chan] |= IO_CHS_WRL;
|
||||
if (!MEM_ADDR_OK(caddr[chan]+1)) {
|
||||
caddr[chan]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chan_io_status[chan] |= IO_CHS_WRL;
|
||||
}
|
||||
}
|
||||
if ((cmd[chan] & CHAN_NOREC) && MEM_ADDR_OK(caddr[chan])) {
|
||||
chan_io_status[chan] |= IO_CHS_WRL;
|
||||
if (!MEM_ADDR_OK(caddr[chan]+1)) {
|
||||
chan_io_status[chan] &= ~IO_CHS_WRL;
|
||||
}
|
||||
caddr[chan]++;
|
||||
}
|
||||
}
|
||||
chan_flags[chan] &= ~(STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR);
|
||||
chan_io_status[chan] |= IO_CHS_DONE;
|
||||
/* Disconnect if selected */
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= (DEV_DISCO);
|
||||
if (chan_dev.dctrl & cmask)
|
||||
sim_debug(DEBUG_EXP, &chan_dev, "chan %d EOR %d %o\n", chan,
|
||||
caddr[chan], chan_io_status[chan]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((chan_flags[chan] & (DEV_SEL|STA_ACTIVE)) == STA_ACTIVE) &&
|
||||
(chan_flags[chan] & (CTL_CNTL|CTL_PREAD|CTL_PWRITE|CTL_READ|
|
||||
CTL_WRITE|CTL_SNS)) == 0) {
|
||||
chan_flags[chan] &= ~STA_ACTIVE;
|
||||
}
|
||||
|
||||
/* If device requested attention, abort current command */
|
||||
if (chan_flags[chan] & CHS_ATTN) {
|
||||
chan_flags[chan] &= ~(CHS_ATTN|STA_ACTIVE|STA_WAIT);
|
||||
chan_io_status[chan] |= IO_CHS_DONE|IO_CHS_COND;
|
||||
/* Disconnect if selected */
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= (DEV_DISCO);
|
||||
if (chan_dev.dctrl & cmask)
|
||||
sim_debug(DEBUG_EXP, &chan_dev, "chan %d Attn %o\n",
|
||||
chan, chan_io_status[chan]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void chan_set_attn_urec(int chan, uint16 addr) {
|
||||
if (irqdev[chan] == addr)
|
||||
urec_irq[chan] = 1;
|
||||
}
|
||||
|
||||
void chan_set_attn_inq(int chan) {
|
||||
inquiry = 1;
|
||||
}
|
||||
|
||||
void chan_clear_attn_inq(int chan) {
|
||||
inquiry = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Issue a command to a channel */
|
||||
int
|
||||
chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
|
||||
{
|
||||
uint32 chan;
|
||||
t_stat r;
|
||||
|
||||
/* Find device on given channel and give it the command */
|
||||
chan = (dev >> 12) & 0x7;
|
||||
/* If no channel device, quick exit */
|
||||
if (chan_unit[chan].flags & UNIT_DIS)
|
||||
return SCPE_IOERR;
|
||||
/* Unit is busy doing something, wait */
|
||||
if (chan_flags[chan] & (DEV_SEL|DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE))
|
||||
return SCPE_BUSY;
|
||||
/* Ok, try and find the unit */
|
||||
caddr[chan] = addr;
|
||||
assembly[chan] = 0;
|
||||
cmd[chan] = 0;
|
||||
if (dcmd & 0100) /* Mod $ or X */
|
||||
cmd[chan] |= CHAN_NOREC;
|
||||
if (dcmd & 0200) /* Opcode L */
|
||||
cmd[chan] |= CHAN_LOAD;
|
||||
else
|
||||
cmd[chan] |= CHAN_WM; /* Force first char to have word mark set */
|
||||
dcmd = (dcmd >> 8) & 0x7f;
|
||||
chunit[chan] = dev;
|
||||
chan_flags[chan] &= ~(CTL_CNTL|CTL_READ|CTL_WRITE|SNS_UEND|CTL_WRITE
|
||||
|CTL_SNS|STA_PEND);
|
||||
/* Handle disk device special */
|
||||
if ((dsk_dib.mask & dev) == (dsk_dib.addr & dsk_dib.mask)) {
|
||||
uint16 dsk_cmd = 0;
|
||||
dsk_cmd = disk_cmdmap[dev&017];
|
||||
/* Set up channel if command ok */
|
||||
if (dsk_cmd == 0xFF || dev & 060) {
|
||||
/* Set io error and abort */
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
if (cmd[chan] & CHAN_LOAD) {
|
||||
cmd[chan] &= ~CHAN_LOAD;
|
||||
dsk_cmd = 0x100;
|
||||
} else {
|
||||
cmd[chan] |= CHAN_6BIT;
|
||||
}
|
||||
/* Try to start drive */
|
||||
r = chan_issue_cmd(chan, dsk_cmd, dev);
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
chan_flags[chan] |= CTL_CNTL;
|
||||
if (dcmd == IO_RDS)
|
||||
chan_flags[chan] |= CTL_PREAD;
|
||||
if (dcmd == IO_WRS)
|
||||
chan_flags[chan] |= CTL_PWRITE;
|
||||
if (dcmd == IO_TRS)
|
||||
chan_flags[chan] |= CTL_SNS;
|
||||
cmd[chan] |= CHAN_DSK_DATA;
|
||||
if ((dsk_cmd & 0xff) == 0x80 && cmd[chan] & CHAN_OVLP) {
|
||||
cmd[chan] |= CHAN_DSK_SEEK;
|
||||
chan_seek_done[chan] = 0;
|
||||
}
|
||||
chan_flags[chan] &= ~DEV_REOR; /* Clear in case still set */
|
||||
chan_flags[chan] |= STA_ACTIVE;
|
||||
return r;
|
||||
}
|
||||
if ((com_dib.mask & dev) == (com_dib.addr & com_dib.mask)) {
|
||||
switch(dcmd) {
|
||||
case IO_RDS: chan_flags[chan] |= CTL_READ; break;
|
||||
case IO_WRS: chan_flags[chan] |= CTL_WRITE; break;
|
||||
case IO_TRS: chan_flags[chan] |= CTL_SNS; break;
|
||||
case IO_CTL: chan_flags[chan] |= CTL_CNTL; break;
|
||||
}
|
||||
if ((dev & 077) != 1)
|
||||
cmd[chan] |= CHAN_6BIT;
|
||||
r = chan_issue_cmd(chan, dcmd, dev);
|
||||
if (r == SCPE_OK)
|
||||
chan_flags[chan] |= STA_ACTIVE;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = chan_issue_cmd(chan, dcmd, dev);
|
||||
/* Activate channel if select raised */
|
||||
if (chan_flags[chan] & DEV_SEL) {
|
||||
chan_flags[chan] |= STA_ACTIVE;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a word to the assembly register.
|
||||
*/
|
||||
int
|
||||
chan_write(int chan, t_uint64 * data, int flags)
|
||||
{
|
||||
/* Not implimented on this machine */
|
||||
return TIME_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next word from assembly register.
|
||||
*/
|
||||
int
|
||||
chan_read(int chan, t_uint64 * data, int flags)
|
||||
{
|
||||
/* Not implimented on this machine */
|
||||
return TIME_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a char to the assembly register.
|
||||
*/
|
||||
int
|
||||
chan_write_char(int chan, uint8 * data, int flags)
|
||||
{
|
||||
uint8 ch = *data;
|
||||
|
||||
sim_debug(DEBUG_DATA, &chan_dev, "chan %d char %o %d %o %o\n", chan,
|
||||
*data, caddr[chan], chan_io_status[chan], flags);
|
||||
|
||||
if (chan_flags[chan] & STA_WAIT) {
|
||||
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d setWR %d %o\n", chan,
|
||||
caddr[chan], chan_io_status[chan]);
|
||||
chan_io_status[chan] |= IO_CHS_WRL;
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
/* Check if end of data */
|
||||
if ((chan_flags[chan] & STA_WAIT) == 0 && (cmd[chan] & CHAN_NOREC) == 0 &&
|
||||
M[caddr[chan]] == (WM|077)) {
|
||||
chan_flags[chan] |= STA_WAIT; /* Saw group mark */
|
||||
chan_io_status[chan] |= IO_CHS_WRL;
|
||||
caddr[chan]++;
|
||||
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d GEor %d %o\n", chan,
|
||||
caddr[chan], chan_io_status[chan]);
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
/* If over size of memory, terminate */
|
||||
if (!MEM_ADDR_OK(caddr[chan])) {
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
chan_io_status[chan] |= IO_CHS_DONE;
|
||||
caddr[chan]++;
|
||||
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d past mem %d %o\n", chan,
|
||||
caddr[chan], chan_io_status[chan]);
|
||||
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
/* If we are in load mode and see word mark, save it */
|
||||
if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == CHAN_LOAD && ch == 035)
|
||||
cmd[chan] |= CHAN_WM;
|
||||
else {
|
||||
if (cmd[chan] & CHAN_6BIT)
|
||||
ch &= 077;
|
||||
if (cmd[chan] & CHAN_WM && ch != 035)
|
||||
ch |= WM;
|
||||
cmd[chan] &= ~CHAN_WM;
|
||||
if ((cmd[chan] & CHAN_LOAD) == 0)
|
||||
ch |= M[caddr[chan]] & WM;
|
||||
if ((chan_flags[chan] & DEV_REOR) == 0)
|
||||
M[caddr[chan]] = ch;
|
||||
caddr[chan]++;
|
||||
}
|
||||
|
||||
|
||||
/* If device gave us an end, terminate transfer */
|
||||
if (flags & DEV_REOR) {
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d Eor %d %o %x\n", chan,
|
||||
caddr[chan], chan_io_status[chan], chan_flags[chan]);
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next char from assembly register.
|
||||
*/
|
||||
int
|
||||
chan_read_char(int chan, uint8 * data, int flags)
|
||||
{
|
||||
|
||||
/* Return END_RECORD if requested */
|
||||
if (flags & DEV_WEOR) {
|
||||
chan_flags[chan] &= ~(DEV_WEOR);
|
||||
chan_io_status[chan] |= IO_CHS_DONE;
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
/* Check if he write out last data */
|
||||
if ((chan_flags[chan] & STA_ACTIVE) == 0)
|
||||
return TIME_ERROR;
|
||||
|
||||
/* Send rest of command */
|
||||
if (cmd[chan] & CHAN_DSK_DATA) {
|
||||
*data = M[caddr[chan]];
|
||||
if (*data == (WM|077))
|
||||
return END_RECORD;
|
||||
*data &= 077;
|
||||
caddr[chan]++;
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
/* If we had a previous word mark send it */
|
||||
if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_LOAD|CHAN_WM)) {
|
||||
*data = assembly[chan];
|
||||
cmd[chan] &= ~CHAN_WM;
|
||||
} else {
|
||||
if (!MEM_ADDR_OK(caddr[chan]+1)) {
|
||||
chan_flags[chan] &= ~STA_ACTIVE;
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
caddr[chan]++;
|
||||
return END_RECORD;
|
||||
}
|
||||
assembly[chan] = M[caddr[chan]++];
|
||||
/* Handle end of record */
|
||||
if ((cmd[chan] & CHAN_NOREC) == 0 && assembly[chan] == (WM|077)) {
|
||||
chan_flags[chan] &= ~STA_ACTIVE;
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
chan_io_status[chan] |= IO_CHS_DONE;
|
||||
return END_RECORD;
|
||||
}
|
||||
if (cmd[chan] & CHAN_LOAD &&
|
||||
(assembly[chan] & WM || assembly[chan] == 035)) {
|
||||
cmd[chan] |= CHAN_WM;
|
||||
assembly[chan] &= 077;
|
||||
*data = 035;
|
||||
return DATA_OK;
|
||||
}
|
||||
if (cmd[chan] & CHAN_6BIT)
|
||||
*data &= 077;
|
||||
*data = assembly[chan];
|
||||
}
|
||||
|
||||
/* If end of record, don't transfer any data */
|
||||
if (flags & DEV_REOR) {
|
||||
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
|
||||
if (chan_flags[chan] & DEV_SEL)
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
chan_io_status[chan] |= IO_CHS_DONE;
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
return END_RECORD;
|
||||
} else
|
||||
chan_flags[chan] |= DEV_WRITE;
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
chan9_set_error(int chan, uint32 mask)
|
||||
{
|
||||
if (chan_flags[chan] & mask)
|
||||
return;
|
||||
chan_flags[chan] |= mask;
|
||||
}
|
||||
|
||||
t_stat
|
||||
chan_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "%s\n\n", chan_description(dptr));
|
||||
fprintf (st, "The 7010 supports up to 4 channels. Channel models include\n\n");
|
||||
fprintf (st, " Channel * is for unit record devices.\n");
|
||||
fprintf (st, " Channels 1-4 are 7010 multiplexor channel\n\n");
|
||||
fprintf (st, "Channels are fixed on the 7010.\n\n");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
chan_description(DEVICE *dptr)
|
||||
{
|
||||
return "IBM 7010 channel controller";
|
||||
}
|
||||
|
3957
I7000/i7010_cpu.c
Normal file
3957
I7000/i7010_cpu.c
Normal file
File diff suppressed because it is too large
Load diff
133
I7000/i7010_defs.h
Normal file
133
I7000/i7010_defs.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* i7010_defs.h: IBM 7010 simulator definitions
|
||||
|
||||
Copyright (c) 2006-2016, 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 "sim_defs.h" /* simulator defns */
|
||||
|
||||
#include "i7000_defs.h"
|
||||
|
||||
/* Memory */
|
||||
#define AMASK 0x1ffff
|
||||
#define BBIT 0x80000000
|
||||
#define MEM_ADDR_OK(x) ((uint32)(x & AMASK) < MEMSIZE)
|
||||
extern uint8 M[MAXMEMSIZE];
|
||||
#define WM 0200 /* Word mark in memory */
|
||||
|
||||
/* Issue a command to a channel */
|
||||
int chan_cmd(uint16 dev, uint16 cmd, uint32 addr);
|
||||
|
||||
/* Opcodes */ /* I A B */
|
||||
#define OP_A CHR_A /* Aab */ /* NSI ALW BLB */
|
||||
#define OP_S CHR_S /* Sab */ /* NSI ALW BLB */
|
||||
#define OP_ZA CHR_QUEST /* ?ab */ /* NSI ALW BLB */
|
||||
#define OP_ZS CHR_EXPL /* !ab */ /* NSI ALW BLB */
|
||||
#define OP_M CHR_QUOT /* @ab */ /* NSI ALA BLB */
|
||||
#define OP_D CHR_RPARN /* %ab */ /* NSI ALA 10-quotient */
|
||||
#define OP_SAR CHR_G /* Gcd */ /* NSI * * C */
|
||||
/* A B E F T*/ /* 061, 062, 065, 066 */
|
||||
#define OP_SWM CHR_COM /* ,ab */ /* NSI A-1 B-1 */
|
||||
#define OP_CWM CHR_LPARN /* sqab*/ /* NSI A-1 B-1 */
|
||||
#define OP_CS CHR_SLSH /* /ib */ /* NSI/B B bbb00-1/NSIB */
|
||||
#define OP_H CHR_DOT /* .i */ /* NSI/B BI NSIB */
|
||||
#define OP_NOP CHR_N /* Nxxx^ */ /* NSI * * */
|
||||
#define OP_MOV CHR_D /* Dabd */ /* NSI */
|
||||
/* B A 8 4 2 1 */
|
||||
/* 1pos r-l scan */
|
||||
/* awm wm Z N */
|
||||
/* bwm */
|
||||
/* a|bwm */
|
||||
/* a|bwm l-r */
|
||||
/* arm */
|
||||
/* agm|awm */
|
||||
/* arm|agm|arm */
|
||||
#define OP_MSZ CHR_Z /* Zab */ /* NSI ALA B+1 */
|
||||
#define OP_C CHR_C /* Cab */ /* NSI ALW BLW */
|
||||
#define OP_T CHR_T /* Tabd */ /* NSI ALW last addr */
|
||||
/* 1 <, 2 ==, 3 <=, 4 >, 5 <>, 6 =>, 7 any, b end */
|
||||
#define OP_E CHR_E /* Eab */ /* NSI ALA ? */
|
||||
#define OP_B CHR_J /* Jid */ /* NSIB BI NSIB */
|
||||
/* blank jump */
|
||||
/* Z Arith overflow */
|
||||
/* 9 Carriage 9 CH1 */
|
||||
/* ! Carriage 9 CH2 */
|
||||
/* R Carriage Busy CH1 */
|
||||
/* L Carriage Busy CH2 */
|
||||
/* @ Cariage Overflow 12 CH 1 */
|
||||
/* sq Cariage Overflow 12 CH 2 */
|
||||
/* S Equal */
|
||||
/* U High */
|
||||
/* T Low */
|
||||
/* / High or Low */
|
||||
/* W Divide overflow */
|
||||
/* Q Inq req ch 1 */
|
||||
/* * Inq req ch 2 */
|
||||
/* 1 Overlap in Proc Ch 1 */
|
||||
/* 2 Overlap in Proc Ch 2 */
|
||||
/* 3 Overlap in Proc Ch 1 */
|
||||
/* 4 Overlap in Proc Ch 2 */
|
||||
/* K Tape indicator */
|
||||
/* V Zero Balence */
|
||||
/* Y Branch Exp over */
|
||||
/* X Branch Exp under */
|
||||
/* M Branch Bin Card 1 */
|
||||
/* ( Branch Bin Card 2 */
|
||||
#define OP_IO1 CHR_R /* Rid */ /* NSIB BI NSIB */
|
||||
#define OP_IO2 CHR_X /* Xid */ /* NSIB BI NSIB */
|
||||
#define OP_IO3 CHR_3 /* 3id */ /* NSIB BI NSIB */
|
||||
#define OP_IO4 CHR_1 /* 1id */ /* NSIB BI NSIB */
|
||||
/* B-Wrong len, A-No Trans, 8-Condition,
|
||||
4-Data Check, 2-Busy, 1- not Ready */
|
||||
#define OP_BCE CHR_B /* Bibd */ /* NSIB BI B-1/NSIB */
|
||||
#define OP_BBE CHR_W /* Wibd */ /* NSIB BI B-1/NSIB */
|
||||
#define OP_BWE CHR_V /* Vibd */ /* NSIB BI B-1/NSIB */
|
||||
|
||||
#define OP_RD CHR_M /* Mxbd */
|
||||
#define OP_RDW CHR_L /* Lxbd */
|
||||
#define OP_CC1 CHR_F /* Fd */
|
||||
#define OP_CC2 CHR_2 /* 2d */
|
||||
#define OP_SSF1 CHR_K /* Kd */
|
||||
#define OP_SSF2 CHR_4 /* 4d */
|
||||
#define OP_UC CHR_U /* Uxd */
|
||||
#define OP_PRI CHR_Y /* Yd */ /* E- enter, X leave */
|
||||
/* 21 - enable prot? */
|
||||
/* 11 - disable prot? */
|
||||
#define OP_STS CHR_DOL /* $ad */ /* S- store, R- restore */
|
||||
/* E - stchan1, G stchan2 */
|
||||
/* 1 - rschan1, 4 rschan4*/
|
||||
/* 47 - set low? */
|
||||
/* 72 - set high? */
|
||||
#define OP_FP CHR_EQ /* =ad */ /* R - Floating Reset Add */
|
||||
/* L - Floating store */
|
||||
/* A - Floating add */
|
||||
/* S - Floating sub */
|
||||
/* M - Floating mul */
|
||||
/* D - Floating div */
|
||||
|
||||
/* Flags for chan_io_status. */
|
||||
#define IO_CHS_NORDY 0001 /* Unit not Ready */
|
||||
#define IO_CHS_BUSY 0002 /* Unit or channel Busy */
|
||||
#define IO_CHS_CHECK 0004 /* Data check */
|
||||
#define IO_CHS_COND 0010 /* Condition */
|
||||
#define IO_CHS_NOTR 0020 /* No transfer */
|
||||
#define IO_CHS_WRL 0040 /* Wrong length */
|
||||
#define IO_CHS_DONE 0100 /* Device done */
|
||||
#define IO_CHS_OVER 0200 /* Channel busy on overlap processing */
|
1250
I7000/i7010_sys.c
Normal file
1250
I7000/i7010_sys.c
Normal file
File diff suppressed because it is too large
Load diff
416
I7000/i701_chan.c
Normal file
416
I7000/i701_chan.c
Normal file
|
@ -0,0 +1,416 @@
|
|||
/* i701_chan.c: IBM 701 Channel simulator
|
||||
|
||||
Copyright (c) 2005, 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.
|
||||
|
||||
channel
|
||||
|
||||
There is no channel on the 701, this module just provides basic support
|
||||
for polled mode devices.
|
||||
|
||||
Simulated register for the channel is:
|
||||
STATUS<0:16> Simulated register for basic channel status.
|
||||
*/
|
||||
|
||||
#include "i7090_defs.h"
|
||||
|
||||
extern uint8 iocheck;
|
||||
extern UNIT cpu_unit;
|
||||
extern uint16 IC;
|
||||
extern t_uint64 MQ;
|
||||
|
||||
t_stat chan_reset(DEVICE * dptr);
|
||||
void chan_fetch(int chan);
|
||||
t_stat chan_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *chan_description (DEVICE *dptr);
|
||||
uint32 dly_cmd(UNIT *, uint16, uint16);
|
||||
|
||||
/* Channel data structures
|
||||
|
||||
chan_dev Channel device descriptor
|
||||
chan_unit Channel unit descriptor
|
||||
chan_reg Channel register list
|
||||
chan_mod Channel modifiers list
|
||||
*/
|
||||
|
||||
t_uint64 assembly[NUM_CHAN]; /* Assembly register */
|
||||
uint32 chan_flags[NUM_CHAN]; /* Unit status */
|
||||
uint8 bcnt[NUM_CHAN]; /* Character count */
|
||||
|
||||
const char *chan_type_name[] = {
|
||||
"Polled", "", "", "", ""};
|
||||
|
||||
|
||||
/* Delay device for IOD instruction */
|
||||
DIB dly_dib =
|
||||
{ CH_TYP_PIO, 1, 2052, 07777, &dly_cmd, NULL };
|
||||
|
||||
|
||||
UNIT chan_unit[] = {
|
||||
/* Puesdo channel for 701 devices */
|
||||
{UDATA(NULL, UNIT_DISABLE | CHAN_SET |
|
||||
CHAN_S_TYPE(CHAN_PIO)|UNIT_S_CHAN(0), 0)},
|
||||
};
|
||||
|
||||
REG chan_reg[] = {
|
||||
{BRDATAD(ASM, assembly, 8, 36, NUM_CHAN, "Channel Assembly Register"),
|
||||
REG_RO|REG_FIT},
|
||||
{BRDATAD(FLAGS, chan_flags, 2, 32, NUM_CHAN, "Channel flags"),
|
||||
REG_RO|REG_FIT},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
MTAB chan_mod[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE chan_dev = {
|
||||
"CH", chan_unit, chan_reg, chan_mod,
|
||||
NUM_CHAN, 8, 15, 1, 8, 36,
|
||||
NULL, NULL, &chan_reset, NULL, NULL, NULL,
|
||||
&dly_dib, DEV_DEBUG, 0, NULL,
|
||||
NULL, NULL, &chan_help, NULL, NULL, &chan_description
|
||||
};
|
||||
|
||||
|
||||
/* Nothing special to do, just return true if cmd is write and we got here */
|
||||
uint32 dly_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
if (cmd == IO_WRS)
|
||||
return SCPE_OK;
|
||||
return SCPE_NODEV;
|
||||
}
|
||||
|
||||
|
||||
|
||||
t_stat
|
||||
chan_reset(DEVICE * dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear channel assignment */
|
||||
for (i = 0; i < NUM_CHAN; i++) {
|
||||
if (chan_unit[i].flags & CHAN_AUTO)
|
||||
chan_unit[i].flags &= ~CHAN_SET;
|
||||
else
|
||||
chan_unit[i].flags |= CHAN_SET;
|
||||
chan_flags[i] = 0;
|
||||
}
|
||||
return chan_set_devs(dptr);
|
||||
}
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat
|
||||
chan_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
/* Tell device to do a read, 3 records */
|
||||
/* Set channel address = 0, wc = 3, location = 0, CMD=0 */
|
||||
/* Set M[1] = TCO? 1, IC = 1 */
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
|
||||
IC = 0;
|
||||
chan_flags[chan] |= STA_ACTIVE;
|
||||
chan_flags[chan] &= ~STA_PEND;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Execute the next channel instruction. */
|
||||
void
|
||||
chan_proc()
|
||||
{
|
||||
if (chan_flags[0] & CHS_ATTN) {
|
||||
chan_flags[0] &= ~(CHS_ATTN | STA_START | STA_ACTIVE | STA_WAIT);
|
||||
if (chan_flags[0] & DEV_SEL)
|
||||
chan_flags[0] |= (DEV_DISCO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Issue a command to a channel */
|
||||
int
|
||||
chan_cmd(uint16 dev, uint16 dcmd)
|
||||
{
|
||||
UNIT *uptr;
|
||||
uint32 chan;
|
||||
DEVICE **dptr;
|
||||
DIB *dibp;
|
||||
int j;
|
||||
|
||||
/* Find device on given channel and give it the command */
|
||||
chan = (dev >> 9) & 017;
|
||||
if (chan >= NUM_CHAN)
|
||||
return SCPE_IOERR;
|
||||
/* If no channel device, quick exit */
|
||||
if (chan_unit[chan].flags & UNIT_DIS)
|
||||
return SCPE_IOERR;
|
||||
/* On 704 device new command aborts current operation */
|
||||
if (CHAN_G_TYPE(chan_unit[chan].flags) == CHAN_PIO &&
|
||||
(chan_flags[chan] & (DEV_SEL | DEV_FULL | DEV_DISCO)) == DEV_SEL) {
|
||||
chan_flags[chan] |= DEV_DISCO | DEV_WEOR;
|
||||
return SCPE_BUSY;
|
||||
}
|
||||
/* Unit is busy doing something, wait */
|
||||
if (chan_flags[chan] & (DEV_SEL | DEV_DISCO | STA_TWAIT | STA_WAIT))
|
||||
return SCPE_BUSY;
|
||||
/* Ok, try and find the unit */
|
||||
dev &= 07777;
|
||||
for (dptr = sim_devices; *dptr != NULL; dptr++) {
|
||||
int r;
|
||||
|
||||
dibp = (DIB *) (*dptr)->ctxt;
|
||||
/* If no DIB, not channel device */
|
||||
if (dibp == NULL || dibp->ctype == CHAN_7909 ||
|
||||
(dibp->addr & dibp->mask) != (dev & dibp->mask))
|
||||
continue;
|
||||
uptr = (*dptr)->units;
|
||||
if (dibp->upc == 1) {
|
||||
int num = (*dptr)->numunits;
|
||||
|
||||
for (j = 0; j < num; j++) {
|
||||
if (UNIT_G_CHAN(uptr->flags) == chan) {
|
||||
r = dibp->cmd(uptr, dcmd, dev);
|
||||
if (r != SCPE_NODEV) {
|
||||
bcnt[chan] = 6;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
uptr++;
|
||||
}
|
||||
} else {
|
||||
if (UNIT_G_CHAN(uptr->flags) == chan) {
|
||||
r = dibp->cmd(uptr, dcmd, dev);
|
||||
if (r != SCPE_NODEV) {
|
||||
bcnt[chan] = 6;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_NODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a word to the assembly register.
|
||||
*/
|
||||
int
|
||||
chan_write(int chan, t_uint64 * data, int flags)
|
||||
{
|
||||
|
||||
/* Check if last data still not taken */
|
||||
if (chan_flags[chan] & DEV_FULL) {
|
||||
/* Nope, see if we are waiting for end of record. */
|
||||
if (chan_flags[chan] & DEV_WEOR) {
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
chan_flags[chan] &= ~(DEV_WEOR|STA_WAIT);
|
||||
return END_RECORD;
|
||||
}
|
||||
if (chan_flags[chan] & STA_ACTIVE) {
|
||||
chan_flags[chan] |= CHS_ATTN; /* We had error */
|
||||
if ((flags & DEV_DISCO) == 0)
|
||||
iocheck = 1;
|
||||
}
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
return TIME_ERROR;
|
||||
} else {
|
||||
if (chan == 0)
|
||||
MQ = *data;
|
||||
assembly[chan] = *data;
|
||||
bcnt[chan] = 6;
|
||||
chan_flags[chan] |= DEV_FULL;
|
||||
chan_flags[chan] &= ~DEV_WRITE;
|
||||
if (flags & DEV_REOR) {
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
}
|
||||
}
|
||||
|
||||
/* If Writing end of record, abort */
|
||||
if (flags & DEV_WEOR) {
|
||||
chan_flags[chan] &= ~(DEV_FULL | DEV_WEOR);
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next word from assembly register.
|
||||
*/
|
||||
int
|
||||
chan_read(int chan, t_uint64 * data, int flags)
|
||||
{
|
||||
|
||||
/* Return END_RECORD if requested */
|
||||
if (flags & DEV_WEOR) {
|
||||
chan_flags[chan] &= ~(DEV_WEOR);
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
/* Check if he write out last data */
|
||||
if ((chan_flags[chan] & DEV_FULL) == 0) {
|
||||
if (chan_flags[chan] & DEV_WEOR) {
|
||||
chan_flags[chan] |= DEV_WRITE;
|
||||
chan_flags[chan] &= ~(DEV_WEOR | STA_WAIT);
|
||||
return END_RECORD;
|
||||
}
|
||||
if (chan_flags[chan] & STA_ACTIVE) {
|
||||
chan_flags[chan] |= CHS_ATTN;
|
||||
if ((flags & DEV_DISCO) == 0)
|
||||
iocheck = 1;
|
||||
}
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
return TIME_ERROR;
|
||||
} else {
|
||||
*data = assembly[chan];
|
||||
bcnt[chan] = 6;
|
||||
chan_flags[chan] &= ~DEV_FULL;
|
||||
/* If end of record, don't transfer any data */
|
||||
if (flags & DEV_REOR) {
|
||||
chan_flags[chan] &= ~(DEV_WRITE);
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
} else
|
||||
chan_flags[chan] |= DEV_WRITE;
|
||||
}
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a char to the assembly register.
|
||||
*/
|
||||
int
|
||||
chan_write_char(int chan, uint8 * data, int flags)
|
||||
{
|
||||
|
||||
/* Check if last data still not taken */
|
||||
if (chan_flags[chan] & DEV_FULL) {
|
||||
/* Nope, see if we are waiting for end of record. */
|
||||
if (chan_flags[chan] & DEV_WEOR) {
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
chan_flags[chan] &= ~(DEV_WEOR|STA_WAIT);
|
||||
return END_RECORD;
|
||||
}
|
||||
if (chan_flags[chan] & STA_ACTIVE) {
|
||||
chan_flags[chan] |= CHS_ATTN; /* We had error */
|
||||
if ((flags & DEV_DISCO) == 0)
|
||||
iocheck = 1;
|
||||
}
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
return TIME_ERROR;
|
||||
} else {
|
||||
int cnt = --bcnt[chan];
|
||||
t_uint64 wd = (chan == 0)? MQ:assembly[chan];
|
||||
wd &= 0007777777777LL;
|
||||
wd <<= 6;
|
||||
wd |= (*data) & 077;
|
||||
if (chan == 0)
|
||||
MQ = wd;
|
||||
else
|
||||
assembly[chan] = wd;
|
||||
|
||||
if (cnt == 0) {
|
||||
chan_flags[chan] |= DEV_FULL;
|
||||
chan_flags[chan] &= ~DEV_WRITE;
|
||||
}
|
||||
if (flags & DEV_REOR) {
|
||||
chan_flags[chan] |= DEV_FULL|DEV_REOR;
|
||||
chan_flags[chan] &= ~DEV_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If Writing end of record, abort */
|
||||
if (flags & DEV_WEOR) {
|
||||
chan_flags[chan] &= ~(DEV_FULL | DEV_WEOR);
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next char from assembly register.
|
||||
*/
|
||||
int
|
||||
chan_read_char(int chan, uint8 * data, int flags)
|
||||
{
|
||||
|
||||
/* Return END_RECORD if requested */
|
||||
if (flags & DEV_WEOR) {
|
||||
chan_flags[chan] &= ~(DEV_WEOR);
|
||||
return END_RECORD;
|
||||
}
|
||||
|
||||
/* Check if he write out last data */
|
||||
if ((chan_flags[chan] & DEV_FULL) == 0) {
|
||||
if (chan_flags[chan] & DEV_WEOR) {
|
||||
chan_flags[chan] |= DEV_WRITE;
|
||||
chan_flags[chan] &= ~(DEV_WEOR | STA_WAIT);
|
||||
return END_RECORD;
|
||||
}
|
||||
if (chan_flags[chan] & STA_ACTIVE) {
|
||||
chan_flags[chan] |= CHS_ATTN;
|
||||
if ((flags & DEV_DISCO) == 0)
|
||||
iocheck = 1;
|
||||
}
|
||||
chan_flags[chan] |= DEV_DISCO;
|
||||
return TIME_ERROR;
|
||||
} else {
|
||||
int cnt = --bcnt[chan];
|
||||
t_uint64 wd = assembly[chan];
|
||||
*data = 077 & (wd >> 30);
|
||||
wd <<= 6;
|
||||
wd |= 077 & (wd >> 36);
|
||||
wd &= 0777777777777LL;
|
||||
if (chan == 0)
|
||||
MQ = wd;
|
||||
assembly[chan] = wd;
|
||||
if (cnt == 0) {
|
||||
chan_flags[chan] &= ~DEV_FULL;
|
||||
bcnt[chan] = 6;
|
||||
}
|
||||
/* If end of record, don't transfer any data */
|
||||
if (flags & DEV_REOR) {
|
||||
chan_flags[chan] &= ~(DEV_WRITE|DEV_FULL);
|
||||
chan_flags[chan] |= DEV_REOR;
|
||||
} else
|
||||
chan_flags[chan] |= DEV_WRITE;
|
||||
}
|
||||
return DATA_OK;
|
||||
}
|
||||
|
||||
void
|
||||
chan9_set_error(int chan, uint32 mask)
|
||||
{
|
||||
}
|
||||
|
||||
t_stat
|
||||
chan_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) {
|
||||
fprintf(st, "IBM 701 Channel\n\n");
|
||||
fprintf(st, "Psuedo device to display IBM 701 I/O. The IBM 701 used polled");
|
||||
fprintf(st, " I/O,\nThe assembly register and the flags can be displayed\n");
|
||||
fprintf(st, "There are no options for the this device\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *chan_description (DEVICE *dptr) {
|
||||
return "IBM 701 Psuedo Channel";
|
||||
}
|
||||
|
961
I7000/i701_cpu.c
Normal file
961
I7000/i701_cpu.c
Normal file
|
@ -0,0 +1,961 @@
|
|||
/* i701_cpu.c: IBM 701 CPU simulator
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
cpu 701 central processor
|
||||
|
||||
The IBM 701 also know as "Defense Calculator" was introduced by IBM
|
||||
on April 7, 1953. This computer was start of IBM 700 and 7000 line.
|
||||
Memory was 2048 36 bit words. Each instruction could be signed plus
|
||||
or minus, plus would access memory as 18 bit words, minus as 36 bit
|
||||
words. There was a expansion option to add another 2048 words of
|
||||
memory, but I can't find documentation on how it worked. Memory cycle
|
||||
time was 12 microseconds. The 701 was withdrawn from the market
|
||||
October 1, 1954 replaced by 704 and 702. A total of 19 machines were
|
||||
installed.
|
||||
|
||||
The system state for the IBM 701 is:
|
||||
|
||||
AC<S,P,Q,1:35> AC register
|
||||
MQ<S,1:35> MQ register
|
||||
IC<0:15> program counter
|
||||
SSW<0:5> sense switches
|
||||
SLT<0:3> sense lights
|
||||
ACOVF AC overflow
|
||||
DVC divide check
|
||||
IOC I/O check
|
||||
|
||||
The 701 had one instruction format: memory reference,
|
||||
|
||||
00000 000011111111
|
||||
S 12345 678901234567
|
||||
+-+-----+------------+
|
||||
| |opcod| address | memory reference
|
||||
+-+-----+------------+
|
||||
|
||||
This routine is the instruction decode routine for the 701.
|
||||
It is called from the simulator control program to execute
|
||||
instructions in simulated memory, starting at the simulated PC.
|
||||
It runs until a stop condition occurs.
|
||||
|
||||
General notes:
|
||||
|
||||
1. Reasons to stop. The simulator can be stopped by:
|
||||
|
||||
HALT instruction
|
||||
illegal instruction
|
||||
illegal I/O operation for device
|
||||
illegal I/O operation for channel
|
||||
breakpoint encountered
|
||||
nested XEC's exceeding limit
|
||||
divide check
|
||||
I/O error in I/O simulator
|
||||
|
||||
3. Arithmetic. The 701 uses signed magnitude arithmetic for
|
||||
integer and floating point calculations, and 2's complement
|
||||
arithmetic for indexing calculations.
|
||||
|
||||
4. Adding I/O devices. These modules must be modified:
|
||||
|
||||
i7090_defs.h add device definitions
|
||||
i7090_chan.c add channel subsystem
|
||||
i701_sys.c add sim_devices table entry
|
||||
*/
|
||||
|
||||
#include "i7090_defs.h"
|
||||
|
||||
#define HIST_XCT 1 /* instruction */
|
||||
#define HIST_INT 2 /* interrupt cycle */
|
||||
#define HIST_TRP 3 /* trap cycle */
|
||||
#define HIST_MIN 64
|
||||
#define HIST_MAX 65536
|
||||
#define HIST_NOEA 0x40000000
|
||||
#define HIST_PC 0x10000
|
||||
|
||||
struct InstHistory
|
||||
{
|
||||
t_int64 ac;
|
||||
t_int64 mq;
|
||||
t_int64 op;
|
||||
t_int64 sr;
|
||||
uint32 ic;
|
||||
uint16 ea;
|
||||
};
|
||||
|
||||
t_stat cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr,
|
||||
int32 sw);
|
||||
t_stat cpu_dep(t_value val, t_addr addr, UNIT * uptr,
|
||||
int32 sw);
|
||||
t_stat cpu_reset(DEVICE * dptr);
|
||||
t_stat cpu_set_size(UNIT * uptr, int32 val, CONST char *cptr,
|
||||
void *desc);
|
||||
t_stat cpu_show_hist(FILE * st, UNIT * uptr, int32 val,
|
||||
CONST void *desc);
|
||||
t_stat cpu_set_hist(UNIT * uptr, int32 val, CONST char *cptr,
|
||||
void *desc);
|
||||
t_stat cpu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *cpu_description (DEVICE *dptr);
|
||||
|
||||
|
||||
t_uint64 M[MAXMEMSIZE] = { 0 }; /* memory */
|
||||
t_uint64 AC, MQ; /* registers */
|
||||
uint16 IC; /* program counter */
|
||||
uint8 SL; /* Sense lights */
|
||||
uint8 SW = 0; /* Sense switch */
|
||||
uint8 dcheck; /* Divide check */
|
||||
uint8 acoflag; /* AC Overflow */
|
||||
uint8 ihold = 0; /* Hold interrupts */
|
||||
uint16 iotraps; /* IO trap flags */
|
||||
t_uint64 ioflags; /* Trap enable flags */
|
||||
uint8 iocheck;
|
||||
uint8 iowait; /* Waiting on io */
|
||||
uint8 dualcore; /* Set to true if dual core in
|
||||
use */
|
||||
uint16 dev_pulse[NUM_CHAN]; /* SPRA device pulses */
|
||||
int cycle_time = 120; /* Cycle time of 12us */
|
||||
|
||||
/* History information */
|
||||
int32 hst_p = 0; /* History pointer */
|
||||
int32 hst_lnt = 0; /* History length */
|
||||
struct InstHistory *hst = NULL; /* History stack */
|
||||
extern uint32 drum_addr;
|
||||
uint32 hsdrm_addr;
|
||||
extern UNIT chan_unit[];
|
||||
|
||||
#undef AMASK /* Change definition of AMASK here */
|
||||
#define AMASK 00000000007777L
|
||||
|
||||
/* CPU data structures
|
||||
|
||||
cpu_dev CPU device descriptor
|
||||
cpu_unit CPU unit descriptor
|
||||
cpu_reg CPU register list
|
||||
cpu_mod CPU modifiers list
|
||||
*/
|
||||
|
||||
UNIT cpu_unit =
|
||||
{ UDATA(NULL, UNIT_BINK, MAXMEMSIZE / 2) };
|
||||
|
||||
REG cpu_reg[] = {
|
||||
{ORDATAD(IC, IC, 15, "Instruction counter"), REG_FIT},
|
||||
{ORDATAD(AC, AC, 38, "Accumulator"), REG_FIT},
|
||||
{ORDATAD(MQ, MQ, 36, "Multiplier quotent"), REG_FIT},
|
||||
{ORDATAD(SL, SL, 4, "Lights"), REG_FIT},
|
||||
{ORDATAD(SW, SW, 6, "Switch register"), REG_FIT},
|
||||
{FLDATAD(SW1, SW, 0, "Switch 0"), REG_FIT},
|
||||
{FLDATAD(SW2, SW, 1, "Switch 1"), REG_FIT},
|
||||
{FLDATAD(SW3, SW, 2, "Switch 2"), REG_FIT},
|
||||
{FLDATAD(SW4, SW, 3, "Switch 3"), REG_FIT},
|
||||
{FLDATAD(SW5, SW, 4, "Switch 4"), REG_FIT},
|
||||
{FLDATAD(SW6, SW, 5, "Switch 5"), REG_FIT},
|
||||
{ORDATAD(ACOVF, acoflag, 1, "Overflow flag"), REG_FIT},
|
||||
{ORDATAD(IOC, iocheck, 1, "I/O Check flag"), REG_FIT},
|
||||
{ORDATAD(DVC, dcheck, 1, "Divide Check"), REG_FIT},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
MTAB cpu_mod[] = {
|
||||
{MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_SHP, 0, "HISTORY", "HISTORY",
|
||||
&cpu_set_hist, &cpu_show_hist},
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE cpu_dev = {
|
||||
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
||||
1, 8, 15, 1, 8, 36,
|
||||
&cpu_ex, &cpu_dep, &cpu_reset, NULL, NULL, NULL,
|
||||
NULL, 0, 0, NULL,
|
||||
NULL, NULL, &cpu_help, NULL, NULL, &cpu_description
|
||||
};
|
||||
|
||||
/* Simulate instructions */
|
||||
t_stat
|
||||
sim_instr(void)
|
||||
{
|
||||
t_stat reason;
|
||||
t_uint64 temp = 0;
|
||||
t_uint64 ibr;
|
||||
t_uint64 SR;
|
||||
uint16 opcode;
|
||||
uint16 MA;
|
||||
uint8 f;
|
||||
int shiftcnt;
|
||||
int stopnext = 0;
|
||||
int instr_count = 0; /* Number of instructions to execute */
|
||||
|
||||
if (sim_step != 0) {
|
||||
instr_count = sim_step;
|
||||
sim_cancel_step();
|
||||
}
|
||||
|
||||
reason = 0;
|
||||
|
||||
iowait = 0;
|
||||
while (reason == 0) { /* loop until halted */
|
||||
|
||||
/* If doing fast I/O don't sit in idle loop */
|
||||
if (iowait == 0 && stopnext)
|
||||
return SCPE_STEP;
|
||||
|
||||
if (sim_interval <= 0) { /* event queue? */
|
||||
reason = sim_process_event();
|
||||
if (reason != SCPE_OK) {
|
||||
if (reason == SCPE_STEP && iowait)
|
||||
stopnext = 1;
|
||||
else
|
||||
break; /* process */
|
||||
}
|
||||
}
|
||||
|
||||
if (iowait == 0 && sim_brk_summ && sim_brk_test(IC, SWMASK('E'))) {
|
||||
reason = STOP_IBKPT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Split out current instruction */
|
||||
if (iowait) {
|
||||
/* If we are awaiting I/O complete, don't fetch. */
|
||||
sim_interval -= 6;
|
||||
iowait = 0;
|
||||
} else {
|
||||
MA = IC >> 1;
|
||||
sim_interval -= 24; /* count down */
|
||||
SR = ReadP(MA);
|
||||
temp = SR;
|
||||
if ((IC & 1) == 0)
|
||||
temp >>= 18;
|
||||
if (hst_lnt) { /* history enabled? */
|
||||
hst_p = (hst_p + 1); /* next entry */
|
||||
if (hst_p >= hst_lnt)
|
||||
hst_p = 0;
|
||||
hst[hst_p].ic = IC | HIST_PC;
|
||||
hst[hst_p].ea = 0;
|
||||
hst[hst_p].op = temp & RMASK;
|
||||
hst[hst_p].ac = AC;
|
||||
hst[hst_p].mq = MQ;
|
||||
hst[hst_p].sr = 0;
|
||||
}
|
||||
IC = (IC + 1) & AMASK;
|
||||
}
|
||||
ihold = 0;
|
||||
opcode = ((uint16)(temp >> 12L)) & 077;
|
||||
MA = (uint16)(temp & AMASK);
|
||||
ibr = SR = ReadP(MA>>1);
|
||||
if ((opcode & 040) == 0) {
|
||||
if (MA & 1)
|
||||
SR <<= 18;
|
||||
SR &= LMASK;
|
||||
}
|
||||
if (hst_lnt) { /* history enabled? */
|
||||
hst[hst_p].sr = SR;
|
||||
hst[hst_p].ea = MA;
|
||||
}
|
||||
|
||||
switch (opcode & 037) {
|
||||
case 19: /* RND */
|
||||
if (MQ & ONEBIT)
|
||||
AC++;
|
||||
break;
|
||||
case 30: /* SENSE */
|
||||
switch (MA) {
|
||||
case 64: /* SLN */
|
||||
SL = 0;
|
||||
break;
|
||||
case 65: /* */
|
||||
SL |= 1;
|
||||
break;
|
||||
case 66:
|
||||
SL |= 2;
|
||||
break;
|
||||
case 67:
|
||||
SL |= 4;
|
||||
break;
|
||||
case 68:
|
||||
SL |= 8;
|
||||
break;
|
||||
case 69:
|
||||
if ((SW & 1) == 0)
|
||||
IC++;
|
||||
break;
|
||||
case 70:
|
||||
if ((SW & 2) == 0)
|
||||
IC++;
|
||||
break;
|
||||
case 71:
|
||||
if ((SW & 4) == 0)
|
||||
IC++;
|
||||
break;
|
||||
case 72:
|
||||
if ((SW & 8) == 0)
|
||||
IC++;
|
||||
break;
|
||||
case 73:
|
||||
if ((SW & 16) == 0)
|
||||
IC++;
|
||||
break;
|
||||
case 74:
|
||||
if ((SW & 32) == 0)
|
||||
IC++;
|
||||
break;
|
||||
case 1024:
|
||||
case 1025:
|
||||
MA -= 1024;
|
||||
dev_pulse[0] |= 1 << MA;
|
||||
break;
|
||||
case 522:
|
||||
if (dev_pulse[0] & PRINT_I)
|
||||
IC++;
|
||||
dev_pulse[0] &= ~PRINT_I;
|
||||
break;
|
||||
case 512:
|
||||
case 513:
|
||||
case 514:
|
||||
case 515:
|
||||
case 516:
|
||||
case 517:
|
||||
case 518:
|
||||
case 519:
|
||||
case 520:
|
||||
case 521:
|
||||
MA = (MA - 512) + 5;
|
||||
dev_pulse[0] |= 1 << MA;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0: /* STOP */
|
||||
/* Stop at HTR instruction if trapped */
|
||||
IC--;
|
||||
halt:
|
||||
reason = STOP_HALT;
|
||||
/* Clear off any pending events before we halt */
|
||||
do {
|
||||
|
||||
f = chan_active(0);
|
||||
chan_proc();
|
||||
for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
|
||||
f |= chan_active(shiftcnt);
|
||||
}
|
||||
sim_interval = 0;
|
||||
sim_process_event();
|
||||
} while (f);
|
||||
if (reason != 0)
|
||||
IC = MA;
|
||||
break;
|
||||
case 8: /* NO OP */
|
||||
break;
|
||||
case 1: /* TR */
|
||||
IC = MA;
|
||||
break;
|
||||
case 4: /* TR 0 */
|
||||
f = (AC & AMMASK) == 0;
|
||||
branch:
|
||||
if (f) {
|
||||
IC = MA;
|
||||
}
|
||||
break;
|
||||
case 2: /* TR OV */
|
||||
f = acoflag;
|
||||
acoflag = 0;
|
||||
goto branch;
|
||||
case 3: /* TR + */
|
||||
f = ((AC & AMSIGN) == 0);
|
||||
goto branch;
|
||||
case 10: /* R ADD */
|
||||
AC = ((SR & MSIGN) << 2) | (SR & PMASK);
|
||||
sim_interval -= 6;
|
||||
break;
|
||||
case 6: /* R SUB */
|
||||
AC = (((SR & MSIGN) ^ MSIGN) << 2) | (SR & PMASK);
|
||||
sim_interval -= 6;
|
||||
break;
|
||||
case 15: /* LOAD MQ */
|
||||
MQ = SR;
|
||||
sim_interval -= 6;
|
||||
break;
|
||||
case 14: /* STORE MQ */
|
||||
SR = MQ;
|
||||
goto store;
|
||||
case 12: /* STORE */
|
||||
SR = AC & PMASK;
|
||||
if (AC & AMSIGN)
|
||||
SR |= MSIGN;
|
||||
store:
|
||||
if ((opcode & 040) == 0) {
|
||||
SR &= LMASK;
|
||||
if (MA & 1) {
|
||||
ibr &= LMASK;
|
||||
SR >>= 18;
|
||||
} else {
|
||||
ibr &= RMASK;
|
||||
}
|
||||
SR |= ibr;
|
||||
}
|
||||
WriteP(MA>>1, SR);
|
||||
if (hst_lnt) { /* history enabled? */
|
||||
hst[hst_p].sr = SR;
|
||||
}
|
||||
sim_interval -= 6;
|
||||
break;
|
||||
/* Logic operations */
|
||||
case 13: /* EXTR or STORE A */
|
||||
if ((opcode & 040) == 0) {
|
||||
SR &= ~(AMASK << 18);
|
||||
SR |= AC & (AMASK << 18);
|
||||
} else {
|
||||
t_uint64 t = AC & PMASK;
|
||||
if (AC & AMSIGN)
|
||||
t |= MSIGN;
|
||||
SR &= t;
|
||||
}
|
||||
goto store;
|
||||
case 7: /* SUB AB */
|
||||
SR |= MSIGN;
|
||||
goto iadd;
|
||||
case 11: /* ADD AB */
|
||||
SR &= PMASK;
|
||||
goto iadd;
|
||||
case 5: /* SUB */
|
||||
SR ^= MSIGN;
|
||||
/* Fall through */
|
||||
case 9: /* ADD */
|
||||
iadd:
|
||||
f = 0;
|
||||
/* Make AC Positive */
|
||||
if (AC & AMSIGN) {
|
||||
f = 2;
|
||||
AC &= AMMASK;
|
||||
}
|
||||
if (AC & APSIGN)
|
||||
f |= 8;
|
||||
/* Check signes of SR & AC */
|
||||
if (((SR & MSIGN) && ((f & 2) == 0)) ||
|
||||
(((SR & MSIGN) == 0) && ((f & 2) != 0))) {
|
||||
AC ^= AMMASK; /* One's compliment */
|
||||
f |= 1;
|
||||
}
|
||||
AC = AC + (SR & PMASK);
|
||||
/* Check carry from Q */
|
||||
if (f & 1) { /* Check if signs were not same */
|
||||
if (AC & AMSIGN) {
|
||||
f ^= 2;
|
||||
AC++;
|
||||
if (((AC & APSIGN) != 0) != ((f & 8) != 0))
|
||||
acoflag = 1;
|
||||
} else {
|
||||
AC ^= AMMASK; /* One's compliment */
|
||||
}
|
||||
} else {
|
||||
if (((AC & APSIGN) != 0) != ((f & 8) != 0))
|
||||
acoflag = 1;
|
||||
}
|
||||
/* Restore sign to AC */
|
||||
AC &= AMMASK;
|
||||
if (f & 2)
|
||||
AC |= AMSIGN;
|
||||
sim_interval -= 6;
|
||||
break;
|
||||
case 16: /* MPY */
|
||||
case 17: /* MPY R */
|
||||
shiftcnt = 043;
|
||||
sim_interval -= 34 * 6;
|
||||
f = 0;
|
||||
/* Save sign */
|
||||
if (MQ & MSIGN)
|
||||
f |= 1;
|
||||
if (SR & MSIGN)
|
||||
f |= 2;
|
||||
SR &= PMASK;
|
||||
MQ &= PMASK;
|
||||
AC = 0; /* Clear AC */
|
||||
if (SR == 0) {
|
||||
MQ = 0;
|
||||
} else {
|
||||
while (shiftcnt-- > 0) {
|
||||
if (MQ & 1)
|
||||
AC += SR;
|
||||
MQ >>= 1;
|
||||
if (AC & 1)
|
||||
MQ |= ONEBIT;
|
||||
AC >>= 1;
|
||||
}
|
||||
}
|
||||
if ((opcode & 037) == 17 && MQ & ONEBIT)
|
||||
AC++;
|
||||
if (f & 2)
|
||||
f ^= 1;
|
||||
if (f & 1) {
|
||||
MQ |= MSIGN;
|
||||
AC |= AMSIGN;
|
||||
}
|
||||
break;
|
||||
case 18: /* DIV */
|
||||
shiftcnt = 043;
|
||||
sim_interval -= 34 * 6;
|
||||
/* Save sign */
|
||||
if (SR & MSIGN) {
|
||||
SR &= PMASK;
|
||||
f = 1;
|
||||
} else
|
||||
f = 0;
|
||||
|
||||
if (AC & AMSIGN)
|
||||
f |= 2;
|
||||
|
||||
/* Check if SR less then AC */
|
||||
if (((SR - (AC & AMMASK)) & AMSIGN) ||
|
||||
(SR == (AC & AMMASK))) {
|
||||
dcheck = 1;
|
||||
MQ &= PMASK;
|
||||
if (f == 1 || f == 2)
|
||||
MQ |= MSIGN;
|
||||
goto halt;
|
||||
}
|
||||
/* Clear signs */
|
||||
MQ &= PMASK;
|
||||
AC &= AMMASK;
|
||||
/* Do divide operation */
|
||||
do {
|
||||
AC <<= 1;
|
||||
AC &= AMMASK;
|
||||
MQ <<= 1;
|
||||
if (MQ & MSIGN) {
|
||||
MQ ^= MSIGN;
|
||||
AC |= 1;
|
||||
}
|
||||
if (SR <= AC) {
|
||||
AC -= SR;
|
||||
MQ |= 1;
|
||||
}
|
||||
} while (--shiftcnt != 0);
|
||||
switch (f) {
|
||||
case 0:
|
||||
break;
|
||||
case 3:
|
||||
AC |= AMSIGN;
|
||||
break;
|
||||
case 2:
|
||||
AC |= AMSIGN;
|
||||
/* FALL THRU */
|
||||
case 1:
|
||||
MQ |= MSIGN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Shift */
|
||||
case 20: /* L LEFT */
|
||||
shiftcnt = MA & 0377;
|
||||
sim_interval -= (shiftcnt >> 6) * 6;
|
||||
/* Save sign */
|
||||
if (MQ & MSIGN)
|
||||
f = 1;
|
||||
else
|
||||
f = 0;
|
||||
/* Clear it for now */
|
||||
AC &= AQMASK;
|
||||
while (shiftcnt-- > 0) {
|
||||
MQ <<= 1;
|
||||
AC <<= 1;
|
||||
if (MQ & MSIGN)
|
||||
AC |= 1;
|
||||
if (AC & APSIGN)
|
||||
acoflag = 1;
|
||||
}
|
||||
/* Restore sign when done */
|
||||
AC &= AMMASK;
|
||||
MQ &= PMASK;
|
||||
if (f) {
|
||||
AC |= AMSIGN;
|
||||
MQ |= MSIGN;
|
||||
}
|
||||
break;
|
||||
case 21: /* L RIGHT */
|
||||
shiftcnt = MA & 0377;
|
||||
sim_interval -= (shiftcnt >> 6) * 6;
|
||||
/* Save sign */
|
||||
if (AC & AMSIGN)
|
||||
f = 1;
|
||||
else
|
||||
f = 0;
|
||||
/* Clear it for now */
|
||||
AC &= AMMASK;
|
||||
MQ &= PMASK;
|
||||
while (shiftcnt-- > 0) {
|
||||
if (AC & 1)
|
||||
MQ |= MSIGN;;
|
||||
MQ >>= 1;
|
||||
AC >>= 1;
|
||||
}
|
||||
/* Restore sign when done */
|
||||
AC &= AMMASK;
|
||||
if (f) {
|
||||
AC |= AMSIGN;
|
||||
MQ |= MSIGN;
|
||||
}
|
||||
break;
|
||||
case 22: /* A LEFT */
|
||||
shiftcnt = MA & 0377;
|
||||
sim_interval -= (shiftcnt >> 6) * 6;
|
||||
/* Save sign */
|
||||
if (AC & AMSIGN)
|
||||
f = 1;
|
||||
else
|
||||
f = 0;
|
||||
/* Clear it for now */
|
||||
AC &= AQMASK;
|
||||
while (shiftcnt-- > 0) {
|
||||
AC <<= 1;
|
||||
if (AC & APSIGN)
|
||||
acoflag = 1;
|
||||
}
|
||||
/* Restore sign and overflow when done */
|
||||
AC &= AMMASK;
|
||||
if (f)
|
||||
AC |= AMSIGN;
|
||||
break;
|
||||
case 23: /* A RIGHT */
|
||||
shiftcnt = MA & 0377;
|
||||
sim_interval -= (shiftcnt >> 6) * 6;
|
||||
/* Save sign */
|
||||
if (AC & AMSIGN)
|
||||
f = 1;
|
||||
else
|
||||
f = 0;
|
||||
/* Clear it for now */
|
||||
AC &= AMMASK;
|
||||
AC >>= shiftcnt;
|
||||
/* Restore sign when done */
|
||||
if (f)
|
||||
AC |= AMSIGN;
|
||||
break;
|
||||
|
||||
/* 704 Input output Instructions */
|
||||
case 29: /* SET DR */
|
||||
if (chan_test(0, DEV_SEL)) {
|
||||
drum_addr = (uint32)MA;
|
||||
chan_clear(0, DEV_FULL); /* Incase something got
|
||||
read while waiting */
|
||||
} else
|
||||
iocheck = 1;
|
||||
break;
|
||||
case 31: /* COPY */
|
||||
/* If no channel, set Iocheck and treat as nop */
|
||||
if (chan_unit[0].flags & UNIT_DIS) {
|
||||
iocheck = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If device disconnecting, just wait */
|
||||
if (chan_test(0, DEV_DISCO)) {
|
||||
iowait = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Instruct is NOP first time */
|
||||
/* Incomplete last word leaves result in MQ */
|
||||
if (chan_select(0)) {
|
||||
extern uint8 bcnt[NUM_CHAN];
|
||||
chan_set(0, STA_ACTIVE);
|
||||
switch (chan_flags[0] & (DEV_WRITE | DEV_FULL)) {
|
||||
case DEV_WRITE | DEV_FULL:
|
||||
case 0:
|
||||
/* On EOR skip 1, on EOF skip two */
|
||||
if (chan_test(0, CHS_EOF|CHS_EOT|DEV_REOR))
|
||||
chan_set(0, DEV_DISCO);
|
||||
iowait = 1;
|
||||
break;
|
||||
case DEV_WRITE:
|
||||
MQ = assembly[0] = SR;
|
||||
bcnt[0] = 6;
|
||||
chan_set(0, DEV_FULL);
|
||||
break;
|
||||
case DEV_FULL:
|
||||
SR = MQ;
|
||||
WriteP(MA, MQ);
|
||||
bcnt[0] = 6;
|
||||
chan_clear(0, DEV_FULL);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (chan_stat(0, CHS_EOF|CHS_EOT)) {
|
||||
IC++;
|
||||
/* On EOR skip two */
|
||||
} else if (chan_stat(0, DEV_REOR)) {
|
||||
IC += 2;
|
||||
/* Advance 1 on Error and set iocheck */
|
||||
} else if (chan_stat(0, CHS_ERR)) {
|
||||
iocheck = 1;
|
||||
IC++;
|
||||
}
|
||||
chan_clear(0, STA_ACTIVE|DEV_REOR|CHS_ERR);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Input/Output Instuctions */
|
||||
case 24: /* Read select */
|
||||
opcode = IO_RDS;
|
||||
MQ = 0;
|
||||
goto iostart;
|
||||
case 26: /* Write select */
|
||||
opcode = IO_WRS;
|
||||
goto iostart;
|
||||
case 27: /* Write EOF */
|
||||
opcode = IO_WEF;
|
||||
goto iostart;
|
||||
case 25: /* Read Backwards */
|
||||
opcode = IO_RDB;
|
||||
MQ = 0;
|
||||
goto iostart;
|
||||
case 28: /* Rewind */
|
||||
opcode = IO_REW;
|
||||
iostart:
|
||||
switch (chan_cmd(MA, opcode)) {
|
||||
case SCPE_BUSY:
|
||||
iowait = 1; /* Channel is active, hold */
|
||||
case SCPE_OK:
|
||||
ihold = 1; /* Hold interupts for one */
|
||||
break;
|
||||
case SCPE_IOERR:
|
||||
iocheck = 1;
|
||||
break;
|
||||
case SCPE_NODEV:
|
||||
reason = STOP_IOCHECK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
reason = STOP_UUO;
|
||||
break;
|
||||
}
|
||||
|
||||
chan_proc(); /* process any pending channel events */
|
||||
if (instr_count != 0 && --instr_count == 0)
|
||||
return SCPE_STEP;
|
||||
} /* end while */
|
||||
|
||||
/* Simulation halted */
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat
|
||||
cpu_reset(DEVICE * dptr)
|
||||
{
|
||||
AC = 0;
|
||||
MQ = 0;
|
||||
dualcore = 0;
|
||||
iotraps = 0;
|
||||
ioflags = 0;
|
||||
dcheck = acoflag = iocheck = 0;
|
||||
sim_brk_types = sim_brk_dflt = SWMASK('E');
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Memory examine */
|
||||
|
||||
t_stat
|
||||
cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr, int32 sw)
|
||||
{
|
||||
if (addr >= (MEMSIZE * 2))
|
||||
return SCPE_NXM;
|
||||
if (vptr == NULL)
|
||||
return SCPE_OK;
|
||||
|
||||
*vptr = M[(addr & 07777) >> 1];
|
||||
if ((addr & 0400000) == 0) {
|
||||
if ( addr & 1)
|
||||
*vptr <<= 18;
|
||||
else
|
||||
*vptr &= LMASK;
|
||||
}
|
||||
*vptr &= 0777777777777L;
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Memory deposit */
|
||||
|
||||
t_stat
|
||||
cpu_dep(t_value val, t_addr addr, UNIT * uptr, int32 sw)
|
||||
{
|
||||
t_addr a = (addr >> 1) & 03777;
|
||||
|
||||
if (addr >= (MEMSIZE * 2))
|
||||
return SCPE_NXM;
|
||||
if ((addr & 0400000) == 0) {
|
||||
if (addr & 1) {
|
||||
M[a] &= LMASK;
|
||||
M[a] |= (val >> 18) & RMASK;
|
||||
} else {
|
||||
M[a] &= RMASK;
|
||||
M[a] |= val & LMASK;
|
||||
}
|
||||
} else
|
||||
M[a] = val & 0777777777777L;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Handle execute history */
|
||||
|
||||
/* Set history */
|
||||
t_stat
|
||||
cpu_set_hist(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int32 i, lnt;
|
||||
t_stat r;
|
||||
|
||||
if (cptr == NULL) {
|
||||
for (i = 0; i < hst_lnt; i++)
|
||||
hst[i].ic = 0;
|
||||
hst_p = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
lnt = (int32) get_uint(cptr, 10, HIST_MAX, &r);
|
||||
if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN)))
|
||||
return SCPE_ARG;
|
||||
hst_p = 0;
|
||||
if (hst_lnt) {
|
||||
free(hst);
|
||||
hst_lnt = 0;
|
||||
hst = NULL;
|
||||
}
|
||||
if (lnt) {
|
||||
hst = (struct InstHistory *)calloc(sizeof(struct InstHistory), lnt);
|
||||
|
||||
if (hst == NULL)
|
||||
return SCPE_MEM;
|
||||
hst_lnt = lnt;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Show history */
|
||||
|
||||
t_stat
|
||||
cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
int32 k, di, lnt;
|
||||
char *cptr = (char *) desc;
|
||||
t_stat r;
|
||||
t_value sim_eval;
|
||||
struct InstHistory *h;
|
||||
|
||||
if (hst_lnt == 0)
|
||||
return SCPE_NOFNC; /* enabled? */
|
||||
if (cptr) {
|
||||
lnt = (int32) get_uint(cptr, 10, hst_lnt, &r);
|
||||
if ((r != SCPE_OK) || (lnt == 0))
|
||||
return SCPE_ARG;
|
||||
} else
|
||||
lnt = hst_lnt;
|
||||
di = hst_p - lnt; /* work forward */
|
||||
if (di < 0)
|
||||
di = di + hst_lnt;
|
||||
fprintf(st, "IC AC MQ EA SR\n\n");
|
||||
for (k = 0; k < lnt; k++) { /* print specified */
|
||||
h = &hst[(++di) % hst_lnt]; /* entry pointer */
|
||||
if (h->ic & HIST_PC) { /* instruction? */
|
||||
fprintf(st, "%06lo ", h->ic & AMASK);
|
||||
switch (h->ac & (AMSIGN | AQSIGN | APSIGN)) {
|
||||
case AMSIGN | AQSIGN | APSIGN:
|
||||
fprintf(st, "-QP");
|
||||
break;
|
||||
case AMSIGN | AQSIGN:
|
||||
fprintf(st, " -Q");
|
||||
break;
|
||||
case AMSIGN | APSIGN:
|
||||
fprintf(st, " -P");
|
||||
break;
|
||||
case AMSIGN:
|
||||
fprintf(st, " -");
|
||||
break;
|
||||
case AQSIGN | APSIGN:
|
||||
fprintf(st, " QP");
|
||||
break;
|
||||
case AQSIGN:
|
||||
fprintf(st, " Q");
|
||||
break;
|
||||
case APSIGN:
|
||||
fprintf(st, " P");
|
||||
break;
|
||||
case 0:
|
||||
fprintf(st, " ");
|
||||
break;
|
||||
}
|
||||
fprint_val(st, h->ac & PMASK, 8, 35, PV_RZRO);
|
||||
fputc(' ', st);
|
||||
if (h->mq & MSIGN)
|
||||
fputc('-', st);
|
||||
else
|
||||
fputc(' ', st);
|
||||
fprint_val(st, h->mq & PMASK, 8, 35, PV_RZRO);
|
||||
fputc(' ', st);
|
||||
fprint_val(st, h->ea, 8, 12, PV_RZRO);
|
||||
fputc(' ', st);
|
||||
if (h->sr & MSIGN)
|
||||
fputc('-', st);
|
||||
else
|
||||
fputc(' ', st);
|
||||
fprint_val(st, h->sr & PMASK, 8, 35, PV_RZRO);
|
||||
fputc(' ', st);
|
||||
sim_eval = h->op;
|
||||
if (
|
||||
(fprint_sym
|
||||
(st, h->ic & AMASK, &sim_eval, &cpu_unit,
|
||||
SWMASK('M'))) > 0) fprintf(st, "(undefined) %012llo",
|
||||
h->op);
|
||||
fputc('\n', st); /* end line */
|
||||
} /* end else instruction */
|
||||
} /* end for */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
cpu_description (DEVICE *dptr)
|
||||
{
|
||||
return "IBM 701 CPU";
|
||||
}
|
||||
|
||||
t_stat
|
||||
cpu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "The CPU behaves as a IBM 701\n");
|
||||
fprintf (st, "These switches are recognized when examining or depositing in CPU memory:\n\n");
|
||||
fprintf (st, " -c examine/deposit characters, 6 per word\n");
|
||||
fprintf (st, " -l examine/deposit half words\n");
|
||||
fprintf (st, " -m examine/deposit IBM 701 instructions\n\n");
|
||||
fprintf (st, "The CPU can maintain a history of the most recently executed instructions.\n");
|
||||
fprintf (st, "This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:\n\n");
|
||||
fprintf (st, " sim> SET CPU HISTORY clear history buffer\n");
|
||||
fprintf (st, " sim> SET CPU HISTORY=0 disable history\n");
|
||||
fprintf (st, " sim> SET CPU HISTORY=n{:file} enable history, length = n\n");
|
||||
fprintf (st, " sim> SHOW CPU HISTORY print CPU history\n");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
477
I7000/i701_sys.c
Normal file
477
I7000/i701_sys.c
Normal file
|
@ -0,0 +1,477 @@
|
|||
/* i701_sys.c: IBM 701 Simulator system interface.
|
||||
|
||||
Copyright (c) 2005-2016, 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 "i7090_defs.h"
|
||||
#include "sim_card.h"
|
||||
#include <ctype.h>
|
||||
|
||||
t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT * uptr, t_value * val, int32 sw);
|
||||
|
||||
/* SCP data structures and interface routines
|
||||
|
||||
sim_name simulator name string
|
||||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
||||
char sim_name[] = "IBM 701";
|
||||
|
||||
REG *sim_PC = &cpu_reg[0];
|
||||
|
||||
int32 sim_emax = 1;
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&chan_dev,
|
||||
#ifdef NUM_DEVS_CDR
|
||||
&cdr_dev,
|
||||
#endif
|
||||
#ifdef NUM_DEVS_CDP
|
||||
&cdp_dev,
|
||||
#endif
|
||||
#ifdef NUM_DEVS_LPR
|
||||
&lpr_dev,
|
||||
#endif
|
||||
#ifdef MT_CHANNEL_ZERO
|
||||
&mtz_dev,
|
||||
#endif
|
||||
#ifdef NUM_DEVS_DR
|
||||
&drm_dev,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef NUM_DEVS_CDR
|
||||
DIB cdp_dib = { CH_TYP_PIO, 1, 02000, 07777, &cdp_cmd, &cdp_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_CDP
|
||||
DIB cdr_dib = { CH_TYP_PIO, 1, 04000, 07777, &cdr_cmd, NULL };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_DR
|
||||
DIB drm_dib = { CH_TYP_PIO, 1, 0200, 07774, &drm_cmd, &drm_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_LPR
|
||||
DIB lpr_dib = { CH_TYP_PIO, 1, 01000, 07777, &lpr_cmd, &lpr_ini };
|
||||
#endif
|
||||
#ifdef MT_CHANNEL_ZERO
|
||||
DIB mt_dib = { CH_TYP_PIO, NUM_UNITS_MT, 0400, 07770, &mt_cmd, &mt_ini };
|
||||
#endif
|
||||
|
||||
|
||||
/* Simulator stop codes */
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"IO device not ready",
|
||||
"HALT instruction",
|
||||
"Breakpoint",
|
||||
"Unknown Opcode",
|
||||
"Nested indirects exceed limit",
|
||||
"Nested XEC's exceed limit",
|
||||
"I/O Check opcode",
|
||||
"Memory management trap during trap",
|
||||
"7750 invalid line number",
|
||||
"7750 invalid message",
|
||||
"7750 No free output buffers",
|
||||
"7750 No free input buffers", "Error?", "Error2", 0
|
||||
};
|
||||
|
||||
/* Simulator debug controls */
|
||||
DEBTAB dev_debug[] = {
|
||||
{"CHANNEL", DEBUG_CHAN, "Debug Channel use"},
|
||||
{"TRAP", DEBUG_TRAP, "Show CPU Traps"},
|
||||
{"CMD", DEBUG_CMD, "Show device commands"},
|
||||
{"DATA", DEBUG_DATA, "Show data transfers"},
|
||||
{"DETAIL", DEBUG_DETAIL, "Show detailed device information"},
|
||||
{"EXP", DEBUG_EXP, "Show device exceptions"},
|
||||
{"SENSE", DEBUG_SNS, "Show sense data on 7909 channel"},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
DEBTAB crd_debug[] = {
|
||||
{"CHAN", DEBUG_CHAN},
|
||||
{"CMD", DEBUG_CMD},
|
||||
{"DATA", DEBUG_DATA},
|
||||
{"DETAIL", DEBUG_DETAIL},
|
||||
{"EXP", DEBUG_EXP},
|
||||
{"CARD", DEBUG_CARD},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
/* Load a card image file into memory. */
|
||||
|
||||
t_stat
|
||||
sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag)
|
||||
{
|
||||
t_uint64 wd;
|
||||
t_uint64 mask;
|
||||
int addr = 0;
|
||||
int dlen = 0;
|
||||
char *p;
|
||||
char buf[160];
|
||||
|
||||
if (match_ext(fnam, "crd")) {
|
||||
int firstcard = 1;
|
||||
uint16 cbuf[80];
|
||||
t_uint64 lbuff[24];
|
||||
int i;
|
||||
|
||||
while (sim_fread(cbuf, 2, 80, fileref) == 80) {
|
||||
|
||||
/* Bit flip into read buffer */
|
||||
for (i = 0; i < 24; i++) {
|
||||
int bit = 1 << (i / 2);
|
||||
int b = 36 * (i & 1);
|
||||
int col;
|
||||
|
||||
mask = 1;
|
||||
wd = 0;
|
||||
for (col = 35; col >= 0; mask <<= 1) {
|
||||
if (cbuf[col-- + b] & bit)
|
||||
wd |= mask;
|
||||
}
|
||||
lbuff[i] = wd;
|
||||
}
|
||||
i = 2;
|
||||
if (firstcard) {
|
||||
addr = 0;
|
||||
dlen = 3 + (int)((lbuff[0] >> 18) & 077777);
|
||||
firstcard = 0;
|
||||
i = 0;
|
||||
} else if (dlen == 0) {
|
||||
addr = (int)(lbuff[0] & 077777);
|
||||
dlen = (int)(lbuff[0] >> 18) & 077777;
|
||||
}
|
||||
for (; i < 24 && dlen > 0; i++) {
|
||||
M[addr++] = lbuff[i];
|
||||
dlen--;
|
||||
}
|
||||
}
|
||||
} else if (match_ext(fnam, "oct")) {
|
||||
while (fgets(&buf[0], 160, fileref) != 0) {
|
||||
for(p = &buf[0]; *p == ' ' || *p == '\t'; p++);
|
||||
/* Grab address */
|
||||
for(addr = 0; *p >= '0' && *p <= '7'; p++)
|
||||
addr = (addr << 3) + *p - '0';
|
||||
while(*p != '\n' && *p != '\0') {
|
||||
for(; *p == ' ' || *p == '\t'; p++);
|
||||
for(wd = 0; *p >= '0' && *p <= '7'; p++)
|
||||
wd = (wd << 3) + *p - '0';
|
||||
if (addr < MAXMEMSIZE)
|
||||
M[addr++] = wd;
|
||||
}
|
||||
}
|
||||
} else if (match_ext(fnam, "txt")) {
|
||||
while (fgets(&buf[0], 160, fileref) != 0) {
|
||||
for(p = &buf[0]; *p == ' ' || *p == '\t'; p++);
|
||||
/* Grab address */
|
||||
for(addr = 0; *p >= '0' && *p <= '7'; p++)
|
||||
addr = (addr << 3) + *p - '0';
|
||||
while(*p == ' ' || *p == '\t') p++;
|
||||
if(sim_strncasecmp(p, "BCD", 3) == 0) {
|
||||
p += 3;
|
||||
parse_sym(++p, addr, &cpu_unit, &M[addr], SWMASK('C'));
|
||||
} else if (sim_strncasecmp(p, "OCT", 3) == 0) {
|
||||
p += 3;
|
||||
for(; *p == ' ' || *p == '\t'; p++);
|
||||
parse_sym(p, addr, &cpu_unit, &M[addr], 0);
|
||||
} else {
|
||||
parse_sym(p, addr, &cpu_unit, &M[addr], SWMASK('M'));
|
||||
}
|
||||
}
|
||||
} else
|
||||
return SCPE_ARG;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Symbol tables */
|
||||
typedef struct _opcode
|
||||
{
|
||||
uint16 opbase;
|
||||
CONST char *name;
|
||||
}
|
||||
t_opcode;
|
||||
|
||||
/* Opcodes */
|
||||
t_opcode base_ops[] = {
|
||||
{0, "STOP"},
|
||||
{1, "TR"},
|
||||
{2, "TRO"},
|
||||
{3, "TRP"},
|
||||
{4, "TRZ"},
|
||||
{5, "SUB"},
|
||||
{6, "R SUB"},
|
||||
{7, "SUB AB"},
|
||||
{8, "NO OP"},
|
||||
{9, "ADD"},
|
||||
{10, "R ADD"},
|
||||
{11, "ADD AB"},
|
||||
{12, "STORE"},
|
||||
{13, "STORE A"},
|
||||
{14, "STORE MQ"},
|
||||
{15, "LOAD MQ"},
|
||||
{16, "MPY"},
|
||||
{17, "MPY R"},
|
||||
{18, "DIV"},
|
||||
{19, "ROUND"},
|
||||
{20, "L LEFT"},
|
||||
{21, "L RIGHT"},
|
||||
{22, "A LEFT"},
|
||||
{23, "A RIGHT"},
|
||||
{24, "READ"},
|
||||
{25, "READ B"},
|
||||
{26, "WRITE"},
|
||||
{27, "WRITE EF"},
|
||||
{28, "REWIND"},
|
||||
{29, "SET DR"},
|
||||
{30, "SENSE"},
|
||||
{31, "COPY"},
|
||||
{13 + 040, "EXTR"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
const char *chname[] = { "*" };
|
||||
|
||||
|
||||
|
||||
/* Parse address
|
||||
|
||||
Inputs:
|
||||
*dptr = pointer to device.
|
||||
*cptr = pointer to string.
|
||||
**tptr = pointer to final scaned character.
|
||||
Outputs:
|
||||
address with sign.
|
||||
*/
|
||||
|
||||
t_addr
|
||||
parse_addr(DEVICE *dptr, const char *cptr, const char **tptr) {
|
||||
t_addr v;
|
||||
int s = 0;
|
||||
*tptr = cptr;
|
||||
if (dptr != &cpu_dev)
|
||||
return 0;
|
||||
v = 0;
|
||||
if (*cptr == '-') {
|
||||
cptr++;
|
||||
s = 1;
|
||||
}
|
||||
while(*cptr >= '0' && *cptr <= '7') {
|
||||
v <<= 3;
|
||||
v += *cptr++ - '0';
|
||||
}
|
||||
if (v > 4096)
|
||||
return 0;
|
||||
if (s) {
|
||||
if ((cptr - 1) != *tptr)
|
||||
*tptr = cptr;
|
||||
v |= 0400000;
|
||||
} else {
|
||||
if (cptr != *tptr)
|
||||
*tptr = cptr;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sys_init(void) {
|
||||
sim_vm_parse_addr = &parse_addr;
|
||||
}
|
||||
|
||||
void (*sim_vm_init) (void) = &sys_init;
|
||||
|
||||
/* Symbolic decode
|
||||
|
||||
Inputs:
|
||||
*of = output stream
|
||||
addr = current PC
|
||||
*val = pointer to values
|
||||
*uptr = pointer to unit
|
||||
sw = switches
|
||||
Outputs:
|
||||
return = status code
|
||||
*/
|
||||
|
||||
t_stat
|
||||
fprint_sym(FILE * of, t_addr addr, t_value * val, UNIT * uptr, int32 sw)
|
||||
{
|
||||
t_uint64 inst = *val;
|
||||
|
||||
/* Print value in octal first */
|
||||
fputc(' ', of);
|
||||
fprint_val(of, inst, 8, 36, PV_RZRO);
|
||||
|
||||
if (sw & SWMASK('M')) {
|
||||
int op = (int)(inst >> (12+18));
|
||||
int i;
|
||||
fputs(" rt ", of);
|
||||
if (op != (040 + 13))
|
||||
op &= 037;
|
||||
for(i = 0; base_ops[i].name != NULL; i++) {
|
||||
if (base_ops[i].opbase == op) {
|
||||
fputs(base_ops[i].name, of);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc(' ', of);
|
||||
if ((inst >> 18) & 0400000L)
|
||||
fputc('-', of);
|
||||
fprint_val(of, (inst >> 18) & 0000000007777L, 8, 12, PV_RZRO);
|
||||
op = (int)(inst >> 12);
|
||||
fputs(" lt ", of);
|
||||
if (op != (040 + 13))
|
||||
op &= 037;
|
||||
for(i = 0; base_ops[i].name != NULL; i++) {
|
||||
if (base_ops[i].opbase == op) {
|
||||
fputs(base_ops[i].name, of);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputc(' ', of);
|
||||
if (inst & 0400000L)
|
||||
fputc('-', of);
|
||||
else
|
||||
fputc(' ', of);
|
||||
fprint_val(of, inst & 0000000007777L, 8, 12, PV_RZRO);
|
||||
}
|
||||
|
||||
if (sw & SWMASK('C')) {
|
||||
int i;
|
||||
|
||||
fputs(" '", of);
|
||||
for (i = 5; i >= 0; i--) {
|
||||
int ch;
|
||||
|
||||
ch = (int)(inst >> (6 * i)) & 077;
|
||||
fputc(sim_six_to_ascii[ch], of);
|
||||
}
|
||||
fputc('\'', of);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_opcode *
|
||||
find_opcode(char *op, t_opcode * tab)
|
||||
{
|
||||
while (tab->name != NULL) {
|
||||
if (*tab->name != '\0' && strcmp(op, tab->name) == 0)
|
||||
return tab;
|
||||
tab++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Symbolic input
|
||||
|
||||
Inputs:
|
||||
*cptr = pointer to input string
|
||||
addr = current PC
|
||||
uptr = pointer to unit
|
||||
*val = pointer to output values
|
||||
sw = switches
|
||||
Outputs:
|
||||
status = error status
|
||||
*/
|
||||
|
||||
t_stat
|
||||
parse_sym(CONST char *cptr, t_addr addr, UNIT * uptr, t_value * val, int32 sw)
|
||||
{
|
||||
int i;
|
||||
int f;
|
||||
t_value d;
|
||||
t_addr tag;
|
||||
int sign;
|
||||
char opcode[100];
|
||||
const char *arg;
|
||||
|
||||
while (isspace(*cptr))
|
||||
cptr++;
|
||||
d = 0;
|
||||
if (sw & SWMASK('M')) {
|
||||
t_opcode *op;
|
||||
|
||||
do {
|
||||
i = 0;
|
||||
sign = 0;
|
||||
f = 0;
|
||||
if (*cptr == ',') {
|
||||
d <<= 18;
|
||||
cptr++;
|
||||
}
|
||||
/* Skip blanks */
|
||||
while (isspace(*cptr))
|
||||
cptr++;
|
||||
/* Grab opcode */
|
||||
cptr = get_glyph(cptr, opcode, ',');
|
||||
|
||||
if ((op = find_opcode(opcode, base_ops)) != 0) {
|
||||
d |= (t_uint64) op->opbase << 12;
|
||||
} else {
|
||||
return STOP_UUO;
|
||||
}
|
||||
|
||||
cptr = get_glyph(cptr, opcode, ',');
|
||||
tag = parse_addr(&cpu_dev, opcode, &arg);
|
||||
if (*arg != opcode[0])
|
||||
d += (t_value)tag;
|
||||
} while (*cptr == ',');
|
||||
if (*cptr != '\0')
|
||||
return STOP_UUO;
|
||||
*val = d;
|
||||
return SCPE_OK;
|
||||
} else if (sw & SWMASK('C')) {
|
||||
i = 0;
|
||||
while (*cptr != '\0' && i < 6) {
|
||||
d <<= 6;
|
||||
if (sim_ascii_to_six[0177 & *cptr] != -1)
|
||||
d |= sim_ascii_to_six[0177 & *cptr];
|
||||
cptr++;
|
||||
i++;
|
||||
}
|
||||
while (i < 6) {
|
||||
d <<= 6;
|
||||
d |= 060;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
if (*cptr == '-') {
|
||||
sign = 1;
|
||||
cptr++;
|
||||
} else {
|
||||
sign = 0;
|
||||
if (*cptr == '+')
|
||||
cptr++;
|
||||
}
|
||||
while (*cptr >= '0' && *cptr <= '7') {
|
||||
d <<= 3;
|
||||
d |= *cptr++ - '0';
|
||||
}
|
||||
if (sign)
|
||||
d |= 00400000000000L;
|
||||
}
|
||||
*val = d;
|
||||
return SCPE_OK;
|
||||
}
|
1597
I7000/i7070_chan.c
Normal file
1597
I7000/i7070_chan.c
Normal file
File diff suppressed because it is too large
Load diff
3001
I7000/i7070_cpu.c
Normal file
3001
I7000/i7070_cpu.c
Normal file
File diff suppressed because it is too large
Load diff
241
I7000/i7070_defs.h
Normal file
241
I7000/i7070_defs.h
Normal file
|
@ -0,0 +1,241 @@
|
|||
/* i7070_defs.h: IBM 7070 simulator definitions
|
||||
|
||||
Copyright (c) 2006-2016, 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 "sim_defs.h" /* simulator defns */
|
||||
|
||||
#include "i7000_defs.h"
|
||||
/* Simulator stop codes */
|
||||
|
||||
#define STOP_IONRDY 1 /* I/O dev not ready */
|
||||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
#define STOP_UUO 4 /* invalid opcode */
|
||||
#define STOP_INDLIM 5 /* indirect limit */
|
||||
#define STOP_XECLIM 6 /* XEC limit */
|
||||
#define STOP_IOCHECK 7 /* IOCHECK */
|
||||
#define STOP_MMTRP 8 /* mm in trap */
|
||||
#define STOP_INVLIN 9 /* 7750 invalid line number */
|
||||
#define STOP_INVMSG 10 /* 7750 invalid message */
|
||||
#define STOP_NOOFREE 11 /* 7750 No free output buffers */
|
||||
#define STOP_NOIFREE 12 /* 7750 No free input buffers */
|
||||
|
||||
/* Trap codes */
|
||||
|
||||
|
||||
/* Conditional error returns */
|
||||
|
||||
/* Memory */
|
||||
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
extern t_uint64 M[MAXMEMSIZE];
|
||||
|
||||
/* Arithmetic */
|
||||
|
||||
/* Instruction format */
|
||||
|
||||
/* Globally visible flags */
|
||||
#define DMASK 0x0FFFFFFFFFFLL
|
||||
#define IMASK 0x000FFFF0000LL
|
||||
#define IMASK2 0x00FFFFF0000LL
|
||||
#define XMASK 0x00F00000000LL
|
||||
#define XMASK2 0x0F000000000LL
|
||||
#define AMASK 0x0000000FFFFLL
|
||||
#define OMASK 0x0FF00000000LL
|
||||
#define SMASK 0xF0000000000LL
|
||||
#define PSIGN 0x90000000000LL
|
||||
#define MSIGN 0x60000000000LL
|
||||
#define ASIGN 0x30000000000LL
|
||||
#define NINES 0x09999999999LL /* All nines */
|
||||
#define FNINES 0x00099999999LL /* Floating point all nines */
|
||||
#define EMASK 0x0FF00000000LL /* Floating point exponent */
|
||||
#define FMASK 0x000FFFFFFFFLL /* Floating point mantisa mask */
|
||||
#define NMASK 0x000F0000000LL /* Floating point normalize mask */
|
||||
|
||||
/* 7604 channel commands */
|
||||
#define CHN_ALPHA_MODE 000 /* Recieve alpha words */
|
||||
#define CHN_NUM_MODE 001 /* Recieve numeric words */
|
||||
#define CHN_WRITE 002 /* Channel direction */
|
||||
#define CHN_LAST 004 /* Last transfer */
|
||||
#define CHN_MODE 0170 /* Mode of channel */
|
||||
#define CHN_NORMAL 000 /* Normal mode */
|
||||
#define CHN_COMPRESS 010 /* Compress leading zeros */
|
||||
#define CHN_RECORD 020 /* Dectect record marks */
|
||||
#define CHN_SEGMENT 040 /* Search for next segment */
|
||||
#define CHN_ALPHA 0100 /* Alpha read only */
|
||||
#define CHN_RM_FND 0200 /* Record mark read */
|
||||
|
||||
/* 7070 channel specific functions */
|
||||
|
||||
/* Issue a command to a channel */
|
||||
int chan_cmd(uint16 dev, uint16 cmd, uint16 addr);
|
||||
|
||||
/* Decimal helper functions */
|
||||
int dec_add(t_uint64 *a, t_uint64 b);
|
||||
void dec_add_noov(t_uint64 *a, t_uint64 b);
|
||||
void dec_comp(t_uint64 *a);
|
||||
int dec_cmp(t_uint64 a, t_uint64 b);
|
||||
void mul_step(t_uint64 *a, t_uint64 b, int c);
|
||||
void div_step(t_uint64 b);
|
||||
void bin_dec(t_uint64 *a, uint32 b, int s, int l);
|
||||
uint32 dec_bin_idx(t_uint64 a);
|
||||
uint32 dec_bin_lim(t_uint64 a, uint32 b);
|
||||
int get_rdw(t_uint64 a, uint32 *base, uint32 *limit);
|
||||
void upd_idx(t_uint64 *a, uint32 b);
|
||||
int scan_irq();
|
||||
|
||||
/* Opcodes */
|
||||
#define OP_HB 0x000
|
||||
#define OP_B 0x001
|
||||
#define OP_BLX 0x002
|
||||
#define OP_CD 0x003
|
||||
#define OP_EXMEM 0x004
|
||||
#define OP_DIAGC 0x008
|
||||
#define OP_DIAGT 0x009
|
||||
#define OP_BZ1 0x010
|
||||
#define OP_BV1 0x011
|
||||
#define OP_ST1 0x012
|
||||
#define OP_ZA1 0x013
|
||||
#define OP_A1 0x014
|
||||
#define OP_C1 0x015
|
||||
#define OP_ZAA 0x016
|
||||
#define OP_AA 0x017
|
||||
#define OP_AS1 0x018
|
||||
#define OP_AAS1 0x019
|
||||
#define OP_BZ2 0x020
|
||||
#define OP_BV2 0x021
|
||||
#define OP_ST2 0x022
|
||||
#define OP_ZA2 0x023
|
||||
#define OP_A2 0x024
|
||||
#define OP_C2 0x025
|
||||
#define OP_AS2 0x028
|
||||
#define OP_AAS2 0x029
|
||||
#define OP_BZ3 0x030
|
||||
#define OP_BV3 0x031
|
||||
#define OP_ST3 0x032
|
||||
#define OP_ZA3 0x033
|
||||
#define OP_A3 0x034
|
||||
#define OP_C3 0x035
|
||||
#define OP_AS3 0x038
|
||||
#define OP_AAS3 0x039
|
||||
#define OP_BL 0x040
|
||||
#define OP_BFLD 0x041
|
||||
#define OP_BXN 0x044
|
||||
#define OP_XL 0x045
|
||||
#define OP_XZA 0x046
|
||||
#define OP_XA 0x047
|
||||
#define OP_XSN 0x048
|
||||
#define OP_BIX 0x049
|
||||
#define OP_SC 0x050
|
||||
#define OP_BSWITCH 0x051
|
||||
#define OP_M 0x053
|
||||
#define OP_INQ 0x054
|
||||
#define OP_PC 0x055
|
||||
#define OP_ENA 0x056
|
||||
#define OP_ENB 0x057
|
||||
#define OP_PRTST 0x060
|
||||
#define OP_BSW21 0x061
|
||||
#define OP_BSW22 0x062
|
||||
#define OP_BSW23 0x063
|
||||
#define OP_PR 0x064
|
||||
#define OP_RS 0x065
|
||||
#define OP_LL 0x066
|
||||
#define OP_LE 0x067
|
||||
#define OP_LEH 0x068
|
||||
#define OP_UREC 0x069
|
||||
#define OP_FBV 0x070
|
||||
#define OP_FR 0x071
|
||||
#define OP_FM 0x073
|
||||
#define OP_FA 0x074
|
||||
#define OP_FZA 0x075
|
||||
#define OP_FAD 0x076
|
||||
#define OP_FAA 0x077
|
||||
#define OP_TAPP1 0x081
|
||||
#define OP_TAPP2 0x082
|
||||
#define OP_TAPP3 0x083
|
||||
#define OP_TAPP4 0x084
|
||||
#define OP_TRNP 0x088
|
||||
#define OP_CHNP1 0x093
|
||||
#define OP_CHNP2 0x094
|
||||
#define OP_CHNP3 0x096
|
||||
#define OP_CHNP4 0x097
|
||||
#define OP_HP 0x100
|
||||
#define OP_NOP 0x101
|
||||
#define OP_CS 0x103
|
||||
#define OP_DIAGS 0x108
|
||||
#define OP_DIAGR 0x109
|
||||
#define OP_BM1 0x110
|
||||
#define OP_ZST1 0x111
|
||||
#define OP_STD1 0x112
|
||||
#define OP_ZS1 0x113
|
||||
#define OP_S1 0x114
|
||||
#define OP_CA 0x115
|
||||
#define OP_ZSA 0x116
|
||||
#define OP_SA 0x117
|
||||
#define OP_SS1 0x118
|
||||
#define OP_BM2 0x120
|
||||
#define OP_ZST2 0x121
|
||||
#define OP_STD2 0x122
|
||||
#define OP_ZS2 0x123
|
||||
#define OP_S2 0x124
|
||||
#define OP_SS2 0x128
|
||||
#define OP_BM3 0x130
|
||||
#define OP_ZST3 0x131
|
||||
#define OP_STD3 0x132
|
||||
#define OP_ZS3 0x133
|
||||
#define OP_S3 0x134
|
||||
#define OP_SS3 0x138
|
||||
#define OP_BH 0x140
|
||||
#define OP_BE 0x141
|
||||
#define OP_BCX 0x143
|
||||
#define OP_BXM 0x144
|
||||
#define OP_XU 0x145
|
||||
#define OP_XZS 0x146
|
||||
#define OP_XS 0x147
|
||||
#define OP_XLIN 0x148
|
||||
#define OP_BDX 0x149
|
||||
#define OP_CSC 0x150
|
||||
#define OP_D 0x153
|
||||
#define OP_ENS 0x156
|
||||
#define OP_EAN 0x157
|
||||
#define OP_PRION 0x161
|
||||
#define OP_PRIOF 0x162
|
||||
#define OP_RG 0x165
|
||||
#define OP_FBU 0x170
|
||||
#define OP_FD 0x173
|
||||
#define OP_FS 0x174
|
||||
#define OP_FDD 0x175
|
||||
#define OP_FADS 0x176
|
||||
#define OP_FSA 0x177
|
||||
#define OP_TAP1 0x181
|
||||
#define OP_TAP2 0x182
|
||||
#define OP_TAP3 0x183
|
||||
#define OP_TAP4 0x184
|
||||
#define OP_TRN 0x188
|
||||
#define OP_CHN1 0x193
|
||||
#define OP_CHN2 0x194
|
||||
#define OP_CHN3 0x196
|
||||
#define OP_CHN4 0x197
|
||||
|
||||
|
||||
|
||||
|
1100
I7000/i7070_sys.c
Normal file
1100
I7000/i7070_sys.c
Normal file
File diff suppressed because it is too large
Load diff
1250
I7000/i7080_chan.c
Normal file
1250
I7000/i7080_chan.c
Normal file
File diff suppressed because it is too large
Load diff
3426
I7000/i7080_cpu.c
Normal file
3426
I7000/i7080_cpu.c
Normal file
File diff suppressed because it is too large
Load diff
103
I7000/i7080_defs.h
Normal file
103
I7000/i7080_defs.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* i7080_defs.h: IBM 7080 simulator definitions
|
||||
|
||||
Copyright (c) 2006-2016, 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 "sim_defs.h" /* simulator defns */
|
||||
|
||||
#include "i7000_defs.h"
|
||||
|
||||
/* Memory */
|
||||
#define MEM_ADDR_OK(x) ((x) < MEMSIZE)
|
||||
extern uint8 M[MAXMEMSIZE];
|
||||
extern uint32 EMEMSIZE; /* Size of emulated memory */
|
||||
|
||||
/* Issue a command to a channel */
|
||||
int chan_cmd(uint16 dev, uint16 cmd, uint32 addr);
|
||||
/* Map device to channel */
|
||||
int chan_mapdev(uint16 dev);
|
||||
/* Process the CHR 3 13 command and abort all channel activity */
|
||||
void chan_chr_13();
|
||||
uint32 load_addr(int loc);
|
||||
void store_addr(uint32 addr, int loc);
|
||||
|
||||
/* Opcode definitions. */
|
||||
#define OP_TR CHR_1
|
||||
#define OP_SEL CHR_2
|
||||
#define OP_CTL CHR_3
|
||||
#define OP_CMP CHR_4
|
||||
#define OP_SPR CHR_5
|
||||
#define OP_ADM CHR_6
|
||||
#define OP_UNL CHR_7
|
||||
#define OP_LOD CHR_8
|
||||
#define OP_TMT CHR_9
|
||||
#define OP_TRS CHR_O
|
||||
#define OP_NOP CHR_A
|
||||
#define OP_SET CHR_B
|
||||
#define OP_SHR CHR_C
|
||||
#define OP_LEN CHR_D
|
||||
#define OP_RND CHR_E
|
||||
#define OP_ST CHR_F
|
||||
#define OP_ADD CHR_G
|
||||
#define OP_RAD CHR_H
|
||||
#define OP_TRA CHR_I
|
||||
#define OP_HLT CHR_J
|
||||
#define OP_TRH CHR_K
|
||||
#define OP_TRE CHR_L
|
||||
#define OP_TRP CHR_M
|
||||
#define OP_TRZ CHR_N
|
||||
#define OP_SUB CHR_P
|
||||
#define OP_RSU CHR_Q
|
||||
#define OP_WR CHR_R
|
||||
#define OP_RWW CHR_S
|
||||
#define OP_SGN CHR_T
|
||||
#define OP_RCV CHR_U
|
||||
#define OP_MPY CHR_V
|
||||
#define OP_DIV CHR_W
|
||||
#define OP_NTR CHR_X
|
||||
#define OP_RD CHR_Y
|
||||
#define OP_WRE CHR_Z
|
||||
#define OP_AAM CHR_QUOT
|
||||
#define OP_CTL2 CHR_COM
|
||||
#define OP_LDA CHR_EQ
|
||||
#define OP_ULA CHR_STAR
|
||||
#define OP_SND CHR_SLSH
|
||||
#define OP_BLM CHR_DOL
|
||||
#define OP_SBZ CHR_RPARN
|
||||
#define OP_TZB CHR_DOT
|
||||
#define OP_CTL3 CHR_LPARN
|
||||
#define OP_SMT CHR_TRM
|
||||
|
||||
/* Channel options */
|
||||
#define CHAN_NOREC 0001 /* Don't stop at record */
|
||||
#define CHAN_8BIT 0002 /* Send 8 bit data */
|
||||
#define CHAN_SNS 0010 /* Issue sense command */
|
||||
#define CHAN_CTL 0020 /* Issue control command */
|
||||
#define CHAN_ZERO 0040 /* Zero memory after write */
|
||||
#define CHAN_SKIP 0040 /* Don't read data */
|
||||
#define CHAN_END 0100 /* Last location */
|
||||
#define CHAN_RECCNT 0200 /* Last was set record counter */
|
||||
#define CHAN_CMD 0400 /* Opcode in high order bits */
|
||||
|
||||
#define CHAN_AFULL 01000 /* A buffer has data */
|
||||
#define CHAN_BFULL 02000 /* B buffer has data */
|
||||
#define CHAN_BFLAG 04000 /* Write/read B buffer */
|
||||
|
195
I7000/i7080_drum.c
Normal file
195
I7000/i7080_drum.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* i7080_drum.c: IBM 7080 Drum
|
||||
|
||||
Copyright (c) 2007-2016, 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.
|
||||
|
||||
Provides support for 702/705 drums.
|
||||
|
||||
Drums are arranged in tracks of 200 characters each.
|
||||
|
||||
Writing continues until a end of record is recieved. At which point a
|
||||
drum mark is written. If more then 200 characters are written the next
|
||||
track is automaticaly selected.
|
||||
|
||||
Reading continues until a drum mark is read.
|
||||
|
||||
Drums address is 1000-1999
|
||||
|
||||
*/
|
||||
|
||||
#include "i7080_defs.h"
|
||||
|
||||
#ifdef NUM_DEVS_DR
|
||||
#define UNIT_DRM UNIT_ATTABLE | UNIT_DISABLE | UNIT_FIX | \
|
||||
UNIT_BUFABLE | UNIT_MUSTBUF
|
||||
|
||||
/* Device status information stored in u5 */
|
||||
#define DRMSTA_READ 000001 /* Unit is in read */
|
||||
#define DRMSTA_WRITE 000002 /* Unit is in write */
|
||||
#define DRMSTA_CMD 000004 /* Unit has recieved a cmd */
|
||||
#define DRMSTA_START 000200 /* Drum has started to transfer */
|
||||
#define DRMWORDTIME 20 /* Number of cycles per drum word */
|
||||
#define DRMCHARTRK 200 /* Characters per track */
|
||||
|
||||
uint32 drm_cmd(UNIT *, uint16, uint16);
|
||||
t_stat drm_srv(UNIT *);
|
||||
t_stat drm_boot(int32, DEVICE *);
|
||||
void drm_ini(UNIT *, t_bool);
|
||||
t_stat drm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *drm_description (DEVICE *dptr);
|
||||
extern t_stat chan_boot(int32, DEVICE *);
|
||||
|
||||
UNIT drm_unit[] = {
|
||||
{UDATA(&drm_srv, UNIT_S_CHAN(0) | UNIT_DRM, DRMCHARTRK * 1000), 0, 0},
|
||||
};
|
||||
|
||||
DEVICE drm_dev = {
|
||||
"DR", drm_unit, NULL /* Registers */ , NULL,
|
||||
1, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, NULL, &drm_boot, NULL, NULL,
|
||||
&drm_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &drm_help, NULL, NULL, &drm_description
|
||||
};
|
||||
|
||||
uint32 drm_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int addr = dev;
|
||||
|
||||
addr -= drm_dib.addr * DRMCHARTRK;
|
||||
if (addr > (int32)uptr->capac)
|
||||
return SCPE_NODEV;
|
||||
if ((uptr->flags & UNIT_ATT) != 0) {
|
||||
switch (cmd) {
|
||||
case IO_RDS:
|
||||
/* Start device */
|
||||
uptr->u5 = DRMSTA_READ | DRMSTA_CMD;
|
||||
sim_debug(DEBUG_CMD, &drm_dev, "RDS %o\n", dev);
|
||||
chan_set_sel(chan, 0);
|
||||
break;
|
||||
case IO_WRS:
|
||||
/* Start device */
|
||||
uptr->u5 = DRMSTA_WRITE | DRMSTA_CMD;
|
||||
uptr->hwmark = uptr->capac;
|
||||
sim_debug(DEBUG_CMD, &drm_dev, "WRS %o\n", dev);
|
||||
chan_set_sel(chan, 1);
|
||||
break;
|
||||
default:
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
/* Choose which part to use */
|
||||
uptr->u6 = addr; /* Set drum address */
|
||||
chan_clear(chan, CHS_ATTN); /* Clear attentions */
|
||||
/* Make sure drum is spinning */
|
||||
sim_activate(uptr, DRMWORDTIME);
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
t_stat drm_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
uint8 *buf = (uint8 *)uptr->filebuf;
|
||||
t_stat r;
|
||||
|
||||
/* Channel has disconnected, abort current read. */
|
||||
if (uptr->u5 & DRMSTA_CMD && chan_stat(chan, DEV_DISCO)) {
|
||||
uptr->u5 = 0;
|
||||
chan_clear(chan, DEV_WEOR | DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, &drm_dev, "Disconnect\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Check if we have a address match */
|
||||
if ((chan_flags[chan] & (STA_ACTIVE | DEV_SEL)) == (STA_ACTIVE | DEV_SEL)
|
||||
&& (uptr->u5 & (DRMSTA_READ | DRMSTA_WRITE))) {
|
||||
if (uptr->u6 > (int32)uptr->capac) {
|
||||
uptr->u5 = DRMSTA_CMD;
|
||||
chan_set(chan, CHS_ATTN);
|
||||
sim_activate(uptr, DRMWORDTIME);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Try and transfer a word of data */
|
||||
if (uptr->u5 & DRMSTA_READ) {
|
||||
uint8 ch = buf[uptr->u6++];
|
||||
r = chan_write_char(chan, &ch, (buf[uptr->u6] == 0)? DEV_REOR:0);
|
||||
} else {
|
||||
r = chan_read_char(chan, &buf[uptr->u6], 0);
|
||||
uptr->u6++;
|
||||
}
|
||||
switch (r) {
|
||||
case DATA_OK:
|
||||
sim_debug(DEBUG_DATA, &drm_dev, "loc %6d data %02o\n", uptr->u6,
|
||||
buf[uptr->u6]);
|
||||
break;
|
||||
|
||||
case END_RECORD:
|
||||
case TIME_ERROR:
|
||||
/* If no data, disconnect */
|
||||
sim_debug(DEBUG_DATA, &drm_dev, "loc %6d done\n", uptr->u6);
|
||||
if (uptr->u5 & DRMSTA_WRITE)
|
||||
buf[uptr->u6] = 0; /* Write mark */
|
||||
uptr->u5 = DRMSTA_CMD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sim_activate(uptr, DRMWORDTIME);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat
|
||||
drm_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
/* Init for a read */
|
||||
if (drm_cmd(uptr, IO_RDS, drm_dib.addr) != SCPE_OK)
|
||||
return STOP_IONRDY;
|
||||
return chan_boot(unit_num, dptr);
|
||||
}
|
||||
|
||||
void
|
||||
drm_ini(UNIT *uptr, t_bool f) {
|
||||
uptr->u5 = 0;
|
||||
}
|
||||
|
||||
t_stat
|
||||
drm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) {
|
||||
fprintf(st, "Drum device for IBM 702 and 705\n\n");
|
||||
fprintf(st, "The Drum had 1000 tracks with the capacity of %d digits ",
|
||||
DRMCHARTRK);
|
||||
fprintf(st, "per track\n");
|
||||
fprintf(st, "The drum does not have any settings to change\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
drm_description (DEVICE *dptr) {
|
||||
return "Drum";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
729
I7000/i7080_sys.c
Normal file
729
I7000/i7080_sys.c
Normal file
|
@ -0,0 +1,729 @@
|
|||
/* i7090_sys.c: IBM 705 Simulator system interface.
|
||||
|
||||
Copyright (c) 2006-2016, 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 "i7080_defs.h"
|
||||
#include "sim_card.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* SCP data structures and interface routines
|
||||
|
||||
sim_name simulator name string
|
||||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
||||
char sim_name[] = "IBM 7080";
|
||||
|
||||
REG *sim_PC = &cpu_reg[0];
|
||||
|
||||
int32 sim_emax = 50;
|
||||
|
||||
#ifdef NUM_DEVS_CDP
|
||||
extern DEVICE stack_dev[];
|
||||
#endif
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&chan_dev,
|
||||
#if NUM_DEVS_CDR > 0
|
||||
&cdr_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_CDP > 0
|
||||
&cdp_dev,
|
||||
#endif
|
||||
#ifdef STACK_DEV
|
||||
&stack_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_LPR > 0
|
||||
&lpr_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_CON > 0
|
||||
&con_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_MT > 0
|
||||
&mta_dev,
|
||||
#if NUM_DEVS_MT > 1
|
||||
&mtb_dev,
|
||||
#if NUM_DEVS_MT > 2
|
||||
&mtc_dev,
|
||||
#if NUM_DEVS_MT > 3
|
||||
&mtd_dev,
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if NUM_DEVS_DR > 0
|
||||
&drm_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_HT > 0
|
||||
&hta_dev,
|
||||
#if NUM_DEVS_HT > 1
|
||||
&htb_dev,
|
||||
#endif
|
||||
#endif
|
||||
#if NUM_DEVS_DSK > 0
|
||||
&dsk_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_COM > 0
|
||||
&coml_dev,
|
||||
&com_dev,
|
||||
#endif
|
||||
#if NUM_DEVS_CHRON > 0
|
||||
&chron_dev,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Device addressing words */
|
||||
#ifdef NUM_DEVS_CDP
|
||||
DIB cdp_dib = { CH_TYP_UREC, 1, 0x300, 0xff00, &cdp_cmd, &cdp_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_CDR
|
||||
DIB cdr_dib = { CH_TYP_UREC, 1, 0x100, 0xff00, &cdr_cmd, NULL };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_LPR
|
||||
DIB lpr_dib = { CH_TYP_UREC, 1, 0x400, 0xff00, &lpr_cmd, &lpr_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_CON
|
||||
DIB con_dib = { CH_TYP_UREC, 1, 0x500, 0xff00, &con_cmd, &con_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_DR
|
||||
DIB drm_dib = { CH_TYP_UREC, 1, 0x1000, 0xff00, &drm_cmd, &drm_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_MT
|
||||
DIB mt_dib = { CH_TYP_76XX|CH_TYP_754, NUM_UNITS_MT, 0x200, 0xff00, &mt_cmd, &mt_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_CHRON
|
||||
DIB chron_dib = { CH_TYP_76XX|CH_TYP_UREC, 1, 0x200, 0xff00, &chron_cmd, NULL };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_HT
|
||||
DIB ht_dib = { CH_TYP_79XX, NUM_UNITS_HT, 0, 0, &ht_cmd, NULL };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_DSK
|
||||
DIB dsk_dib = { CH_TYP_79XX, 0, 0, 0, &dsk_cmd, &dsk_ini };
|
||||
#endif
|
||||
#ifdef NUM_DEVS_COM
|
||||
DIB com_dib = { CH_TYP_79XX, 0, 0, 0, &com_cmd, NULL };
|
||||
#endif
|
||||
|
||||
/* Simulator stop codes */
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"IO device not ready",
|
||||
"HALT instruction",
|
||||
"Breakpoint",
|
||||
"Unknown Opcode",
|
||||
"Error1", /* Ind limit */ /* Not on 7080 */
|
||||
"Error2", /* XEC limit */ /* Not on 7080 */
|
||||
"I/O Check opcode",
|
||||
"Machine Check", /* MM in trap */
|
||||
"7750 invalid line number",
|
||||
"7750 invalid message",
|
||||
"7750 No free output buffers",
|
||||
"7750 No free input buffers",
|
||||
"Overflow Check", /* Field overflow */
|
||||
"Sign Check", /* Sign change */
|
||||
"Divide error",
|
||||
"Error6", /* Alpha index */ /* Not on 7080 */
|
||||
"No word mark",
|
||||
"Invalid Address",
|
||||
"Record Check",
|
||||
"Program Check",
|
||||
"Protect Check",
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
/* Simulator debug controls */
|
||||
DEBTAB dev_debug[] = {
|
||||
{"CHANNEL", DEBUG_CHAN},
|
||||
{"TRAP", DEBUG_TRAP},
|
||||
{"CMD", DEBUG_CMD},
|
||||
{"DATA", DEBUG_DATA},
|
||||
{"DETAIL", DEBUG_DETAIL},
|
||||
{"EXP", DEBUG_EXP},
|
||||
{"SENSE", DEBUG_SNS},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
DEBTAB crd_debug[] = {
|
||||
{"CHAN", DEBUG_CHAN},
|
||||
{"CMD", DEBUG_CMD},
|
||||
{"DATA", DEBUG_DATA},
|
||||
{"DETAIL", DEBUG_DETAIL},
|
||||
{"EXP", DEBUG_EXP},
|
||||
{"CARD", DEBUG_CARD},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
const char mem_to_ascii[64] = {
|
||||
'a', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '0', '=', '\'', ':', '>', 's',
|
||||
' ', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '#', ',', '(', '`', '\\', '_',
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', '!', '$', '*', ']', ';', '^',
|
||||
'+', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', '?', '.', ')', '[', '<', '|',
|
||||
/*Sq*/ /*GM*/
|
||||
};
|
||||
|
||||
t_stat parse_sym(CONST char *, t_addr, UNIT *, t_value *, int32);
|
||||
|
||||
|
||||
|
||||
/* Load BCD card image into memory, following 705 standard load format */
|
||||
int
|
||||
load_rec(uint8 *image) {
|
||||
extern uint8 bcd_bin[16];
|
||||
extern uint32 IC;
|
||||
uint32 addr;
|
||||
int len, i;
|
||||
|
||||
/* Convert blanks to space code */
|
||||
for(i = 0; i < 80; i++)
|
||||
if (image[i] == 0)
|
||||
image[i] = 020;
|
||||
|
||||
addr = bcd_bin[image[12] & 0xf];
|
||||
addr += 10 * bcd_bin[image[11] & 0xf];
|
||||
addr += 100 * bcd_bin[image[10] & 0xf];
|
||||
addr += 1000 * bcd_bin[image[9] & 0xf];
|
||||
i = (image[9] & 060) >> 4; /* Handle zones */
|
||||
i |= (image[12] & 040) >> 3;
|
||||
i |= (image[12] & 020) >> 1;
|
||||
addr += 10000 * i;
|
||||
while(addr > EMEMSIZE) addr -= EMEMSIZE; /* Wrap around */
|
||||
len = bcd_bin[image[14] & 0xf];
|
||||
len += 10 * bcd_bin[image[13] & 0xf];
|
||||
if (len > 65)
|
||||
len = 65;
|
||||
if (len == 0) {
|
||||
IC = addr;
|
||||
return 1;
|
||||
}
|
||||
for(i = 0; i < len; i++) {
|
||||
uint8 ch = image[15+i];
|
||||
if (ch == 075)
|
||||
ch = 077;
|
||||
M[addr++] = ch;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load a card image file into memory. */
|
||||
t_stat
|
||||
sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag)
|
||||
{
|
||||
char buffer[160];
|
||||
int i, j;
|
||||
|
||||
if (match_ext(fnam, "crd")) {
|
||||
uint8 image[80];
|
||||
|
||||
while (sim_fread(buffer, 1, 160, fileref) == 160) {
|
||||
/* Convert bits into image */
|
||||
for (j = i = 0; j < 80; j++) {
|
||||
uint16 x;
|
||||
x = buffer[i++];
|
||||
x |= buffer[i++] << 8;
|
||||
image[j] = sim_hol_to_bcd(x);
|
||||
}
|
||||
if (load_rec(image))
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK;
|
||||
} else if (match_ext(fnam, "cbn")) {
|
||||
uint8 image[80];
|
||||
|
||||
while (sim_fread(buffer, 1, 160, fileref) == 160) {
|
||||
/* Convert bits into image */
|
||||
for (j = i = 0; j < 80; j++) {
|
||||
uint16 x;
|
||||
x = buffer[i++];
|
||||
x |= buffer[i++] << 8;
|
||||
image[j] = sim_hol_to_bcd(x);
|
||||
}
|
||||
if (load_rec(image))
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK;
|
||||
} else if (match_ext(fnam, "dck")) {
|
||||
extern char ascii_to_six[128];
|
||||
while (fgets(buffer, 160, fileref) != 0) {
|
||||
uint8 image[80];
|
||||
/* Convert bits into image */
|
||||
memset(image, 0, sizeof(image));
|
||||
for (j = 0; j < 80; j++) {
|
||||
if (buffer[j] == '\n' || buffer[j] == '\0')
|
||||
break;
|
||||
image[j] = sim_ascii_to_six[buffer[j]&0177];
|
||||
}
|
||||
if (load_rec(image))
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK;
|
||||
} else
|
||||
return SCPE_ARG;
|
||||
|
||||
|
||||
|
||||
return SCPE_ARG;
|
||||
}
|
||||
|
||||
/* Symbol tables */
|
||||
typedef struct _opcode
|
||||
{
|
||||
uint32 opbase;
|
||||
const char *name;
|
||||
uint8 type;
|
||||
}
|
||||
t_opcode;
|
||||
|
||||
const char *chname[11] = {
|
||||
"*", "20", "21", "22", "23", "40", "41", "44", "45", "46", "47"
|
||||
};
|
||||
|
||||
#define TYPE_A 1 /* Standard memory operation */
|
||||
#define TYPE_B 2 /* ASU encoded operation */
|
||||
#define TYPE_C 3 /* MA encoded operation MA < 100 */
|
||||
#define TYPE_D 4 /* MA + ASU fixed MA < 100 */
|
||||
|
||||
t_opcode optbl[] = {
|
||||
{OP_ADD, "ADD", TYPE_A},
|
||||
{OP_RAD, "RAD", TYPE_A},
|
||||
{OP_SUB, "SUB", TYPE_A},
|
||||
{OP_RSU, "RSU", TYPE_A},
|
||||
{OP_MPY, "MPY", TYPE_A},
|
||||
{OP_DIV, "DIV", TYPE_A},
|
||||
{OP_ST, "ST", TYPE_A},
|
||||
{OP_ADM, "ADM", TYPE_A},
|
||||
{OP_AAM, "AAM", TYPE_A},
|
||||
{OP_SGN, "SGN", TYPE_A},
|
||||
{OP_SET, "SET", TYPE_A},
|
||||
{OP_SHR, "SHR", TYPE_A},
|
||||
{OP_LEN, "LNG", TYPE_A},
|
||||
{OP_RND, "RND", TYPE_A},
|
||||
{OP_LOD, "LOD", TYPE_A},
|
||||
{OP_UNL, "UNL", TYPE_A},
|
||||
{OP_LDA, "LDA", TYPE_A},
|
||||
{OP_ULA, "ULA", TYPE_A},
|
||||
{OP_SPR, "SPR", TYPE_A},
|
||||
{OP_RCV, "RCV", TYPE_A},
|
||||
{OP_SND, "SND", TYPE_A},
|
||||
{OP_CMP, "CMP", TYPE_A},
|
||||
{OP_TRE, "TRE", TYPE_A},
|
||||
{OP_TRH, "TRH", TYPE_A},
|
||||
{OP_NTR, "NTR", TYPE_A},
|
||||
{OP_TRP, "TRP", TYPE_A},
|
||||
{OP_TRZ, "TRZ", TYPE_A},
|
||||
{OP_NOP, "NOP", TYPE_A},
|
||||
{OP_TR|000100, "TSL", TYPE_B},
|
||||
{OP_TR, "TR", TYPE_A},
|
||||
{OP_TRA|000100, "TAA", TYPE_B},
|
||||
{OP_TRA|000200, "TAB", TYPE_B},
|
||||
{OP_TRA|000300, "TAC", TYPE_B},
|
||||
{OP_TRA|000400, "TAD", TYPE_B},
|
||||
{OP_TRA|000500, "TAE", TYPE_B},
|
||||
{OP_TRA|000600, "TAF", TYPE_B},
|
||||
{OP_TRA|000700, "TNS", TYPE_B},
|
||||
{OP_TRA, "TRA", TYPE_A},
|
||||
{OP_TRS|000100, "TRR", TYPE_B},
|
||||
{OP_TRS|000200, "TTC", TYPE_B},
|
||||
{OP_TRS|000300, "TSA", TYPE_B},
|
||||
{OP_TRS|001100, "TAR", TYPE_B},
|
||||
{OP_TRS|001200, "TIC", TYPE_B},
|
||||
{OP_TRS|001300, "TMC", TYPE_B},
|
||||
{OP_TRS|001400, "TRC", TYPE_B},
|
||||
{OP_TRS|001500, "TEC", TYPE_B},
|
||||
{OP_TRS|001600, "TOC", TYPE_B},
|
||||
{OP_TRS|001700, "TSC", TYPE_B},
|
||||
{OP_TRS, "TRS", TYPE_A},
|
||||
{OP_TMT, "TMT", TYPE_A},
|
||||
{OP_CTL2|000000,"SPC", TYPE_B},
|
||||
{OP_CTL2|000200,"LFC", TYPE_B},
|
||||
{OP_CTL2|000300,"UFC", TYPE_B},
|
||||
{OP_CTL2|000400,"LSB", TYPE_B},
|
||||
{OP_CTL2|000500,"USB", TYPE_B},
|
||||
{OP_CTL2|000600,"EIM", TYPE_B},
|
||||
{OP_CTL2|000700,"LIM", TYPE_B},
|
||||
{OP_CTL2|001000,"TCT", TYPE_B},
|
||||
{OP_CTL2|001100,"B", TYPE_B},
|
||||
{OP_CTL2|001200,"EIA", TYPE_B},
|
||||
{OP_CTL2|001300,"CNO", TYPE_B},
|
||||
{OP_CTL2|001400,"TLU", TYPE_B},
|
||||
{OP_CTL2|001500,"TLH", TYPE_B},
|
||||
{OP_CTL2|001600,"TIP", TYPE_B},
|
||||
{OP_CTL2|001700,"LIP", TYPE_B},
|
||||
{OP_CTL2, "CTL2", TYPE_A},
|
||||
{OP_BLM|000100, "BLMS", TYPE_B},
|
||||
{OP_BLM, "BLM", TYPE_A},
|
||||
{OP_SEL, "SEL", TYPE_A},
|
||||
{OP_CTL|001400, "ECB", TYPE_B},
|
||||
{OP_CTL|001500, "CHR", TYPE_B},
|
||||
{OP_CTL|001600, "EEM", TYPE_B},
|
||||
{OP_CTL|001700, "LEM", TYPE_B},
|
||||
{OP_CTL|0010000, "WTM", TYPE_D},
|
||||
{OP_CTL|0020100, "RUN", TYPE_D},
|
||||
{OP_CTL|0020000, "RWD", TYPE_D},
|
||||
{OP_CTL|0030000, "ION", TYPE_D},
|
||||
{OP_CTL|0040100, "BSF", TYPE_D},
|
||||
{OP_CTL|0040000, "BSP", TYPE_D},
|
||||
{OP_CTL|0050000, "SUP", TYPE_C},
|
||||
{OP_CTL|0110000, "SKP", TYPE_C},
|
||||
{OP_CTL|0450000, "SDL", TYPE_C},
|
||||
{OP_CTL|0460000, "SDH", TYPE_C},
|
||||
{OP_CTL|0000000, "IOF", TYPE_D},
|
||||
{OP_CTL, "CTL", TYPE_A},
|
||||
{OP_HLT, "HLT", TYPE_A},
|
||||
{OP_WR|000500, "WMC", TYPE_B},
|
||||
{OP_WR|000400, "CWR", TYPE_B},
|
||||
{OP_WR|000300, "SCC", TYPE_B},
|
||||
{OP_WR|000200, "SRC", TYPE_B},
|
||||
{OP_WR|000100, "DMP", TYPE_B},
|
||||
{OP_WR, "WR", TYPE_A},
|
||||
{OP_RWW, "RWW", TYPE_A},
|
||||
{OP_RD|000500, "RMB", TYPE_B},
|
||||
{OP_RD|000400, "CRD", TYPE_B},
|
||||
{OP_RD|000300, "SST", TYPE_B},
|
||||
{OP_RD|000200, "RMA", TYPE_B},
|
||||
{OP_RD|000100, "FSP", TYPE_B},
|
||||
{OP_RD, "RD", TYPE_A},
|
||||
{OP_WRE|000100, "WRZ", TYPE_B},
|
||||
{OP_WRE, "WRE", TYPE_A},
|
||||
{OP_SBZ|000100, "SBZ1", TYPE_B},
|
||||
{OP_SBZ|000200, "SBZ2", TYPE_B},
|
||||
{OP_SBZ|000300, "SBZ3", TYPE_B},
|
||||
{OP_SBZ|000400, "SBZ4", TYPE_B},
|
||||
{OP_SBZ|000500, "SBZ5", TYPE_B},
|
||||
{OP_SBZ|000600, "SBZ6", TYPE_B},
|
||||
{OP_SBZ|000700, "SBA", TYPE_B},
|
||||
{OP_SBZ|001000, "SBR", TYPE_B},
|
||||
{OP_SBZ|001100, "SBN1", TYPE_B},
|
||||
{OP_SBZ|001200, "SBN2", TYPE_B},
|
||||
{OP_SBZ|001300, "SBN3", TYPE_B},
|
||||
{OP_SBZ|001400, "SBN4", TYPE_B},
|
||||
{OP_SBZ|001500, "SBN5", TYPE_B},
|
||||
{OP_SBZ|001600, "SBN6", TYPE_B},
|
||||
{OP_SBZ, "SBZ", TYPE_A},
|
||||
{OP_TZB, "TZB", TYPE_A},
|
||||
{OP_SMT|001600, "SMT", TYPE_A},
|
||||
{0, NULL, 0},
|
||||
};
|
||||
|
||||
|
||||
/* Print out a address plus index */
|
||||
t_stat fprint_addr (FILE *of, uint32 addr) {
|
||||
fprintf(of, "%d", addr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Register change decode
|
||||
|
||||
Inputs:
|
||||
*of = output stream
|
||||
inst = mask bits
|
||||
*/
|
||||
|
||||
t_stat
|
||||
fprint_reg (FILE *of, uint32 rdx, t_value *val, UNIT *uptr, int32 sw)
|
||||
{
|
||||
fprintf(of, "Register(%d, %x)", rdx, *val);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Symbolic decode
|
||||
|
||||
Inputs:
|
||||
*of = output stream
|
||||
addr = current PC
|
||||
*val = pointer to values
|
||||
*uptr = pointer to unit
|
||||
sw = switches
|
||||
Outputs:
|
||||
return = status code
|
||||
*/
|
||||
|
||||
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
|
||||
{
|
||||
int32 i, t;
|
||||
uint8 op;
|
||||
|
||||
if (sw & SIM_SW_REG)
|
||||
return fprint_reg(of, addr, val, uptr, sw);
|
||||
|
||||
if (sw & SWMASK ('C')) { /* character? */
|
||||
t = val[0];
|
||||
fprintf (of, " %c<%02o> ", mem_to_ascii[t & 077], t & 077);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((uptr != NULL) && (uptr != &cpu_unit)) return SCPE_ARG; /* CPU? */
|
||||
if (sw & SWMASK ('D')) { /* dump? */
|
||||
for (i = 0; i < 50; i++) fprintf (of, "%c", mem_to_ascii[val[i]&077]) ;
|
||||
return -(i - 1);
|
||||
}
|
||||
if (sw & SWMASK ('S')) { /* string? */
|
||||
i = 0;
|
||||
do {
|
||||
t = val[i++];
|
||||
fprintf (of, "%c", mem_to_ascii[t & 077]);
|
||||
} while (i < 50);
|
||||
return -(i - 1);
|
||||
}
|
||||
if (sw & SWMASK ('M')) { /* machine code? */
|
||||
uint32 addr;
|
||||
t_opcode *tab;
|
||||
uint8 zone;
|
||||
uint8 reg;
|
||||
uint16 opvalue;
|
||||
|
||||
i = 0;
|
||||
op = val[i++] & 077;
|
||||
t = val[i++]; /* First address char */
|
||||
zone = (t & 060) >> 4;
|
||||
t &= 0xf;
|
||||
if (t == 10)
|
||||
t = 0;
|
||||
addr = t * 1000;
|
||||
t = val[i++]; /* Second address char */
|
||||
reg = (t & 060) >> 2;
|
||||
t &= 0xf;
|
||||
if (t == 10)
|
||||
t = 0;
|
||||
addr += t * 100;
|
||||
t = val[i++]; /* Third address char */
|
||||
reg |= (t & 060) >> 4;
|
||||
t &= 0xf;
|
||||
if (t == 10)
|
||||
t = 0;
|
||||
addr += t * 10;
|
||||
t = val[i++]; /* Forth address char */
|
||||
zone |= (t & 060) >> 2;
|
||||
/* Switch BA bits in high zone */
|
||||
zone = (zone & 03) | ((zone & 04) << 1) | ((zone & 010) >> 1);
|
||||
t &= 0xf;
|
||||
if (t == 10)
|
||||
t = 0;
|
||||
addr += t;
|
||||
opvalue = op | (reg << 6);
|
||||
addr += zone * 10000;
|
||||
for(tab = optbl; tab->name != NULL; tab++) {
|
||||
if (tab->type == TYPE_A && op == tab->opbase)
|
||||
break;
|
||||
if (tab->type == TYPE_B && opvalue == tab->opbase)
|
||||
break;
|
||||
if (tab->type == TYPE_C && addr < 100 &&
|
||||
(op|(addr << 12)) == tab->opbase)
|
||||
break;
|
||||
if (tab->type == TYPE_D && addr < 100 &&
|
||||
(opvalue|(addr << 12)) == tab->opbase)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tab->name == NULL)
|
||||
fprintf(of, "%c<%02o>\t", mem_to_ascii[op], op);
|
||||
else
|
||||
fprintf(of, "%s\t", tab->name);
|
||||
|
||||
switch(tab->type) {
|
||||
case TYPE_A:
|
||||
fprintf(of, "%d", addr);
|
||||
if (reg != 0)
|
||||
fprintf(of, ",%d", reg);
|
||||
break;
|
||||
case TYPE_B:
|
||||
fprintf(of, "%d", addr);
|
||||
break;
|
||||
case TYPE_C: /* No operand required for type C or D */
|
||||
case TYPE_D:
|
||||
break;
|
||||
}
|
||||
return -(i - 1);
|
||||
}
|
||||
fprintf (of, " %02o ", val[0] & 077);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_opcode *
|
||||
find_opcode(char *op, t_opcode * tab)
|
||||
{
|
||||
while (tab->name != NULL) {
|
||||
if (*tab->name != '\0' && strcmp(op, tab->name) == 0)
|
||||
return tab;
|
||||
tab++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Symbolic input
|
||||
|
||||
Inputs:
|
||||
*cptr = pointer to input string
|
||||
addr = current PC
|
||||
uptr = pointer to unit
|
||||
*val = pointer to output values
|
||||
sw = switches
|
||||
Outputs:
|
||||
status = error status
|
||||
*/
|
||||
|
||||
t_stat
|
||||
parse_sym(CONST char *cptr, t_addr addr, UNIT * uptr, t_value * val, int32 sw)
|
||||
{
|
||||
int i;
|
||||
t_value d;
|
||||
char buffer[100];
|
||||
extern char ascii_to_six[];
|
||||
|
||||
while (isspace(*cptr))
|
||||
cptr++;
|
||||
d = 0;
|
||||
i = 0;
|
||||
if (sw & SWMASK('C')) {
|
||||
while (*cptr != '\0') {
|
||||
d = sim_ascii_to_six[0177 & *cptr++];
|
||||
if (d == 0)
|
||||
d = 020;
|
||||
val[i++] = d;
|
||||
}
|
||||
if (i == 0)
|
||||
return SCPE_ARG;
|
||||
return -(i - 1);
|
||||
} else if (sw & SWMASK('M')) {
|
||||
t_opcode *op;
|
||||
uint32 addr = 0;
|
||||
uint8 asu = 0;
|
||||
uint8 zone;
|
||||
uint8 t;
|
||||
|
||||
i = 0;
|
||||
/* Grab opcode */
|
||||
cptr = get_glyph(cptr, buffer, 0);
|
||||
if ((op = find_opcode(buffer, optbl)) == 0)
|
||||
return STOP_UUO;
|
||||
if (op->type == TYPE_C || op->type == TYPE_D) {
|
||||
addr = op->opbase >> 12;
|
||||
val[i++] = op->opbase & 077;
|
||||
val[i++] = 10;
|
||||
val[i++] = ((op->opbase & 01400) >> 4) | 10;
|
||||
t = addr / 10;
|
||||
if (t == 0)
|
||||
t = 10;
|
||||
val[i++] = ((op->opbase & 00300) >> 2) | t;
|
||||
t = addr % 10;
|
||||
if (t == 0)
|
||||
t = 10;
|
||||
val[i++] = t;
|
||||
return -(i - 1);
|
||||
}
|
||||
/* Skip blanks */
|
||||
while(isspace(*cptr)) cptr++;
|
||||
/* Collect address */
|
||||
while(*cptr >= '0' && *cptr <= '9')
|
||||
addr = (addr * 10) + (*cptr++ - '0');
|
||||
/* Skip blanks */
|
||||
while(isspace(*cptr)) cptr++;
|
||||
if (*cptr == ',') { /* Collect a ASU */
|
||||
while(*cptr >= '0' && *cptr <= '9')
|
||||
asu = (asu * 10) + (*cptr++ - '0');
|
||||
|
||||
}
|
||||
/* Skip blanks */
|
||||
while(isspace(*cptr)) cptr++;
|
||||
if (*cptr != '\0')
|
||||
return SCPE_ARG;
|
||||
/* Type B's can't have ASU */
|
||||
if (op->type == TYPE_B) {
|
||||
if (asu != 0)
|
||||
return STOP_UUO;
|
||||
asu = (op->opbase >> 6) & 017;
|
||||
}
|
||||
/* Check if ASU out of range */
|
||||
if (asu > 16)
|
||||
return SCPE_ARG;
|
||||
zone = addr / 10000;
|
||||
if (zone > 16)
|
||||
return SCPE_ARG;
|
||||
addr %= 10000;
|
||||
val[i++] = op->opbase & 077;
|
||||
t = addr / 1000;
|
||||
if (t == 0)
|
||||
t = 10;
|
||||
addr %= 1000;
|
||||
val[i++] = t | ((zone << 4) & 060);
|
||||
t = addr / 100;
|
||||
if (t == 0)
|
||||
t = 10;
|
||||
addr %= 100;
|
||||
val[i++] = t | ((asu << 2) & 060);
|
||||
t = addr / 10;
|
||||
if (t == 0)
|
||||
t = 10;
|
||||
addr %= 10;
|
||||
val[i++] = t | ((asu << 4) & 060);
|
||||
t = addr;
|
||||
if (t == 0)
|
||||
t = 10;
|
||||
addr %= 10;
|
||||
val[i++] = t | ((zone << 2) & 060);
|
||||
return -(i - 1);
|
||||
} else {
|
||||
int sign = 0;
|
||||
|
||||
i = 0;
|
||||
while (*cptr != '\0') {
|
||||
sign = 0;
|
||||
/* Skip blanks */
|
||||
while(isspace(*cptr)) cptr++;
|
||||
if (*cptr == '+') {
|
||||
cptr++;
|
||||
sign = 1;
|
||||
} else if (*cptr == '-') {
|
||||
cptr++;
|
||||
sign = -1;
|
||||
}
|
||||
if (!(*cptr >= '0' && *cptr <= '9'))
|
||||
return SCPE_ARG;
|
||||
while(*cptr >= '0' && *cptr <= '9') {
|
||||
d = *cptr++ - '0';
|
||||
if (d == 0)
|
||||
d = 10;
|
||||
val[i++] = d;
|
||||
}
|
||||
if (*cptr == ',')
|
||||
cptr++;
|
||||
if(sign)
|
||||
val[i-1] |= (sign==-1)?040:060; /* Set sign last digit */
|
||||
}
|
||||
if (i == 0)
|
||||
return SCPE_ARG;
|
||||
return -(i - 1);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
302
I7000/i7090_cdp.c
Normal file
302
I7000/i7090_cdp.c
Normal file
|
@ -0,0 +1,302 @@
|
|||
/* i7090_cdp.c: IBM 7090 Card punch.
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This is the standard card punch.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7090_defs.h"
|
||||
#include "sim_card.h"
|
||||
#ifdef NUM_DEVS_CDP
|
||||
#define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE
|
||||
|
||||
|
||||
/* std devices. data structures
|
||||
|
||||
chan_dev Channel device descriptor
|
||||
chan_unit Channel unit descriptor
|
||||
chan_reg Channel register list
|
||||
chan_mod Channel modifiers list
|
||||
*/
|
||||
|
||||
/* Device status information stored in u5 */
|
||||
#define CDPSTA_PUNCH 0004000 /* Punch strobe during run */
|
||||
#define CDPSTA_POSMASK 0770000
|
||||
#define CDPSTA_POSSHIFT 12
|
||||
|
||||
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 *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *cdp_description (DEVICE *dptr);
|
||||
|
||||
UNIT cdp_unit[] = {
|
||||
#if NUM_DEVS_CDP > 1
|
||||
{UDATA(&cdp_srv, UNIT_S_CHAN(CHAN_A) | UNIT_CDP, 0), 6000}, /* A */
|
||||
#endif
|
||||
#if NUM_DEVS_CDP > 2
|
||||
{UDATA(&cdp_srv, UNIT_S_CHAN(CHAN_C) | UNIT_CDP, 0), 6000}, /* B */
|
||||
#endif
|
||||
#if NUM_DEVS_CDP > 3
|
||||
{UDATA(&cdp_srv, UNIT_S_CHAN(CHAN_E) | UNIT_CDP | UNIT_DIS, 0), 6000}, /* C */
|
||||
#endif
|
||||
{UDATA(&cdp_srv, UNIT_S_CHAN(CHAN_CHPIO) | UNIT_CDP, 0), 6000}, /* D */
|
||||
};
|
||||
|
||||
MTAB cdp_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_card_set_fmt, &sim_card_show_fmt, NULL},
|
||||
#if NUM_CHAN != 1
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
||||
&get_chan, NULL},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE cdp_dev = {
|
||||
"CDP", cdp_unit, NULL, cdp_mod,
|
||||
NUM_DEVS_CDP, 8, 15, 1, 8, 36,
|
||||
NULL, NULL, &cdp_reset, NULL, &cdp_attach, &cdp_detach,
|
||||
&cdp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
|
||||
NULL, NULL, &cdp_help, NULL, NULL, &cdp_description
|
||||
};
|
||||
|
||||
/* Card punch routine
|
||||
|
||||
Modifiers have been checked by the caller
|
||||
C modifier is recognized (column binary is implemented)
|
||||
*/
|
||||
|
||||
|
||||
uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - cdp_unit);
|
||||
extern uint16 IC;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) != 0 && cmd == IO_WRS) {
|
||||
/* Start device */
|
||||
if (!(uptr->u5 & URCSTA_CMD)) {
|
||||
dev_pulse[chan] &= ~PUNCH_M;
|
||||
uptr->u5 &= ~CDPSTA_PUNCH;
|
||||
if ((uptr->u5 & URCSTA_ON) == 0) {
|
||||
uptr->wait = 330; /* Startup delay */
|
||||
} else if (uptr->u5 & URCSTA_IDLE && uptr->wait <= 30) {
|
||||
uptr->wait += 85; /* Wait for next latch point */
|
||||
}
|
||||
uptr->u5 |= (URCSTA_WRITE | URCSTA_CMD);
|
||||
uptr->u5 &= ~CDPSTA_POSMASK;
|
||||
chan_set_sel(chan, 1);
|
||||
chan_clear_status(chan);
|
||||
sim_activate(uptr, us_to_ticks(1000)); /* activate */
|
||||
sim_debug(DEBUG_CMD, &cdp_dev, "%05o WRS unit=%d\n", IC, u);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
chan_set_attn(chan);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
t_stat cdp_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - cdp_unit);
|
||||
int pos;
|
||||
t_uint64 wd;
|
||||
int bit;
|
||||
t_uint64 mask;
|
||||
int b;
|
||||
int col;
|
||||
struct _card_data *data;
|
||||
|
||||
/* Channel has disconnected, abort current card. */
|
||||
if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) {
|
||||
if ((uptr->u5 & CDPSTA_POSMASK) != 0) {
|
||||
sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n");
|
||||
sim_punch_card(uptr, NULL);
|
||||
uptr->u5 &= ~CDPSTA_PUNCH;
|
||||
}
|
||||
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_CMD | CDPSTA_POSMASK);
|
||||
chan_clear(chan, DEV_WEOR | DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
|
||||
}
|
||||
|
||||
/* Check to see if we have timed out */
|
||||
if (uptr->wait != 0) {
|
||||
uptr->wait--;
|
||||
/* If at end of record and channel is still active, do another read */
|
||||
if (
|
||||
((uptr->u5 & (URCSTA_CMD | URCSTA_IDLE | URCSTA_WRITE | URCSTA_ON))
|
||||
== (URCSTA_CMD | URCSTA_IDLE | URCSTA_ON)) && uptr->wait > 30
|
||||
&& chan_test(chan, STA_ACTIVE)) {
|
||||
uptr->u5 |= URCSTA_WRITE;
|
||||
uptr->u5 &= ~URCSTA_IDLE;
|
||||
chan_set(chan, DEV_WRITE);
|
||||
chan_clear(chan, DEV_WEOR);
|
||||
sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d restarting\n", u);
|
||||
}
|
||||
sim_activate(uptr, us_to_ticks(1000)); /* activate */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* If no write request, go to idle mode */
|
||||
if ((uptr->u5 & URCSTA_WRITE) == 0) {
|
||||
if ((uptr->u5 & (URCSTA_IDLE | URCSTA_ON)) ==
|
||||
(URCSTA_IDLE | URCSTA_ON)) {
|
||||
uptr->wait = 85; /* Delay 85ms */
|
||||
uptr->u5 &= ~URCSTA_IDLE; /* Not running */
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
} else {
|
||||
uptr->u5 &= ~URCSTA_ON; /* Turn motor off */
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Motor is up to speed now */
|
||||
uptr->u5 |= URCSTA_ON;
|
||||
uptr->u5 &= ~URCSTA_IDLE; /* Not running */
|
||||
|
||||
if (dev_pulse[chan] & PUNCH_M)
|
||||
uptr->u5 |= CDPSTA_PUNCH;
|
||||
|
||||
pos = (uptr->u5 & CDPSTA_POSMASK) >> CDPSTA_POSSHIFT;
|
||||
if (pos == 24) {
|
||||
if (chan_test(chan, STA_ACTIVE)) {
|
||||
sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d set EOR\n", u);
|
||||
chan_set(chan, DEV_REOR);
|
||||
} else {
|
||||
chan_clear(chan, DEV_WEOR | DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card full\n");
|
||||
sim_punch_card(uptr, NULL);
|
||||
uptr->u5 |= URCSTA_IDLE;
|
||||
uptr->u5 &= ~(URCSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH);
|
||||
uptr->wait = 85;
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sim_debug(DEBUG_DATA, &cdp_dev, "unit=%d write column %d ", u, pos);
|
||||
wd = 0;
|
||||
data = (struct _card_data *)uptr->up7;
|
||||
switch (chan_read(chan, &wd, 0)) {
|
||||
case DATA_OK:
|
||||
sim_debug(DEBUG_DATA, &cdp_dev, " %012llo\n", wd);
|
||||
/* Bit flip into temp buffer */
|
||||
bit = 1 << (pos / 2);
|
||||
mask = 1;
|
||||
b = (pos & 1)?36:0;
|
||||
|
||||
for (col = 35; col >= 0; mask <<= 1, col--) {
|
||||
if (wd & mask)
|
||||
data->image[col + b] |= bit;
|
||||
}
|
||||
pos++;
|
||||
uptr->wait = 0;
|
||||
uptr->u5 &= ~CDPSTA_POSMASK;
|
||||
uptr->u5 |= (pos << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
|
||||
sim_activate(uptr, (pos & 1) ? us_to_ticks(300) : us_to_ticks(8000));
|
||||
return SCPE_OK;
|
||||
case END_RECORD:
|
||||
sim_debug(DEBUG_DATA, &cdp_dev, "eor\n");
|
||||
uptr->wait = 8 * (12 - (pos / 2)) /*+ 85*/;
|
||||
uptr->u5 &= ~(CDPSTA_POSMASK);
|
||||
uptr->u5 |= (24 << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
|
||||
break;
|
||||
case TIME_ERROR:
|
||||
sim_debug(DEBUG_DATA, &cdp_dev, "no data\n");
|
||||
chan_set_attn(chan);
|
||||
uptr->wait = 8 * (12 - (pos / 2)) /*+ 85*/;
|
||||
uptr->u5 &= ~(CDPSTA_POSMASK);
|
||||
uptr->u5 |= (24 << CDPSTA_POSSHIFT) & CDPSTA_POSMASK;
|
||||
break;
|
||||
}
|
||||
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void
|
||||
cdp_ini(UNIT * uptr, t_bool f)
|
||||
{
|
||||
uptr->u5 = 0;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdp_reset(DEVICE * dptr)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdp_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u5 = CDPSTA_POSMASK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdp_detach(UNIT * uptr)
|
||||
{
|
||||
return sim_card_detach(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
const char *cpu = cpu_description(&cpu_dev);
|
||||
|
||||
fprintf (st, "%s\n\n", cdp_description(dptr));
|
||||
#if NUM_DEVS_CDP > 3
|
||||
fprintf (st, "The %s supports up to four card punches\n", cpu);
|
||||
#elif NUM_DEVS_CDP > 2
|
||||
fprintf (st, "The %s supports up to three card punches\n", cpu);
|
||||
#elif NUM_DEVS_CDP > 1
|
||||
fprintf (st, "The %s supports up to two card punches\n", cpu);
|
||||
#elif NUM_DEVS_CDP > 0
|
||||
fprintf (st, "The %s supports one card punch\n", cpu);
|
||||
#endif
|
||||
help_set_chan_type(st, dptr, "Card punches");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
fprintf (st, "\n");
|
||||
sim_card_attach_help(st, dptr, uptr, flag, cptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
cdp_description(DEVICE *dptr)
|
||||
{
|
||||
return "721 Card Punch";
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
339
I7000/i7090_cdr.c
Normal file
339
I7000/i7090_cdr.c
Normal file
|
@ -0,0 +1,339 @@
|
|||
/* i7090_cdr.c: IBM 7090 Card Read.
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This is the standard card reader.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7090_defs.h"
|
||||
#include "sim_card.h"
|
||||
|
||||
#ifdef NUM_DEVS_CDR
|
||||
|
||||
#define UNIT_CDR UNIT_ATTABLE | UNIT_RO | UNIT_DISABLE | UNIT_ROABLE |\
|
||||
MODE_026
|
||||
|
||||
|
||||
/* std devices. data structures
|
||||
|
||||
chan_dev Channel device descriptor
|
||||
chan_unit Channel unit descriptor
|
||||
chan_reg Channel register list
|
||||
chan_mod Channel modifiers list
|
||||
*/
|
||||
|
||||
/* Device status information stored in u5 */
|
||||
#define CDRSTA_EOR 002000 /* Hit end of record */
|
||||
#define CDRPOSMASK 0770000 /* Bit Mask to retrive drum position */
|
||||
#define CDRPOSSHIFT 12
|
||||
|
||||
|
||||
t_stat cdr_srv(UNIT *);
|
||||
t_stat cdr_boot(int32, DEVICE *);
|
||||
t_stat cdr_reset(DEVICE *);
|
||||
t_stat cdr_attach(UNIT *, CONST char *);
|
||||
t_stat cdr_detach(UNIT *);
|
||||
t_stat cdr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *cdr_description (DEVICE *dptr);
|
||||
|
||||
UNIT cdr_unit[] = {
|
||||
#if NUM_DEVS_CDR > 1
|
||||
{UDATA(&cdr_srv, UNIT_S_CHAN(CHAN_A) | UNIT_CDR, 0), 3000}, /* A */
|
||||
#endif
|
||||
#if NUM_DEVS_CDR > 2
|
||||
{UDATA(&cdr_srv, UNIT_S_CHAN(CHAN_C) | UNIT_CDR, 0), 3000}, /* B */
|
||||
#endif
|
||||
#if NUM_DEVS_CDR > 3
|
||||
{UDATA(&cdr_srv, UNIT_S_CHAN(CHAN_E) | UNIT_CDR | UNIT_DIS, 0), 3000}, /* C */
|
||||
#endif
|
||||
{UDATA(&cdr_srv, UNIT_S_CHAN(CHAN_CHPIO) | UNIT_CDR, 0), 3000}, /* D */
|
||||
};
|
||||
|
||||
MTAB cdr_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_card_set_fmt, &sim_card_show_fmt, NULL},
|
||||
#if NUM_CHAN != 1
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
||||
&get_chan, NULL},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE cdr_dev = {
|
||||
"CDR", cdr_unit, NULL, cdr_mod,
|
||||
NUM_DEVS_CDR, 8, 15, 1, 8, 36,
|
||||
NULL, NULL, &cdr_reset, &cdr_boot, &cdr_attach, &cdr_detach,
|
||||
&cdr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
|
||||
NULL, NULL, &cdr_help, NULL, NULL, &cdr_description
|
||||
};
|
||||
|
||||
|
||||
uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) != 0 && cmd == IO_RDS) {
|
||||
int u = (uptr - cdr_unit);
|
||||
|
||||
/* Start device */
|
||||
if ((uptr->u5 & URCSTA_CMD) == 0) {
|
||||
if ((uptr->u5 & (URCSTA_ON | URCSTA_IDLE)) ==
|
||||
(URCSTA_ON | URCSTA_IDLE) && (uptr->wait <= 60)) {
|
||||
uptr->wait += 100; /* Wait for next latch point */
|
||||
} else
|
||||
uptr->wait = 75; /* Startup delay */
|
||||
uptr->u5 |= URCSTA_READ | URCSTA_CMD | CDRPOSMASK;
|
||||
chan_set_sel(chan, 0);
|
||||
chan_clear_status(chan);
|
||||
sim_activate(uptr, us_to_ticks(1000)); /* activate */
|
||||
sim_debug(DEBUG_CMD, &cdr_dev, "RDS unit=%d\n", u);
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_BUSY;
|
||||
}
|
||||
chan_set_attn(chan);
|
||||
return SCPE_NODEV;
|
||||
}
|
||||
|
||||
t_stat cdr_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - cdr_unit);
|
||||
int pos, col, b;
|
||||
uint16 bit;
|
||||
t_uint64 mask, wd;
|
||||
struct _card_data *data;
|
||||
|
||||
/* Channel has disconnected, abort current read. */
|
||||
if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) {
|
||||
uptr->u5 &= ~(URCSTA_READ | URCSTA_CMD);
|
||||
uptr->u5 |= CDRPOSMASK;
|
||||
chan_clear(chan, DEV_WEOR | DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, &cdr_dev, "unit=%d disconnecting\n", u);
|
||||
}
|
||||
|
||||
/* Check to see if we have timed out */
|
||||
if (uptr->wait != 0) {
|
||||
/* If at end of record and channel is still active, do another read */
|
||||
if (uptr->wait == 30
|
||||
&& ((uptr->u5 & (URCSTA_CMD|URCSTA_IDLE|URCSTA_READ|URCSTA_ON))
|
||||
== (URCSTA_CMD | URCSTA_IDLE | URCSTA_ON))
|
||||
&& chan_test(chan, STA_ACTIVE)) {
|
||||
uptr->u5 |= URCSTA_READ;
|
||||
sim_debug(DEBUG_CHAN, &cdr_dev, "unit=%d restarting\n", u);
|
||||
}
|
||||
uptr->wait--;
|
||||
sim_activate(uptr, us_to_ticks(1000)); /* activate */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* If no read request, go to idle mode */
|
||||
if ((uptr->u5 & URCSTA_READ) == 0) {
|
||||
if ((uptr->u5 & URCSTA_EOF) || (uptr->u5 & URCSTA_IDLE)) {
|
||||
uptr->u5 &= ~(URCSTA_ON | URCSTA_IDLE); /* Turn motor off */
|
||||
} else {
|
||||
uptr->wait = 85; /* Delay 85ms */
|
||||
uptr->u5 |= URCSTA_IDLE; /* Go idle */
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Motor is up to speed now */
|
||||
uptr->u5 |= URCSTA_ON;
|
||||
uptr->u5 &= ~URCSTA_IDLE;
|
||||
|
||||
pos = (uptr->u5 & CDRPOSMASK) >> CDRPOSSHIFT;
|
||||
if (pos == (CDRPOSMASK >> CDRPOSSHIFT)) {
|
||||
switch (sim_read_card(uptr)) {
|
||||
case SCPE_UNATT:
|
||||
case SCPE_IOERR:
|
||||
sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d Setting ATTN\n", u);
|
||||
chan_set_error(chan);
|
||||
chan_set_attn(chan);
|
||||
uptr->u5 &= ~URCSTA_READ;
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
case SCPE_EOF:
|
||||
sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d EOF\n", u);
|
||||
chan_set_eof(chan);
|
||||
chan_set_attn(chan);
|
||||
uptr->u5 &= ~URCSTA_READ;
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
break;
|
||||
}
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/* Check if everything read in, if so return EOR now */
|
||||
if (pos == 24) {
|
||||
sim_debug(DEBUG_CHAN, &cdr_dev, "unit=%d set EOR\n", u);
|
||||
chan_set(chan, DEV_REOR);
|
||||
uptr->u5 &= ~URCSTA_READ;
|
||||
uptr->u5 |= CDRSTA_EOR | CDRPOSMASK;
|
||||
uptr->wait = 86;
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
data = (struct _card_data *)uptr->up7;
|
||||
/* Bit flip into read buffer */
|
||||
bit = 1 << (pos / 2);
|
||||
mask = 1;
|
||||
wd = 0;
|
||||
b = (pos & 1)?36:0;
|
||||
|
||||
for (col = 35; col >= 0; mask <<= 1) {
|
||||
if (data->image[col-- + b] & bit)
|
||||
wd |= mask;
|
||||
}
|
||||
|
||||
switch (chan_write (chan, &wd,/* (pos == 23) ? DEV_REOR :*/ 0)) {
|
||||
case DATA_OK:
|
||||
sim_debug(DEBUG_DATA, &cdr_dev, "unit=%d read row %d %012llo\n", u,
|
||||
pos, wd);
|
||||
pos++;
|
||||
uptr->u5 &= ~CDRPOSMASK;
|
||||
uptr->u5 |= pos << CDRPOSSHIFT;
|
||||
uptr->wait = 0;
|
||||
sim_activate(uptr, (pos & 1) ? us_to_ticks(300) : us_to_ticks(8000));
|
||||
return SCPE_OK;
|
||||
|
||||
case END_RECORD:
|
||||
sim_debug(DEBUG_CHAN, &cdr_dev, "unit=%d got EOR\n", u);
|
||||
uptr->u5 &= ~CDRPOSMASK;
|
||||
uptr->u5 |= 24 << CDRPOSSHIFT;
|
||||
uptr->wait = 8 * (12 - (pos / 2)) /*+ 86*/;
|
||||
break;
|
||||
|
||||
case TIME_ERROR:
|
||||
sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d no data\n", u);
|
||||
uptr->u5 &= ~CDRPOSMASK;
|
||||
uptr->u5 |= 24 << CDRPOSSHIFT;
|
||||
uptr->wait = 8 * (12 - (pos / 2)) /*+ 85*/;
|
||||
break;
|
||||
}
|
||||
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat
|
||||
cdr_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
t_stat r;
|
||||
int pos;
|
||||
struct _card_data *data;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
uptr->u5 = 0;
|
||||
/* Init for a read */
|
||||
if (cdr_cmd(uptr, IO_RDS, cdr_dib.addr) != SCPE_OK)
|
||||
return STOP_IONRDY;
|
||||
r = sim_read_card(uptr);
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
|
||||
/* Copy first three records. */
|
||||
data = (struct _card_data *)uptr->up7;
|
||||
uptr->u5 &= ~CDRPOSMASK;
|
||||
for(pos = 0; pos <3; pos++) {
|
||||
uint16 bit = 1 << (pos / 2);
|
||||
t_uint64 mask = 1;
|
||||
int b = (pos & 1)?36:0;
|
||||
int col;
|
||||
|
||||
if (pos == 2 && chan == 0)
|
||||
break;
|
||||
M[pos] = 0;
|
||||
for (col = 35; col >= 0; mask <<= 1) {
|
||||
if (data->image[col-- + b] & bit)
|
||||
M[pos] |= mask;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, &cdr_dev, "boot read row %d %012llo\n",
|
||||
pos, M[pos]);
|
||||
}
|
||||
uptr->u5 |= pos << CDRPOSSHIFT;
|
||||
/* Make sure channel is set to start reading rest. */
|
||||
return chan_boot(unit_num, dptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_reset(DEVICE * dptr)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u5 = 0;
|
||||
uptr->u4 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_detach(UNIT * uptr)
|
||||
{
|
||||
return sim_card_detach(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
const char *cpu = cpu_description(&cpu_dev);
|
||||
|
||||
fprintf (st, "%s\n\n", cdr_description(dptr));
|
||||
#if NUM_DEVS_CDR > 3
|
||||
fprintf (st, "The %s supports up to four card readers\n\n", cpu);
|
||||
#elif NUM_DEVS_CDR > 2
|
||||
fprintf (st, "The %s supports up to three card readers\n\n", cpu);
|
||||
#elif NUM_DEVS_CDR > 1
|
||||
fprintf (st, "The %s supports up to two card readers\n\n", cpu);
|
||||
#elif NUM_DEVS_CDR > 0
|
||||
fprintf (st, "The %s supports one card reader\n\n", cpu);
|
||||
#endif
|
||||
help_set_chan_type(st, dptr, "Card readers");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
fprintf (st, "\n");
|
||||
sim_card_attach_help(st, dptr, uptr, flag, cptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
cdr_description(DEVICE *dptr)
|
||||
{
|
||||
return "711 Card Reader";
|
||||
}
|
||||
|
||||
#endif
|
1710
I7000/i7090_chan.c
Normal file
1710
I7000/i7090_chan.c
Normal file
File diff suppressed because it is too large
Load diff
4435
I7000/i7090_cpu.c
Normal file
4435
I7000/i7090_cpu.c
Normal file
File diff suppressed because it is too large
Load diff
437
I7000/i7090_defs.h
Normal file
437
I7000/i7090_defs.h
Normal file
|
@ -0,0 +1,437 @@
|
|||
/* i7090_defs.h: IBM 7090 simulator definitions
|
||||
|
||||
Copyright (c) 2005, 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 "sim_defs.h" /* simulator defns */
|
||||
#include "i7000_defs.h"
|
||||
|
||||
#define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */
|
||||
#define MEM_ADDR_OK(x) (((uint16) (x&077777)) < MEMSIZE)
|
||||
#define ReadP(x) (M[x])
|
||||
#define WriteP(x,y) if (MEM_ADDR_OK (x)) M[x] = y
|
||||
extern t_uint64 M[MAXMEMSIZE];
|
||||
|
||||
/* Processor specific masks */
|
||||
#define ONEBIT 00200000000000LL
|
||||
#define PMASK 00377777777777LL
|
||||
#define RMASK 00000000777777LL
|
||||
#define LMASK 00777777000000LL
|
||||
#define AMSIGN 02000000000000LL
|
||||
#define AMMASK 01777777777777LL
|
||||
#define AQSIGN 01000000000000LL
|
||||
#define AQMASK 00777777777777LL
|
||||
#define APSIGN 00400000000000LL
|
||||
#define PREMASK 00700000000000LL
|
||||
#define AMASK 00000000077777LL
|
||||
#define TMASK 00000000700000LL
|
||||
#define DMASK 00077777000000LL
|
||||
#define MSIGN 00400000000000LL
|
||||
#define WMASK 00777777777777LL
|
||||
#define FPCMASK 00377000000000LL
|
||||
#define FPMMASK 00000777777777LL
|
||||
#define FPOBIT 00001000000000LL
|
||||
#define FPNBIT 00000400000000LL
|
||||
#define FPMQERR 00000001000000LL /* Bit 17 */
|
||||
#define FPACERR 00000002000000LL /* Bit 16 */
|
||||
#define FPOVERR 00000004000000LL /* Bit 15 */
|
||||
#define FPSPERR 00000010000000LL /* Bit 14 */
|
||||
#define FPDPERR 00000040000000LL /* Bit 12 */
|
||||
|
||||
/* 7090 specific channel functions */
|
||||
/* Reset the channel, clear any pending device */
|
||||
void chan_rst(int chan, int type);
|
||||
|
||||
/* Issue a command to a channel */
|
||||
int chan_cmd(uint16 dev, uint16 cmd);
|
||||
|
||||
/* Give channel a command, any executing command is aborted */
|
||||
int chan_start(int chan, uint16 addr);
|
||||
|
||||
/* Give channel a new address to start working at */
|
||||
int chan_load(int chan, uint16 addr);
|
||||
|
||||
/* return the channels current command address */
|
||||
void chan_store(int chan, uint16 addr);
|
||||
|
||||
/* Nop for the momement */
|
||||
void chan_store_diag(int chan, uint16 addr);
|
||||
|
||||
/* Channel data handling */
|
||||
int chan_write(int chan, t_uint64 *data, int flags);
|
||||
int chan_read(int chan, t_uint64 *data, int flags);
|
||||
|
||||
void chan_proc();
|
||||
|
||||
extern uint16 dev_pulse[NUM_CHAN]; /* Device pulse */
|
||||
#define PUNCH_1 000001
|
||||
#define PUNCH_2 000002
|
||||
#define PUNCH_M 000003
|
||||
#define PRINT_I 000004
|
||||
#define PRINT_1 000010
|
||||
#define PRINT_2 000020
|
||||
#define PRINT_3 000040
|
||||
#define PRINT_4 000100
|
||||
#define PRINT_5 000200
|
||||
#define PRINT_6 000400
|
||||
#define PRINT_7 001000
|
||||
#define PRINT_8 002000
|
||||
#define PRINT_9 004000
|
||||
#define PRINT_10 010000
|
||||
#define PRINT_M 017770
|
||||
|
||||
/* Opcodes */
|
||||
#define OP_TXI 1
|
||||
#define OP_TIX 2
|
||||
#define OP_TXH 3
|
||||
#define OP_STR 5
|
||||
#define OP_TNX 6
|
||||
#define OP_TXL 7
|
||||
|
||||
/* Positive opcodes */
|
||||
#define OP_HTR 0000
|
||||
#define OP_TRA 0020
|
||||
#define OP_TTR 0021
|
||||
#define OP_TRCA 0022
|
||||
#define OP_TRCC 0024
|
||||
#define OP_TRCE 0026
|
||||
#define OP_TRCG 0027
|
||||
#define OP_TEFA 0030
|
||||
#define OP_TEFC 0031
|
||||
#define OP_TEFE 0032
|
||||
#define OP_TEFG 0033
|
||||
#define OP_TLQ 0040
|
||||
#define OP_IIA 0041
|
||||
#define OP_TIO 0042
|
||||
#define OP_OAI 0043
|
||||
#define OP_PAI 0044
|
||||
#define OP_TIF 0046
|
||||
#define OP_IIR 0051
|
||||
#define OP_RFT 0054
|
||||
#define OP_SIR 0055
|
||||
#define OP_RNT 0056
|
||||
#define OP_RIR 0057
|
||||
#define OP_TCOA 0060
|
||||
#define OP_TCOB 0061
|
||||
#define OP_TCOC 0062
|
||||
#define OP_TCOD 0063
|
||||
#define OP_TCOE 0064
|
||||
#define OP_TCOF 0065
|
||||
#define OP_TCOG 0066
|
||||
#define OP_TCOH 0067
|
||||
#define OP_TSX 0074
|
||||
#define OP_TZE 0100
|
||||
#define OP_TIA 0101
|
||||
#define OP_CVR 0114
|
||||
#define OP_TPL 0120
|
||||
#define OP_XCA 0131
|
||||
#define OP_TOV 0140
|
||||
#define OP_TQP 0162
|
||||
#define OP_TQO 0161
|
||||
#define OP_MPY 0200
|
||||
#define OP_VLM 0204
|
||||
#define OP_DVH 0220
|
||||
#define OP_DVP 0221
|
||||
#define OP_VDH 0224
|
||||
#define OP_VDP 0225
|
||||
#define OP_FDH 0240
|
||||
#define OP_FDP 0241
|
||||
#define OP_FMP 0260
|
||||
#define OP_DFMP 0261
|
||||
#define OP_FAD 0300
|
||||
#define OP_DFAD 0301
|
||||
#define OP_FSB 0302
|
||||
#define OP_DFSB 0303
|
||||
#define OP_FAM 0304
|
||||
#define OP_DFAM 0305
|
||||
#define OP_FSM 0306
|
||||
#define OP_DFSM 0307
|
||||
#define OP_ANS 0320
|
||||
#define OP_ERA 0322
|
||||
#define OP_CAS 0340
|
||||
#define OP_ACL 0361
|
||||
#define OP_HPR 0420
|
||||
#define OP_OSI 0442
|
||||
#define OP_ADD 0400
|
||||
#define OP_ADM 0401
|
||||
#define OP_SUB 0402
|
||||
#define OP_IIS 0440
|
||||
#define OP_LDI 0441
|
||||
#define OP_DLD 0443
|
||||
#define OP_OFT 0444
|
||||
#define OP_RIS 0445
|
||||
#define OP_ONT 0446
|
||||
#define OP_LDA 0460 /* 704 only */
|
||||
#define OP_CLA 0500
|
||||
#define OP_CLS 0502
|
||||
#define OP_ZET 0520
|
||||
#define OP_XEC 0522
|
||||
#define OP_LXA 0534
|
||||
#define OP_LAC 0535
|
||||
#define OP_RSCA 0540
|
||||
#define OP_RSCC 0541
|
||||
#define OP_RSCE 0542
|
||||
#define OP_RSCG 0543
|
||||
#define OP_STCA 0544
|
||||
#define OP_STCC 0545
|
||||
#define OP_STCE 0546
|
||||
#define OP_STCG 0547
|
||||
#define OP_LDQ 0560
|
||||
#define OP_ECA 0561
|
||||
#define OP_LRI 0562
|
||||
#define OP_ENB 0564
|
||||
#define OP_STZ 0600
|
||||
#define OP_STO 0601
|
||||
#define OP_SLW 0602
|
||||
#define OP_STI 0604
|
||||
#define OP_STA 0621
|
||||
#define OP_STD 0622
|
||||
#define OP_STT 0625
|
||||
#define OP_STP 0630
|
||||
#define OP_SXA 0634
|
||||
#define OP_SCA 0636
|
||||
#define OP_SCHA 0640
|
||||
#define OP_SCHC 0641
|
||||
#define OP_SCHE 0642
|
||||
#define OP_SCHG 0643
|
||||
#define OP_SCDA 0644
|
||||
#define OP_SCDC 0645
|
||||
#define OP_SCDE 0646
|
||||
#define OP_SCDG 0647
|
||||
#define OP_ELD 0670
|
||||
#define OP_EAD 0671
|
||||
#define OP_EDP 0672
|
||||
#define OP_EMP 0673
|
||||
#define OP_CPY 0700 /* 704 only */
|
||||
#define OP_PAX 0734
|
||||
#define OP_PAC 0737
|
||||
#define OP_PXA 0754
|
||||
#define OP_PCA 0756
|
||||
#define OP_NOP 0761
|
||||
#define OP_RDS 0762
|
||||
#define OP_LLS 0763
|
||||
#define OP_BSR 0764
|
||||
#define OP_LRS 0765
|
||||
#define OP_WRS 0766
|
||||
#define OP_ALS 0767
|
||||
#define OP_WEF 0770
|
||||
#define OP_ARS 0771
|
||||
#define OP_REW 0772
|
||||
#define OP_AXT 0774
|
||||
#define OP_DRS 0775
|
||||
#define OP_SDN 0776
|
||||
|
||||
/* Negative opcodes */
|
||||
#define OP_ESNT 04021
|
||||
#define OP_TRCB 04022
|
||||
#define OP_TRCD 04024
|
||||
#define OP_TRCF 04026
|
||||
#define OP_TRCH 04027
|
||||
#define OP_TEFB 04030
|
||||
#define OP_TEFD 04031
|
||||
#define OP_TEFF 04032
|
||||
#define OP_TEFH 04033
|
||||
#define OP_RIA 04042
|
||||
#define OP_PIA 04046
|
||||
#define OP_IIL 04051
|
||||
#define OP_LFT 04054
|
||||
#define OP_SIL 04055
|
||||
#define OP_LNT 04056
|
||||
#define OP_RIL 04057
|
||||
#define OP_TCNA 04060
|
||||
#define OP_TCNB 04061
|
||||
#define OP_TCNC 04062
|
||||
#define OP_TCND 04063
|
||||
#define OP_TCNE 04064
|
||||
#define OP_TCNF 04065
|
||||
#define OP_TCNG 04066
|
||||
#define OP_TCNH 04067
|
||||
#define OP_TNZ 04100
|
||||
#define OP_TIB 04101
|
||||
#define OP_CAQ 04114
|
||||
#define OP_TMI 04120
|
||||
#define OP_XCL 04130
|
||||
#define OP_TNO 04140
|
||||
#define OP_CRQ 04154
|
||||
#define OP_DUFA 04301
|
||||
#define OP_DUAM 04305
|
||||
#define OP_DUFS 04303
|
||||
#define OP_DUSM 04307
|
||||
#define OP_DUFM 04261
|
||||
#define OP_DFDH 04240
|
||||
#define OP_DFDP 04241
|
||||
#define OP_MPR 04200
|
||||
#define OP_UFM 04260
|
||||
#define OP_UFA 04300
|
||||
#define OP_UFS 04302
|
||||
#define OP_UAM 04304
|
||||
#define OP_USM 04306
|
||||
#define OP_ANA 04320
|
||||
#define OP_LAS 04340
|
||||
#define OP_SBM 04400
|
||||
#define OP_CAL 04500
|
||||
#define OP_ORA 04501
|
||||
#define OP_NZT 04520
|
||||
#define OP_LXD 04534
|
||||
#define OP_LDC 04535
|
||||
#define OP_RSCB 04540
|
||||
#define OP_RSCD 04541
|
||||
#define OP_RSCF 04542
|
||||
#define OP_RSCH 04543
|
||||
#define OP_STCB 04544
|
||||
#define OP_STCD 04545
|
||||
#define OP_STCF 04546
|
||||
#define OP_STCH 04547
|
||||
#define OP_ECQ 04561
|
||||
#define OP_LPI 04564
|
||||
#define OP_STQ 04600
|
||||
#define OP_SRI 04601
|
||||
#define OP_ORS 04602
|
||||
#define OP_DST 04603
|
||||
#define OP_SPI 04604
|
||||
#define OP_SLQ 04620
|
||||
#define OP_STL 04625
|
||||
#define OP_SCD 04636
|
||||
#define OP_SXD 04634
|
||||
#define OP_SCHB 04640
|
||||
#define OP_SCHD 04641
|
||||
#define OP_SCHF 04642
|
||||
#define OP_SCHH 04643
|
||||
#define OP_SCDB 04644
|
||||
#define OP_SCDD 04645
|
||||
#define OP_SCDF 04646
|
||||
#define OP_SCDH 04647
|
||||
#define OP_ESB 04671
|
||||
#define OP_EUA 04672
|
||||
#define OP_EST 04673
|
||||
#define OP_CAD 04700 /* 704 only */
|
||||
#define OP_PDX 04734
|
||||
#define OP_PDC 04737
|
||||
#define OP_PXD 04754
|
||||
#define OP_PCD 04756
|
||||
#define OP_SPOP 04761
|
||||
#define OP_LGL 04763
|
||||
#define OP_BSF 04764
|
||||
#define OP_LGR 04765
|
||||
#define OP_RUN 04772
|
||||
#define OP_RQL 04773
|
||||
#define OP_AXC 04774
|
||||
#define OP_TRS 04775
|
||||
|
||||
/* Positive 0760 opcodes */
|
||||
#define OP_CLM 000000
|
||||
#define OP_LBT 000001
|
||||
#define OP_CHS 000002
|
||||
#define OP_SSP 000003
|
||||
#define OP_ENK 000004
|
||||
#define OP_IOT 000005
|
||||
#define OP_COM 000006
|
||||
#define OP_ETM 000007
|
||||
#define OP_RND 000010
|
||||
#define OP_FRN 000011
|
||||
#define OP_DCT 000012
|
||||
#define OP_RCT 000014
|
||||
#define OP_LMTM 000016
|
||||
#define OP_RDCA 001352
|
||||
#define OP_RDCB 002352
|
||||
#define OP_RDCC 003352
|
||||
#define OP_RDCD 004352
|
||||
#define OP_RDCE 005352
|
||||
#define OP_RDCF 006352
|
||||
#define OP_RDCG 007352
|
||||
#define OP_RDCH 010352
|
||||
#define OP_RICA 001350
|
||||
#define OP_RICB 002350
|
||||
#define OP_RICC 003350
|
||||
#define OP_RICD 004350
|
||||
#define OP_RICE 005350
|
||||
#define OP_RICF 006350
|
||||
#define OP_RICG 007350
|
||||
#define OP_RICH 010350
|
||||
#define OP_SLF 000140
|
||||
#define OP_SLN1 000141
|
||||
#define OP_SLN2 000142
|
||||
#define OP_SLN3 000143
|
||||
#define OP_SLN4 000144
|
||||
#define OP_SLN5 000145
|
||||
#define OP_SLN6 000146
|
||||
#define OP_SLN7 000147
|
||||
#define OP_SLN8 000150
|
||||
#define OP_SWT1 000161
|
||||
#define OP_SWT2 000162
|
||||
#define OP_SWT3 000163
|
||||
#define OP_SWT4 000164
|
||||
#define OP_SWT5 000165
|
||||
#define OP_SWT6 000166
|
||||
#define OP_BTTA 001000
|
||||
#define OP_BTTB 002000
|
||||
#define OP_BTTC 003000
|
||||
#define OP_BTTD 004000
|
||||
#define OP_BTTE 005000
|
||||
#define OP_BTTF 006000
|
||||
#define OP_BTTG 007000
|
||||
#define OP_BTTH 010000
|
||||
#define OP_PSE 0
|
||||
|
||||
/* Negative 0760 opcodes */
|
||||
#define OP_ETTA 001000
|
||||
#define OP_ETTB 002000
|
||||
#define OP_ETTC 003000
|
||||
#define OP_ETTD 004000
|
||||
#define OP_ETTE 005000
|
||||
#define OP_ETTF 006000
|
||||
#define OP_ETTG 007000
|
||||
#define OP_ETTH 010000
|
||||
#define OP_PBT 000001
|
||||
#define OP_EFTM 000002
|
||||
#define OP_SSM 000003
|
||||
#define OP_LFTM 000004
|
||||
#define OP_ESTM 000005
|
||||
#define OP_ECTM 000006
|
||||
#define OP_LTM 000007
|
||||
#define OP_LSNM 000010
|
||||
#define OP_ETT 000011
|
||||
#define OP_RTT 000012
|
||||
#define OP_EMTM 000016
|
||||
#define OP_SLT1 000141
|
||||
#define OP_SLT2 000142
|
||||
#define OP_SLT3 000143
|
||||
#define OP_SLT4 000144
|
||||
#define OP_SLT5 000145
|
||||
#define OP_SLT6 000146
|
||||
#define OP_SLT7 000147
|
||||
#define OP_SLT8 000150
|
||||
#define OP_SWT7 000161
|
||||
#define OP_SWT8 000162
|
||||
#define OP_SWT9 000163
|
||||
#define OP_SWT10 000164
|
||||
#define OP_SWT11 000165
|
||||
#define OP_SWT12 000166
|
||||
#define OP_MSE 0
|
||||
|
||||
/* Special Ops -0761 */
|
||||
#define OP_SEA 000041
|
||||
#define OP_SEB 000042
|
||||
#define OP_IFT 000043
|
||||
#define OP_EFT 000044
|
||||
#define OP_ESM 000140
|
||||
#define OP_TSM 000141
|
||||
|
287
I7000/i7090_drum.c
Normal file
287
I7000/i7090_drum.c
Normal file
|
@ -0,0 +1,287 @@
|
|||
/* i7090_drum.c: IBM 7090 Drum
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This supports the direct channel and 704 type drums.
|
||||
|
||||
*/
|
||||
|
||||
#include "i7090_defs.h"
|
||||
|
||||
#ifdef NUM_DEVS_DR
|
||||
#define UNIT_DRM UNIT_ATTABLE | UNIT_DISABLE | UNIT_FIX | \
|
||||
UNIT_BUFABLE | UNIT_MUSTBUF
|
||||
|
||||
/* Device status information stored in u5 */
|
||||
#define DRMSTA_READ 000001 /* Unit is in read */
|
||||
#define DRMSTA_WRITE 000002 /* Unit is in write */
|
||||
#define DRMSTA_CMD 000004 /* Unit has recieved a cmd */
|
||||
#define DRMSTA_UNIT 000170 /* Unit mask */
|
||||
#define DRMSTA_UNITSHIFT 3
|
||||
#define DRMSTA_START 000200 /* Drum has started to transfer */
|
||||
#define DRMWORDTIME us_to_ticks(96) /* Number of cycles per drum word */
|
||||
#define DRMSIZE 2048 /* Number words per drum */
|
||||
#define DRMMASK (DRMSIZE-1)/* Mask of drum address */
|
||||
|
||||
uint32 drm_cmd(UNIT *, uint16, uint16);
|
||||
t_stat drm_srv(UNIT *);
|
||||
t_stat drm_boot(int32, DEVICE *);
|
||||
void drm_ini(UNIT *, t_bool);
|
||||
t_stat drm_reset(DEVICE *);
|
||||
extern t_stat chan_boot(int32, DEVICE *);
|
||||
uint32 drum_addr; /* Read/write drum address */
|
||||
t_stat set_units(UNIT * uptr, int32 val, CONST char *cptr,
|
||||
void *desc);
|
||||
t_stat drm_attach(UNIT * uptr, CONST char *file);
|
||||
t_stat drm_detach(UNIT * uptr);
|
||||
|
||||
t_stat get_units(FILE * st, UNIT * uptr, int32 v, CONST void *desc);
|
||||
t_stat drm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *drm_description (DEVICE *dptr);
|
||||
|
||||
|
||||
UNIT drm_unit[] = {
|
||||
{UDATA(&drm_srv, UNIT_S_CHAN(0) | UNIT_DRM, NUM_UNITS_DR * DRMSIZE), 0,
|
||||
NUM_UNITS_DR},
|
||||
};
|
||||
|
||||
MTAB drm_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "UNITS", "UNITS", &set_units,
|
||||
&get_units, NULL},
|
||||
#if NUM_CHAN != 1
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan, &get_chan,
|
||||
NULL},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE drm_dev = {
|
||||
"DR", drm_unit, NULL /* Registers */ , drm_mod,
|
||||
NUM_DEVS_DR, 8, 15, 1, 8, 36,
|
||||
NULL, NULL, &drm_reset, &drm_boot, &drm_attach, &drm_detach,
|
||||
&drm_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &drm_help, NULL, NULL, &drm_description
|
||||
};
|
||||
|
||||
uint32 drm_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = dev;
|
||||
|
||||
u -= drm_dib.addr;
|
||||
if (u > uptr->u3)
|
||||
return SCPE_NODEV;
|
||||
if ((uptr->flags & UNIT_ATT) != 0) {
|
||||
switch (cmd) {
|
||||
case IO_RDS:
|
||||
/* Start device */
|
||||
uptr->u5 = DRMSTA_READ | DRMSTA_CMD;
|
||||
sim_debug(DEBUG_CMD, &drm_dev, "RDS %o\n", dev);
|
||||
chan_set_sel(chan, 0);
|
||||
break;
|
||||
case IO_WRS:
|
||||
/* Start device */
|
||||
uptr->u5 = DRMSTA_WRITE | DRMSTA_CMD;
|
||||
sim_debug(DEBUG_CMD, &drm_dev, "WRS %o\n", dev);
|
||||
chan_set_sel(chan, 1);
|
||||
break;
|
||||
default:
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
/* Choose which part to use */
|
||||
uptr->u5 |= u << DRMSTA_UNITSHIFT;
|
||||
drum_addr = 0; /* Set drum address */
|
||||
chan_clear(chan, CHS_ATTN); /* Clear attentions */
|
||||
/* Make sure drum is spinning */
|
||||
sim_activate(uptr, us_to_ticks(100));
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
t_stat drm_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
t_uint64 *buf = (t_uint64*)uptr->filebuf;
|
||||
t_stat r;
|
||||
|
||||
uptr->u6++; /* Adjust rotation */
|
||||
uptr->u6 &= DRMMASK;
|
||||
/* Channel has disconnected, abort current read. */
|
||||
if (uptr->u5 & DRMSTA_CMD && chan_stat(chan, DEV_DISCO)) {
|
||||
uptr->u5 = 0;
|
||||
chan_clear(chan, DEV_WEOR | DEV_SEL | STA_ACTIVE);
|
||||
sim_debug(DEBUG_CHAN, &drm_dev, "Disconnect\n");
|
||||
}
|
||||
|
||||
/* Check if we have a address match */
|
||||
if ((chan_flags[chan] & (STA_ACTIVE | DEV_SEL)) == (STA_ACTIVE | DEV_SEL)
|
||||
&& (uptr->u5 & (DRMSTA_READ | DRMSTA_WRITE))
|
||||
&& (uint32)uptr->u6 == (drum_addr & DRMMASK)) {
|
||||
uint32 addr =
|
||||
(((uptr->u5 & DRMSTA_UNIT) >> DRMSTA_UNITSHIFT) << 11)
|
||||
+ (drum_addr & DRMMASK);
|
||||
|
||||
/* Try and transfer a word of data */
|
||||
if (uptr->u5 & DRMSTA_READ) {
|
||||
r = chan_write(chan, &buf[addr], DEV_DISCO);
|
||||
} else {
|
||||
if (addr >= uptr->hwmark)
|
||||
uptr->hwmark = (uint32)addr + 1;
|
||||
r = chan_read(chan, &buf[addr], DEV_DISCO);
|
||||
}
|
||||
switch (r) {
|
||||
case DATA_OK:
|
||||
sim_debug(DEBUG_DATA, &drm_dev, "loc %6o data %012llo\n", addr,
|
||||
buf[addr]);
|
||||
addr++;
|
||||
addr &= DRMMASK;
|
||||
drum_addr &= ~DRMMASK;
|
||||
drum_addr |= addr;
|
||||
break;
|
||||
|
||||
case END_RECORD:
|
||||
case TIME_ERROR:
|
||||
/* If no data, disconnect */
|
||||
sim_debug(DEBUG_DATA, &drm_dev, "loc %6o missed\n", addr);
|
||||
chan_clear(chan, STA_ACTIVE | DEV_SEL);
|
||||
uptr->u5 = DRMSTA_CMD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Increase delay for index time */
|
||||
if (uptr->u6 == 0)
|
||||
sim_activate(uptr, us_to_ticks(120));
|
||||
else
|
||||
sim_activate(uptr, DRMWORDTIME);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Boot from given device */
|
||||
t_stat
|
||||
drm_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
t_uint64 *buf = (t_uint64*)uptr->filebuf;
|
||||
int addr;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
/* Init for a read */
|
||||
if (drm_cmd(uptr, IO_RDS, 0301) != SCPE_OK)
|
||||
return STOP_IONRDY;
|
||||
/* Copy first three records. */
|
||||
addr = 0;
|
||||
M[0] = buf[addr++];
|
||||
M[1] = buf[addr++];
|
||||
drum_addr = 2;
|
||||
return chan_boot(unit_num, dptr);
|
||||
}
|
||||
|
||||
void
|
||||
drm_ini(UNIT * uptr, t_bool f)
|
||||
{
|
||||
uptr->u5 = 0;
|
||||
}
|
||||
|
||||
t_stat
|
||||
drm_reset(DEVICE * dptr)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Sets the number of drum units */
|
||||
t_stat
|
||||
set_units(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
return SCPE_ALATT;
|
||||
i = 0;
|
||||
while (*cptr != '\0') {
|
||||
if (*cptr < '0' || *cptr > '9')
|
||||
return SCPE_ARG;
|
||||
i = (i * 10) + (*cptr++) - '0';
|
||||
}
|
||||
if (i < 0 || i > NUM_UNITS_DR)
|
||||
return SCPE_ARG;
|
||||
uptr->capac = i * 2048;
|
||||
uptr->u3 = i;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
get_units(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "Units=%d", uptr->u3);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
drm_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = attach_unit(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
drm_detach(UNIT * uptr)
|
||||
{
|
||||
sim_cancel(uptr);
|
||||
return detach_unit(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
drm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
const char *cpu = cpu_description(&cpu_dev);
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
int ctype = dibp->ctype;
|
||||
|
||||
fprintf (st, "%s\n\n", drm_description(dptr));
|
||||
fprintf (st, "Up to %d units of drum could be used\n", NUM_UNITS_DR);
|
||||
fprintf (st, " sim> set %s UNITS=n to set number of units\n", dptr->name);
|
||||
help_set_chan_type(st, dptr, "Drums");
|
||||
fprintf (st, "Drums could be booted\n");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
drm_description (DEVICE *dptr)
|
||||
{
|
||||
return "IBM 704/709 Drum";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
253
I7000/i7090_hdrum.c
Normal file
253
I7000/i7090_hdrum.c
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* i7090_drum.c: IBM 7320A High Speed Drum
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
High speed drum for CTSS
|
||||
|
||||
*/
|
||||
|
||||
#include "i7090_defs.h"
|
||||
|
||||
#ifdef NUM_DEVS_HD
|
||||
#define UNIT_DRM UNIT_ATTABLE | UNIT_DISABLE | UNIT_FIX | \
|
||||
UNIT_BUFABLE | UNIT_MUSTBUF
|
||||
|
||||
/* Device status information stored in u5 */
|
||||
#define DRMSTA_READ 000001 /* Unit is in read */
|
||||
#define DRMSTA_WRITE 000002 /* Unit is in write */
|
||||
#define DRMSTA_START 000004 /* Which half of drum accessing */
|
||||
#define DRMSTA_CMD 000010 /* Unit has recieved a cmd */
|
||||
#define DRMSTA_UNIT 000700 /* Unitmask */
|
||||
#define DRMSTA_SHFT 6
|
||||
|
||||
uint32 hsdrm_cmd(UNIT *, uint16, uint16);
|
||||
t_stat hsdrm_srv(UNIT *);
|
||||
void hsdrm_ini(UNIT *, t_bool);
|
||||
t_stat hsdrm_reset(DEVICE *);
|
||||
t_uint64 hsdrm_addr; /* Read/write drum address */
|
||||
t_stat set_hunits(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat get_hunits(FILE * st, UNIT * uptr, int32 v, CONST void *desc);
|
||||
t_stat hsdrm_attach(UNIT * uptr, CONST char *file);
|
||||
t_stat hsdrm_detach(UNIT * uptr);
|
||||
t_stat hsdrm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *hsdrm_description (DEVICE *dptr);
|
||||
|
||||
|
||||
UNIT hsdrm_unit[] = {
|
||||
{UDATA (&hsdrm_srv, UNIT_S_CHAN(7) | UNIT_DRM,
|
||||
NUM_UNITS_HD * 8 * 32767), 0, NUM_UNITS_HD},
|
||||
};
|
||||
|
||||
MTAB hsdrm_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "UNITS", "UNITS",
|
||||
&set_hunits, &get_hunits, NULL},
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN",
|
||||
&set_chan, &get_chan, NULL},
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE hsdrm_dev = {
|
||||
"HD", hsdrm_unit, NULL /* Registers */ , hsdrm_mod,
|
||||
NUM_DEVS_HD, 8, 15, 1, 8, 36,
|
||||
NULL, NULL, &hsdrm_reset, NULL, &hsdrm_attach, &hsdrm_detach,
|
||||
&hsdrm_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &hsdrm_help, NULL, NULL, &hsdrm_description
|
||||
};
|
||||
|
||||
uint32 hsdrm_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) != 0) {
|
||||
/* Delay if transfer still in progress. */
|
||||
if (chan_active(chan))
|
||||
return SCPE_BUSY;
|
||||
/* Wait for device to time out */
|
||||
if (uptr->u5 & DRMSTA_CMD)
|
||||
return SCPE_BUSY;
|
||||
switch (cmd) {
|
||||
case IO_RDS:
|
||||
/* Start device */
|
||||
uptr->u5 = DRMSTA_READ | DRMSTA_CMD;
|
||||
chan_set_sel(chan, 0);
|
||||
sim_debug(DEBUG_CMD, &hsdrm_dev, "RDS dev %o\n", dev);
|
||||
break;
|
||||
case IO_WRS:
|
||||
/* Start device */
|
||||
uptr->hwmark = uptr->capac; /* Mark as changed */
|
||||
uptr->u5 = DRMSTA_WRITE | DRMSTA_CMD;
|
||||
chan_set_sel(chan, 1);
|
||||
sim_debug(DEBUG_CMD, &hsdrm_dev, "WRS dev %o\n", dev);
|
||||
break;
|
||||
default:
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
hsdrm_addr = 0; /* Set drum address */
|
||||
if (!sim_is_active(uptr))
|
||||
sim_activate(uptr, us_to_ticks(100));
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
t_stat hsdrm_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
t_uint64 *buf = (t_uint64 *)uptr->filebuf;
|
||||
t_stat r;
|
||||
|
||||
/* Channel has disconnected, abort current read. */
|
||||
if (uptr->u5 & DRMSTA_CMD && chan_stat(chan, DEV_DISCO)) {
|
||||
uptr->u5 = 0;
|
||||
chan_clear(chan, DEV_WEOR | DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, &hsdrm_dev, "disconnecting\n");
|
||||
sim_activate(uptr, us_to_ticks(50));
|
||||
}
|
||||
|
||||
uptr->u6++; /* Adjust rotation */
|
||||
uptr->u6 &= 007777;
|
||||
|
||||
/* Check if we have a address match */
|
||||
if ((chan_flags[chan] & (STA_ACTIVE | DEV_SEL)) == (STA_ACTIVE | DEV_SEL)
|
||||
&& uptr->u5 & (DRMSTA_READ | DRMSTA_WRITE)
|
||||
&& (uint32)uptr->u6 == (hsdrm_addr & 007777)) {
|
||||
int addr =
|
||||
((hsdrm_addr >> 12) & 07000000) |
|
||||
((hsdrm_addr >> 3) & 0700000) |
|
||||
(hsdrm_addr & 077777);
|
||||
sim_debug(DEBUG_DETAIL, &hsdrm_dev, "drum addr %o\n\r", addr);
|
||||
if (((addr >> 18) & 07) > uptr->u3) {
|
||||
chan_set(chan, DEV_REOR | CHS_ATTN | CHS_ERR);
|
||||
goto next;
|
||||
}
|
||||
/* Flag to disconnect without setting iocheck */
|
||||
if (uptr->u5 & DRMSTA_READ)
|
||||
r = chan_write(chan, &buf[addr], DEV_DISCO);
|
||||
else
|
||||
r = chan_read(chan, &buf[addr], DEV_DISCO);
|
||||
switch (r) {
|
||||
case DATA_OK:
|
||||
sim_debug(DEBUG_DATA, &hsdrm_dev,
|
||||
"transfer %s %o: %012llo\n\r",
|
||||
(uptr->u5 & DRMSTA_READ) ? "read" : "write",
|
||||
addr, buf[addr]);
|
||||
hsdrm_addr++;
|
||||
hsdrm_addr &= 070007077777LL;
|
||||
if ((hsdrm_addr & (2048 - 1)) == 0)
|
||||
chan_set(chan, DEV_REOR);
|
||||
break;
|
||||
|
||||
case END_RECORD:
|
||||
case TIME_ERROR:
|
||||
uptr->u5 = DRMSTA_CMD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
next:
|
||||
sim_activate(uptr, us_to_ticks(20));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void
|
||||
hsdrm_ini(UNIT * uptr, t_bool f)
|
||||
{
|
||||
uptr->u5 = 0;
|
||||
}
|
||||
|
||||
t_stat
|
||||
hsdrm_reset(DEVICE * dptr)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Sets the number of drum units */
|
||||
t_stat
|
||||
set_hunits(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
return SCPE_ALATT;
|
||||
i = 0;
|
||||
while (*cptr != '\0') {
|
||||
if (*cptr < '0' || *cptr > '9')
|
||||
return SCPE_ARG;
|
||||
i = (i * 10) + (*cptr++) - '0';
|
||||
}
|
||||
if (i < 0 || i > NUM_UNITS_HD)
|
||||
return SCPE_ARG;
|
||||
uptr->capac = i * 32767 * 8;
|
||||
uptr->u3 = i;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
get_hunits(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "Units=%d", uptr->u3);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
hsdrm_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = attach_unit(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
sim_activate(uptr, us_to_ticks(100));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
hsdrm_detach(UNIT * uptr)
|
||||
{
|
||||
sim_cancel(uptr);
|
||||
return detach_unit(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
hsdrm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "%s\n\n", hsdrm_description(dptr));
|
||||
fprintf (st, "The High speed drum supports up to %d units of storage\n", NUM_UNITS_HD);
|
||||
fprintf (st, "Each unit held 265k words of data\n");
|
||||
help_set_chan_type(st, dptr, "High speed drum");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
hsdrm_description (DEVICE *dptr)
|
||||
{
|
||||
return "IBM 7320A Drum for CTSS";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
696
I7000/i7090_lpr.c
Normal file
696
I7000/i7090_lpr.c
Normal file
|
@ -0,0 +1,696 @@
|
|||
/* i7090_lpr.c: IBM 7090 Standard line printer.
|
||||
|
||||
Copyright (c) 2005-2016, 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.
|
||||
|
||||
This is the standard line printer that all 70xx systems have.
|
||||
|
||||
For WRS read next 24 words and fill print buffer.
|
||||
Row 9, 8, 7, 6, 5, 4, 3, 2, 1, 10, 11, 12
|
||||
For RDS read rows 9, 8, 7, 6, 5, 4, 3, 2, 1,
|
||||
Echo 8|4
|
||||
read row 10
|
||||
Echo 8|3
|
||||
read row 11
|
||||
Echo 9
|
||||
read row 12
|
||||
Echo 8, 7, 6, 5, 4, 3, 2, 1
|
||||
|
||||
*/
|
||||
|
||||
#include "i7090_defs.h"
|
||||
#include "sim_console.h"
|
||||
#include "sim_card.h"
|
||||
|
||||
#ifdef NUM_DEVS_LPR
|
||||
|
||||
#define UNIT_LPR UNIT_ATTABLE | UNIT_DISABLE
|
||||
#define ECHO (1 << UNIT_V_LOCAL)
|
||||
|
||||
|
||||
/* std devices. data structures
|
||||
|
||||
chan_dev Channel device descriptor
|
||||
chan_unit Channel unit descriptor
|
||||
chan_reg Channel register list
|
||||
chan_mod Channel modifiers list
|
||||
*/
|
||||
|
||||
/* Output selection is stored in u3 */
|
||||
/* Line count is stored in u4 */
|
||||
/* Device status information stored in u5 */
|
||||
/* Position is stored in u6 */
|
||||
#define LPRSTA_RCMD 002000 /* Read command */
|
||||
#define LPRSTA_WCMD 004000 /* Write command */
|
||||
|
||||
#define LPRSTA_EOR 010000 /* Hit end of record */
|
||||
#define LPRSTA_BINMODE 020000 /* Line printer started in bin mode */
|
||||
#define LPRSTA_CHANGE 040000 /* Turn DEV_WRITE on */
|
||||
#define LPRSTA_COL72 0100000 /* Mask to last column printed */
|
||||
#define LPRSTA_IMAGE 0200000 /* Image to print */
|
||||
|
||||
|
||||
struct _lpr_data
|
||||
{
|
||||
t_uint64 wbuff[24]; /* Line buffer */
|
||||
char lbuff[74]; /* Output line buffer */
|
||||
}
|
||||
lpr_data[NUM_DEVS_LPR];
|
||||
|
||||
uint32 lpr_cmd(UNIT *, uint16, uint16);
|
||||
t_stat lpr_srv(UNIT *);
|
||||
void lpr_ini(UNIT *, t_bool);
|
||||
t_stat lpr_reset(DEVICE *);
|
||||
t_stat lpr_attach(UNIT *, CONST char *);
|
||||
t_stat lpr_detach(UNIT *);
|
||||
t_stat lpr_setlpp(UNIT *, int32, CONST char *, void *);
|
||||
t_stat lpr_getlpp(FILE *, UNIT *, int32, CONST void *);
|
||||
t_stat lpr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *lpr_description (DEVICE *dptr);
|
||||
|
||||
extern char six_to_ascii[64];
|
||||
|
||||
UNIT lpr_unit[] = {
|
||||
#if NUM_DEVS_LPR > 1
|
||||
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_A) | UNIT_LPR | ECHO, 55)}, /* A */
|
||||
#endif
|
||||
#if NUM_DEVS_LPR > 2
|
||||
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_C) | UNIT_LPR, 55)}, /* B */
|
||||
#endif
|
||||
#if NUM_DEVS_LPR > 3
|
||||
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_E) | UNIT_LPR | UNIT_DIS, 55)}, /* C */
|
||||
#endif
|
||||
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_CHPIO) | UNIT_LPR, 55)}, /* 704 */
|
||||
};
|
||||
|
||||
MTAB lpr_mod[] = {
|
||||
{ECHO, 0, NULL, "NOECHO", NULL, NULL, NULL, "Done echo to console"},
|
||||
{ECHO, ECHO, "ECHO", "ECHO", NULL, NULL, NULL, "Echo output to console"},
|
||||
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LINESPERPAGE", "LINESPERPAGE",
|
||||
&lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"},
|
||||
#if NUM_CHAN != 1
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
||||
&get_chan, NULL},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE lpr_dev = {
|
||||
"LP", lpr_unit, NULL, lpr_mod,
|
||||
NUM_DEVS_LPR, 8, 15, 1, 8, 36,
|
||||
NULL, NULL, &lpr_reset, NULL, &lpr_attach, &lpr_detach,
|
||||
&lpr_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &lpr_help, NULL, NULL, &lpr_description
|
||||
};
|
||||
|
||||
/* Line printer routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Line printer routines
|
||||
*/
|
||||
|
||||
t_stat
|
||||
lpr_setlpp(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int i;
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
i = 0;
|
||||
while(*cptr != '\0') {
|
||||
if (*cptr < '0' || *cptr > '9')
|
||||
return SCPE_ARG;
|
||||
i = (i * 10) + (*cptr++) - '0';
|
||||
}
|
||||
if (i < 20 || i > 100)
|
||||
return SCPE_ARG;
|
||||
uptr->capac = i;
|
||||
uptr->u4 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_getlpp(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
if (uptr == NULL)
|
||||
return SCPE_IERR;
|
||||
fprintf(st, "linesperpage=%d", uptr->capac);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
print_line(UNIT * uptr, int chan, int unit)
|
||||
{
|
||||
/* Convert word record into column image */
|
||||
/* Check output type, if auto or text, try and convert record to bcd first */
|
||||
/* If failed and text report error and dump what we have */
|
||||
/* Else if binary or not convertable, dump as image */
|
||||
|
||||
uint16 buff[80]; /* Temp conversion buffer */
|
||||
int i, j;
|
||||
int outsel = uptr->u3;
|
||||
int prt_flg = 1;
|
||||
|
||||
if ((uptr->flags & (UNIT_ATT | ECHO)) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
|
||||
if (outsel & PRINT_3) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
}
|
||||
uptr->u5 &= ~LPRSTA_COL72;
|
||||
uptr->u4++;
|
||||
}
|
||||
|
||||
if (outsel & PRINT_4) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n\r\n", 1, 4, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
}
|
||||
uptr->u5 &= ~LPRSTA_COL72;
|
||||
uptr->u4++;
|
||||
uptr->u4++;
|
||||
}
|
||||
|
||||
|
||||
/* Try to convert to text */
|
||||
memset(buff, 0, sizeof(buff));
|
||||
/* Bit flip into temp buffer */
|
||||
for (i = 0; i < 24; i++) {
|
||||
int bit = 1 << (i / 2);
|
||||
t_uint64 mask = 1;
|
||||
t_uint64 wd = 0;
|
||||
int b = 36 * (i & 1);
|
||||
int col;
|
||||
|
||||
wd = lpr_data[unit].wbuff[i];
|
||||
for (col = 35; col >= 0; mask <<= 1, col--) {
|
||||
if (wd & mask)
|
||||
buff[col + b] |= bit;
|
||||
}
|
||||
lpr_data[unit].wbuff[i] = 0;
|
||||
}
|
||||
|
||||
/* Space out printer based on last output */
|
||||
if ((outsel & PRINT_9)) {
|
||||
/* Trim trailing spaces */
|
||||
for (j = 72; j > 0 && lpr_data[unit].lbuff[j] == ' '; j--) ;
|
||||
j++;
|
||||
if ((uptr->u5 & LPRSTA_COL72) == 0)
|
||||
j = 0;
|
||||
|
||||
for (i = j; i < 72; i++) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite(" ", 1, 1, uptr->fileref);
|
||||
if (uptr->flags & ECHO)
|
||||
sim_putchar(' ');
|
||||
}
|
||||
} else {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\n\r", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
sim_putchar('\n');
|
||||
sim_putchar('\r');
|
||||
}
|
||||
uptr->u4++;
|
||||
uptr->u5 &= ~LPRSTA_COL72;
|
||||
}
|
||||
|
||||
/* Scan each column */
|
||||
for (i = 0; i < 72; i++) {
|
||||
int bcd = sim_hol_to_bcd(buff[i]);
|
||||
|
||||
if (bcd == 0x7f)
|
||||
lpr_data[unit].lbuff[i] = '{';
|
||||
else {
|
||||
if (bcd == 020)
|
||||
bcd = 10;
|
||||
if (uptr->u5 & LPRSTA_BINMODE) {
|
||||
char ch = (buff[i] != 0) ? '1' : ' ';
|
||||
lpr_data[unit].lbuff[i] = ch;
|
||||
} else
|
||||
lpr_data[unit].lbuff[i] = sim_six_to_ascii[bcd];
|
||||
}
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &lpr_dev, "WRS unit=%d %3o [%72s]\n", unit,
|
||||
outsel >> 3, &lpr_data[unit].lbuff[0]);
|
||||
|
||||
/* Trim trailing spaces */
|
||||
for (j = 71; j > 0 && lpr_data[unit].lbuff[j] == ' '; j--) ;
|
||||
|
||||
/* Print out buffer */
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite(lpr_data[unit].lbuff, 1, j+1, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
for(i = 0; i <= j; i++)
|
||||
sim_putchar(lpr_data[unit].lbuff[i]);
|
||||
}
|
||||
uptr->u5 |= LPRSTA_COL72;
|
||||
|
||||
/* Put output to column where we left off */
|
||||
if (outsel != 0) {
|
||||
uptr->u5 &= ~LPRSTA_COL72;
|
||||
}
|
||||
|
||||
/* Space printer */
|
||||
if (outsel & PRINT_2) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
}
|
||||
uptr->u4++;
|
||||
}
|
||||
|
||||
if (outsel & PRINT_1) {
|
||||
while (uptr->u4 < (int32)uptr->capac) {
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
sim_fwrite("\r\n", 1, 2, uptr->fileref);
|
||||
if (uptr->flags & ECHO) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
}
|
||||
uptr->u4++;
|
||||
}
|
||||
}
|
||||
|
||||
if (uptr->u4 >= (int32)uptr->capac) {
|
||||
uptr->u4 -= (int32)uptr->capac;
|
||||
dev_pulse[chan] |= PRINT_I;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint32 lpr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - lpr_unit);
|
||||
int i;
|
||||
|
||||
/* Check if valid */
|
||||
if ((dev & 03) == 0 || (dev & 03) == 3)
|
||||
return SCPE_NODEV;
|
||||
/* Check if attached */
|
||||
if ((uptr->flags & (UNIT_ATT | ECHO)) == 0) {
|
||||
chan_set_error(chan);
|
||||
sim_debug(DEBUG_EXP, &lpr_dev, "unit=%d not ready\n", u);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
/* Check if still active */
|
||||
if (uptr->u5 & URCSTA_CMD) {
|
||||
sim_debug(DEBUG_EXP, &lpr_dev, "unit=%d busy\n", u);
|
||||
return SCPE_BUSY;
|
||||
}
|
||||
/* Ok, issue command if correct */
|
||||
if (cmd == IO_WRS || cmd == IO_RDS) {
|
||||
/* Start device */
|
||||
if (((uptr->u5 & (URCSTA_ON | URCSTA_IDLE)) ==
|
||||
(URCSTA_ON | URCSTA_IDLE)) && uptr->wait <= 30) {
|
||||
uptr->wait += 85; /* Wait for next latch point */
|
||||
} else
|
||||
uptr->wait = 330; /* Startup delay */
|
||||
for (i = 0; i < 24; lpr_data[u].wbuff[i++] = 0) ;
|
||||
uptr->u6 = 0;
|
||||
uptr->u5 &= ~(LPRSTA_WCMD | LPRSTA_RCMD | URCSTA_WRITE | URCSTA_READ);
|
||||
uptr->u3 = 0;
|
||||
dev_pulse[chan] = 0;
|
||||
if (cmd == IO_WRS) {
|
||||
sim_debug(DEBUG_CMD, &lpr_dev, "WRS %o unit=%d %d\n", dev, u, uptr->wait);
|
||||
uptr->u5 |= LPRSTA_WCMD | URCSTA_CMD | URCSTA_WRITE;
|
||||
} else {
|
||||
sim_debug(DEBUG_CMD, &lpr_dev, "RDS %o unit=%d %d\n", dev, u, uptr->wait);
|
||||
uptr->u5 |= LPRSTA_RCMD | URCSTA_CMD | URCSTA_READ;
|
||||
}
|
||||
if ((dev & 03) == 2)
|
||||
uptr->u5 |= LPRSTA_BINMODE;
|
||||
else
|
||||
uptr->u5 &= ~LPRSTA_BINMODE;
|
||||
chan_set_sel(chan, 1);
|
||||
chan_clear_status(chan);
|
||||
sim_activate(uptr, us_to_ticks(1000)); /* activate */
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
chan_set_attn(chan);
|
||||
}
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
t_stat lpr_srv(UNIT * uptr)
|
||||
{
|
||||
int chan = UNIT_G_CHAN(uptr->flags);
|
||||
int u = (uptr - lpr_unit);
|
||||
int pos;
|
||||
int r;
|
||||
int eor = 0;
|
||||
|
||||
/* Channel has disconnected, abort current line. */
|
||||
if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) {
|
||||
print_line(uptr, chan, u);
|
||||
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_READ | URCSTA_CMD | LPRSTA_EOR | LPRSTA_CHANGE);
|
||||
uptr->u6 = 0;
|
||||
chan_clear(chan, DEV_WEOR | DEV_SEL);
|
||||
sim_debug(DEBUG_CHAN, &lpr_dev, "unit=%d disconnect\n", u);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* If change requested, do that first */
|
||||
if (uptr->u5 & LPRSTA_CHANGE) {
|
||||
/* Wait until word read by CPU or timeout */
|
||||
if (chan_test(chan, DEV_FULL)) {
|
||||
uptr->wait -= 50;
|
||||
if (uptr->wait == 50)
|
||||
uptr->u5 &= ~LPRSTA_CHANGE;
|
||||
sim_activate(uptr, us_to_ticks(100));
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
chan_set(chan, DEV_WRITE);
|
||||
sim_activate(uptr, uptr->wait);
|
||||
uptr->u5 &= ~LPRSTA_CHANGE;
|
||||
uptr->wait = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if we have timed out */
|
||||
if (uptr->wait != 0) {
|
||||
uptr->wait--;
|
||||
/* If at end of record and channel is still active, do another print */
|
||||
if (((uptr->u5 & (URCSTA_IDLE|URCSTA_CMD|URCSTA_WRITE|URCSTA_READ|
|
||||
URCSTA_ON)) == (URCSTA_IDLE|URCSTA_CMD|URCSTA_ON))
|
||||
&& uptr->wait == 1 && chan_test(chan, STA_ACTIVE)) {
|
||||
/* Restart same command */
|
||||
uptr->u5 |= (URCSTA_WRITE | URCSTA_READ) & (uptr->u5 >> 5);
|
||||
uptr->u6 = 0;
|
||||
chan_set(chan, DEV_WRITE);
|
||||
sim_debug(DEBUG_CHAN, &lpr_dev, "unit=%d restarting\n", u);
|
||||
}
|
||||
sim_activate(uptr, us_to_ticks(1000)); /* activate */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* If no request, go to idle mode */
|
||||
if ((uptr->u5 & (URCSTA_READ | URCSTA_WRITE)) == 0) {
|
||||
if ((uptr->u5 & (URCSTA_IDLE | URCSTA_ON)) == (URCSTA_IDLE | URCSTA_ON)) {
|
||||
uptr->wait = 85; /* Delay 85ms */
|
||||
uptr->u5 &= ~URCSTA_IDLE; /* Not running */
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
} else {
|
||||
uptr->wait = 330; /* Delay 330ms */
|
||||
uptr->u5 &= ~URCSTA_ON; /* Turn motor off */
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Motor is on and up to speed */
|
||||
uptr->u5 |= URCSTA_ON;
|
||||
uptr->u5 &= ~URCSTA_IDLE;
|
||||
pos = uptr->u6;
|
||||
|
||||
uptr->u3 |= dev_pulse[chan] & PRINT_M;
|
||||
|
||||
/* Check if he write out last data */
|
||||
if (uptr->u5 & URCSTA_READ) {
|
||||
int wrow = 0;
|
||||
t_uint64 wd = 0;
|
||||
int action = 0;
|
||||
|
||||
/* Case 0: Read word from MF memory, DEV_WRITE=1 */
|
||||
/* Case 1: Read word from MF memory, write echo back */
|
||||
/* Case 2: Write echoback, after gone switch to read */
|
||||
/* Case 3: Write echoback */
|
||||
/* Case 4: No update, DEV_WRITE=1 */
|
||||
eor = (uptr->u5 & LPRSTA_BINMODE) ? 1 : 0;
|
||||
switch (pos) {
|
||||
case 46:
|
||||
print_line(uptr, chan, u);
|
||||
pos = 0;
|
||||
/* Fall through */
|
||||
case 0:
|
||||
case 1: /* Row 9 */
|
||||
case 2:
|
||||
case 3: /* Row 8 */
|
||||
case 4:
|
||||
case 5: /* Row 7 */
|
||||
case 6:
|
||||
case 7: /* Row 6 */
|
||||
case 8:
|
||||
case 9: /* Row 5 */
|
||||
case 10:
|
||||
case 11: /* Row 4 */
|
||||
case 12:
|
||||
case 13: /* Row 3 */
|
||||
case 14:
|
||||
case 15: /* Row 2 */
|
||||
case 16: /* Row 1R */
|
||||
wrow = pos;
|
||||
break;
|
||||
case 17: /* Row 1L and start Echo */
|
||||
wrow = pos;
|
||||
action = 1;
|
||||
break;
|
||||
case 18: /* Echo 8-4 R */
|
||||
wd = lpr_data[u].wbuff[2];
|
||||
wd &= lpr_data[u].wbuff[10];
|
||||
action = 2;
|
||||
wrow = pos;
|
||||
break;
|
||||
case 19: /* Echo 8-4 L */
|
||||
wd = lpr_data[u].wbuff[3];
|
||||
wd &= lpr_data[u].wbuff[11];
|
||||
action = 3;
|
||||
wrow = pos;
|
||||
break;
|
||||
case 20: /* Row 10 R */
|
||||
wrow = 18;
|
||||
break;
|
||||
case 21: /* Row 10 L */
|
||||
wrow = 19;
|
||||
action = 1;
|
||||
break;
|
||||
case 22: /* Echo 8-3 */
|
||||
/* Fill for echo back */
|
||||
wd = lpr_data[u].wbuff[12];
|
||||
wd &= lpr_data[u].wbuff[2];
|
||||
action = 2;
|
||||
wrow = pos;
|
||||
break;
|
||||
case 23:
|
||||
wd = lpr_data[u].wbuff[13];
|
||||
wd &= lpr_data[u].wbuff[3];
|
||||
action = 3;
|
||||
wrow = pos;
|
||||
break;
|
||||
case 24: /* Row 11 R */
|
||||
wrow = 20;
|
||||
break;
|
||||
case 25: /* Row 11 L */
|
||||
wrow = 21;
|
||||
action = 1;
|
||||
break;
|
||||
case 26: /* Echo 9 */
|
||||
wd = lpr_data[u].wbuff[0];
|
||||
action = 2;
|
||||
wrow = pos;
|
||||
break;
|
||||
case 27:
|
||||
wd = lpr_data[u].wbuff[1];
|
||||
action = 3;
|
||||
wrow = pos;
|
||||
break;
|
||||
case 28:
|
||||
wrow = 22;
|
||||
break;
|
||||
case 29: /* Row 12 */
|
||||
wrow = 23;
|
||||
action = 1;
|
||||
break;
|
||||
case 45: /* Echo 1 */
|
||||
eor = 1;
|
||||
/* Fall through */
|
||||
|
||||
case 30:
|
||||
case 31: /* Echo 8 */
|
||||
case 32:
|
||||
case 33: /* Echo 7 */
|
||||
case 34:
|
||||
case 35: /* Echo 6 */
|
||||
case 36:
|
||||
case 37: /* Echo 5 */
|
||||
case 38:
|
||||
case 39: /* Echo 4 */
|
||||
case 40:
|
||||
case 41: /* Echo 3 */
|
||||
case 42:
|
||||
case 43: /* Echo 2 */
|
||||
case 44: /* Echo 1 */
|
||||
wrow = pos - 28;
|
||||
wd = lpr_data[u].wbuff[wrow];
|
||||
action = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (action == 0 || action == 1) {
|
||||
/* If reading grab next word */
|
||||
r = chan_read(chan, &lpr_data[u].wbuff[wrow], 0);
|
||||
sim_debug(DEBUG_DATA, &lpr_dev, "print read row < %d %d %012llo eor=%d\n",
|
||||
pos, wrow, lpr_data[u].wbuff[wrow], 0);
|
||||
if (action == 1)
|
||||
chan_clear(chan, DEV_WRITE);
|
||||
} else { /* action == 2 || action == 3 */
|
||||
/* Place echo data in buffer */
|
||||
sim_debug(DEBUG_DATA, &lpr_dev, "print read row > %d %d %012llo eor=%d\n",
|
||||
pos, wrow, wd, eor);
|
||||
r = chan_write(chan, &wd, 0);
|
||||
/* Change back to reading */
|
||||
if (action == 3) {
|
||||
uptr->wait = 650;
|
||||
uptr->u6 = ++pos;
|
||||
uptr->u5 &= ~(LPRSTA_EOR);
|
||||
uptr->u5 |= LPRSTA_CHANGE;
|
||||
sim_activate(uptr, us_to_ticks(100));
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eor = (pos == 23 || (uptr->u5 & LPRSTA_BINMODE && pos == 1)) ? 1 : 0;
|
||||
if (pos == 24 || (uptr->u5 & LPRSTA_BINMODE && pos == 2)) {
|
||||
print_line(uptr, chan, u);
|
||||
pos = 0;
|
||||
}
|
||||
r = chan_read(chan, &lpr_data[u].wbuff[pos], 0);
|
||||
sim_debug(DEBUG_DATA, &lpr_dev, "print row %d %012llo %d\n", pos,
|
||||
lpr_data[u].wbuff[pos], eor);
|
||||
}
|
||||
|
||||
uptr->u6 = pos + 1;
|
||||
switch (r) {
|
||||
case END_RECORD:
|
||||
uptr->wait = 100; /* Print wheel gap */
|
||||
uptr->u5 |= LPRSTA_EOR | URCSTA_IDLE;
|
||||
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_READ);
|
||||
chan_set(chan, DEV_REOR);
|
||||
break;
|
||||
case DATA_OK:
|
||||
if (eor) {
|
||||
uptr->wait = 100; /* Print wheel gap */
|
||||
uptr->u5 |= LPRSTA_EOR | URCSTA_IDLE;
|
||||
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_READ);
|
||||
chan_set(chan, DEV_REOR);
|
||||
} else {
|
||||
uptr->wait = 0;
|
||||
uptr->u5 &= ~(LPRSTA_EOR);
|
||||
sim_activate(uptr, (pos & 1) ? us_to_ticks(500) : us_to_ticks(16000));
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
case TIME_ERROR:
|
||||
chan_set_attn(chan);
|
||||
chan_set(chan, DEV_REOR);
|
||||
uptr->wait = 13 * (12 - (pos / 2)) + 85;
|
||||
uptr->u5 &= ~(URCSTA_READ | URCSTA_WRITE);
|
||||
uptr->u5 |= URCSTA_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
sim_activate(uptr, us_to_ticks(1000));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void
|
||||
lpr_ini(UNIT * uptr, t_bool f)
|
||||
{
|
||||
int u = (uptr - lpr_unit);
|
||||
|
||||
uptr->u3 = 0;
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
memset(&lpr_data[u].lbuff, ' ', sizeof(lpr_data[u].lbuff));
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_reset(DEVICE * dptr)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if ((r = attach_unit(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u5 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_detach(UNIT * uptr)
|
||||
{
|
||||
int u = (uptr - lpr_unit);
|
||||
|
||||
return detach_unit(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
const char *cpu = cpu_description(&cpu_dev);
|
||||
extern void fprint_attach_help_ex (FILE *st, DEVICE *dptr, t_bool silent);
|
||||
|
||||
fprintf (st, "%s\n\n", lpr_description(dptr));
|
||||
#if NUM_DEVS_LPR > 3
|
||||
fprintf (st, "The %s supports up to four line printers", cpu);
|
||||
#elif NUM_DEVS_LPR > 2
|
||||
fprintf (st, "The %s supports up to three line printers", cpu);
|
||||
#elif NUM_DEVS_LPR > 1
|
||||
fprintf (st, "The %s supports up to two line printers", cpu);
|
||||
#elif NUM_DEVS_LPR > 0
|
||||
fprintf (st, "The %s supports one line printer", cpu);
|
||||
#endif
|
||||
fprintf (st, "by default. The Line printer can\n");
|
||||
fprintf (st, "The printer acted as the console printer:\n\n");
|
||||
fprintf (st, " sim> SET %s ECHO\n\n", dptr->name);
|
||||
fprintf (st, "Causes all output sent to printer to also go to console.\n");
|
||||
help_set_chan_type(st, dptr, "Line printers");
|
||||
fprint_set_help(st, dptr);
|
||||
fprint_show_help(st, dptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
lpr_description(DEVICE *dptr)
|
||||
{
|
||||
return "716 Line Printer";
|
||||
}
|
||||
|
||||
|
||||
#endif
|
1056
I7000/i7090_sys.c
Normal file
1056
I7000/i7090_sys.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -21,7 +21,9 @@
|
|||
|
||||
#### Gerardo Ospina has implemented a Manchester University SSEM (Small Scale Experimental Machine) simulator.
|
||||
|
||||
#### Richard Cornwell has implemented a Burroughs B5500 simulator.
|
||||
#### Richard Cornwell has implemented a Burroughs B5500.
|
||||
|
||||
#### Richard Cornwell has implemented the IBM 701, IBM 704, IBM 7010/1410, IBM 7070/7074, IBM 7080/702/705/7053 and IBM 7090/7094/709/704 simulators.
|
||||
|
||||
#### Dave Bryan has implemented an HP-3000 Series III simulator.
|
||||
|
||||
|
|
351
Visual Studio Projects/I701.vcproj
Normal file
351
Visual Studio Projects/I701.vcproj
Normal file
|
@ -0,0 +1,351 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="I701"
|
||||
ProjectGUID="{F1F44607-FB9E-428C-AD8F-56F98699D121}"
|
||||
RootNamespace="I701"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I701;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I701;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="false"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_mt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i701_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i701_cpu.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i701_sys.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cdp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cdr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_drum.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_lpr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_rev.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
367
Visual Studio Projects/I7010.vcproj
Normal file
367
Visual Studio Projects/I7010.vcproj
Normal file
|
@ -0,0 +1,367 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="I7010"
|
||||
ProjectGUID="{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}"
|
||||
RootNamespace="I7010"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7010;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7010;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="false"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_cdp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_cdr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chron.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_com.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_con.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_dsk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_ht.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_lpr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_mt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7010_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7010_cpu.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7010_sys.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7010_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_rev.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
351
Visual Studio Projects/I704.vcproj
Normal file
351
Visual Studio Projects/I704.vcproj
Normal file
|
@ -0,0 +1,351 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="I704"
|
||||
ProjectGUID="{91A7D475-1238-4872-BEAE-143E1FCEA297}"
|
||||
RootNamespace="I704"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I704;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I704;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="false"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_mt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cdp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cdr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cpu.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_drum.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_lpr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_sys.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_rev.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
367
Visual Studio Projects/I7070.vcproj
Normal file
367
Visual Studio Projects/I7070.vcproj
Normal file
|
@ -0,0 +1,367 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="I7070"
|
||||
ProjectGUID="{F55D43D3-AD63-4B19-B67A-47064227F3E3}"
|
||||
RootNamespace="I7070"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7070;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7070;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="false"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_cdp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_cdr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chron.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_com.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_con.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_dsk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_ht.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_lpr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_mt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7070_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7070_cpu.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7070_sys.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7070_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_rev.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
371
Visual Studio Projects/I7080.vcproj
Normal file
371
Visual Studio Projects/I7080.vcproj
Normal file
|
@ -0,0 +1,371 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="I7080"
|
||||
ProjectGUID="{BF1E708D-D374-4DE1-A0D3-6D8DB4B4F7FA}"
|
||||
RootNamespace="I7080"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7080;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7080;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="false"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_cdp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_cdr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chron.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_com.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_con.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_dsk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_ht.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_lpr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_mt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7080_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7080_cpu.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7080_drum.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7080_sys.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7080_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_rev.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
371
Visual Studio Projects/I7090.vcproj
Normal file
371
Visual Studio Projects/I7090.vcproj
Normal file
|
@ -0,0 +1,371 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="I7090"
|
||||
ProjectGUID="{33EE34FC-A12F-47FE-9FD6-8B74D08718C7}"
|
||||
RootNamespace="I7090"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7090;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Check for required build dependencies & git commit id"
|
||||
CommandLine="Pre-Build-Event.cmd LIBPCRE"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="./;../;../../windows-build/PCRE/include/"
|
||||
PreprocessorDefinitions="I7090;USE_INT64;USE_SIM_CARD;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
|
||||
GenerateDebugInformation="false"
|
||||
SubSystem="1"
|
||||
StackReserveSize="10485760"
|
||||
StackCommitSize="10485760"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_chron.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_com.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_dsk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_ht.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_mt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cdp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cdr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_chan.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_cpu.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_drum.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_hdrum.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_lpr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_sys.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\I7000\i7000_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\I7000\i7090_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scp.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_card.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_console.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_defs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_disk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_ether.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_fio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_rev.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_serial.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_sock.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_tmxr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sim_video.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -259,6 +259,33 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2", "3B2.vcproj", "{56178
|
|||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I701", "I701.vcproj", "{F1F44607-FB9E-428C-AD8F-56F98699D121}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I7090", "I7090.vcproj", "{33EE34FC-A12F-47FE-9FD6-8B74D08718C7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I704", "I704.vcproj", "{91A7D475-1238-4872-BEAE-143E1FCEA297}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I7080", "I7080.vcproj", "{BF1E708D-D374-4DE1-A0D3-6D8DB4B4F7FA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I7070", "I7070.vcproj", "{F55D43D3-AD63-4B19-B67A-47064227F3E3}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I7010", "I7010.vcproj", "{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -481,6 +508,30 @@ Global
|
|||
{56178F08-8783-4ADA-820C-20C06412678E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{56178F08-8783-4ADA-820C-20C06412678E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{56178F08-8783-4ADA-820C-20C06412678E}.Release|Win32.Build.0 = Release|Win32
|
||||
{F1F44607-FB9E-428C-AD8F-56F98699D121}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F1F44607-FB9E-428C-AD8F-56F98699D121}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F1F44607-FB9E-428C-AD8F-56F98699D121}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F1F44607-FB9E-428C-AD8F-56F98699D121}.Release|Win32.Build.0 = Release|Win32
|
||||
{33EE34FC-A12F-47FE-9FD6-8B74D08718C7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{33EE34FC-A12F-47FE-9FD6-8B74D08718C7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{33EE34FC-A12F-47FE-9FD6-8B74D08718C7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{33EE34FC-A12F-47FE-9FD6-8B74D08718C7}.Release|Win32.Build.0 = Release|Win32
|
||||
{91A7D475-1238-4872-BEAE-143E1FCEA297}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{91A7D475-1238-4872-BEAE-143E1FCEA297}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{91A7D475-1238-4872-BEAE-143E1FCEA297}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{91A7D475-1238-4872-BEAE-143E1FCEA297}.Release|Win32.Build.0 = Release|Win32
|
||||
{BF1E708D-D374-4DE1-A0D3-6D8DB4B4F7FA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BF1E708D-D374-4DE1-A0D3-6D8DB4B4F7FA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BF1E708D-D374-4DE1-A0D3-6D8DB4B4F7FA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BF1E708D-D374-4DE1-A0D3-6D8DB4B4F7FA}.Release|Win32.Build.0 = Release|Win32
|
||||
{F55D43D3-AD63-4B19-B67A-47064227F3E3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F55D43D3-AD63-4B19-B67A-47064227F3E3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F55D43D3-AD63-4B19-B67A-47064227F3E3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F55D43D3-AD63-4B19-B67A-47064227F3E3}.Release|Win32.Build.0 = Release|Win32
|
||||
{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
BIN
doc/i7010_doc.doc
Normal file
BIN
doc/i7010_doc.doc
Normal file
Binary file not shown.
BIN
doc/i701_doc.doc
Normal file
BIN
doc/i701_doc.doc
Normal file
Binary file not shown.
BIN
doc/i7070_doc.doc
Normal file
BIN
doc/i7070_doc.doc
Normal file
Binary file not shown.
BIN
doc/i7080_doc.doc
Normal file
BIN
doc/i7080_doc.doc
Normal file
Binary file not shown.
BIN
doc/i7090_doc.doc
Normal file
BIN
doc/i7090_doc.doc
Normal file
Binary file not shown.
83
makefile
83
makefile
|
@ -1309,6 +1309,51 @@ I1620 = ${I1620D}/i1620_cd.c ${I1620D}/i1620_dp.c ${I1620D}/i1620_pt.c \
|
|||
${I1620D}/i1620_fp.c ${I1620D}/i1620_sys.c
|
||||
I1620_OPT = -I ${I1620D}
|
||||
|
||||
I7000D = I7000
|
||||
I7090 = ${I7000D}/i7090_cpu.c ${I7000D}/i7090_sys.c ${I7000D}/i7090_chan.c \
|
||||
${I7000D}/i7090_cdr.c ${I7000D}/i7090_cdp.c ${I7000D}/i7090_lpr.c \
|
||||
${I7000D}/i7000_chan.c ${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c \
|
||||
${I7000D}/i7090_hdrum.c ${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c \
|
||||
${I7000D}/i7000_com.c ${I7000D}/i7000_ht.c
|
||||
I7090_OPT = -I $(I7000D) -DUSE_INT64 -DI7090 -DUSE_SIM_CARD
|
||||
|
||||
I7080D = I7000
|
||||
I7080 = ${I7000D}/i7080_cpu.c ${I7000D}/i7080_sys.c ${I7000D}/i7080_chan.c \
|
||||
${I7000D}/i7080_drum.c ${I7000D}/i7000_cdp.c ${I7000D}/i7000_cdr.c \
|
||||
${I7000D}/i7000_con.c ${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c \
|
||||
${I7000D}/i7000_mt.c ${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c \
|
||||
${I7000D}/i7000_com.c ${I7000D}/i7000_ht.c
|
||||
I7080_OPT = -I $(I7000D) -DI7080 -DUSE_SIM_CARD
|
||||
|
||||
I7070D = I7000
|
||||
I7070 = ${I7000D}/i7070_cpu.c ${I7000D}/i7070_sys.c ${I7000D}/i7070_chan.c \
|
||||
${I7000D}/i7000_cdp.c ${I7000D}/i7000_cdr.c ${I7000D}/i7000_con.c \
|
||||
${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c ${I7000D}/i7000_mt.c \
|
||||
${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c ${I7000D}/i7000_com.c \
|
||||
${I7000D}/i7000_ht.c
|
||||
I7070_OPT = -I $(I7000D) -DUSE_INT64 -DI7070 -DUSE_SIM_CARD
|
||||
|
||||
I7010D = I7000
|
||||
I7010 = ${I7000D}/i7010_cpu.c ${I7000D}/i7010_sys.c ${I7000D}/i7010_chan.c \
|
||||
${I7000D}/i7000_cdp.c ${I7000D}/i7000_cdr.c ${I7000D}/i7000_con.c \
|
||||
${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c ${I7000D}/i7000_mt.c \
|
||||
${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c ${I7000D}/i7000_com.c \
|
||||
${I7000D}/i7000_ht.c
|
||||
I7010_OPT = -I $(I7010D) -DI7010 -DUSE_SIM_CARD
|
||||
|
||||
I704D = I7000
|
||||
I704 = ${I7000D}/i7090_cpu.c ${I7000D}/i7090_sys.c ${I7000D}/i7090_chan.c \
|
||||
${I7000D}/i7090_cdr.c ${I7000D}/i7090_cdp.c ${I7000D}/i7090_lpr.c \
|
||||
${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c ${I7000D}/i7000_chan.c
|
||||
I704_OPT = -I $(I7000D) -DUSE_INT64 -DI704 -DUSE_SIM_CARD
|
||||
|
||||
|
||||
I701D = I7000
|
||||
I701 = ${I7000D}/i701_cpu.c ${I7000D}/i701_sys.c ${I7000D}/i701_chan.c \
|
||||
${I7000D}/i7090_cdr.c ${I7000D}/i7090_cdp.c ${I7000D}/i7090_lpr.c \
|
||||
${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c ${I7000D}/i7000_chan.c
|
||||
I701_OPT = -I $(I7000D) -DUSE_INT64 -DI701 -DUSE_SIM_CARD
|
||||
|
||||
|
||||
I7094D = I7094
|
||||
I7094 = ${I7094D}/i7094_cpu.c ${I7094D}/i7094_cpu1.c ${I7094D}/i7094_io.c \
|
||||
|
@ -1622,7 +1667,7 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
|
|||
nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \
|
||||
i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \
|
||||
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 \
|
||||
isys8030 isys8024 imds-225 scelbi 3b2
|
||||
isys8030 isys8024 imds-225 scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090
|
||||
|
||||
all : ${ALL}
|
||||
|
||||
|
@ -2006,6 +2051,42 @@ ${BIN}3b2${EXE} : ${ATT3B2} ${SIM} ${BUILD_ROMS}
|
|||
${MKDIRBIN}
|
||||
${CC} ${ATT3B2} ${SIM} ${ATT3B2_OPT} $(CC_OUTSPEC) ${LDFLAGS}
|
||||
|
||||
i7090 : $(BIN)i7090$(EXE)
|
||||
|
||||
${BIN}i7090${EXE} : ${I7090} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${I7090} ${SIM} ${I7090_OPT} $(CC_OUTSPEC) ${LDFLAGS}
|
||||
|
||||
i7080 : $(BIN)i7080$(EXE)
|
||||
|
||||
${BIN}i7080${EXE} : ${I7080} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${I7080} ${SIM} ${I7080_OPT} $(CC_OUTSPEC) ${LDFLAGS}
|
||||
|
||||
i7070 : $(BIN)i7070$(EXE)
|
||||
|
||||
${BIN}i7070${EXE} : ${I7070} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${I7070} ${SIM} ${I7070_OPT} $(CC_OUTSPEC) ${LDFLAGS}
|
||||
|
||||
i7010 : $(BIN)i7010$(EXE)
|
||||
|
||||
${BIN}i7010${EXE} : ${I7010} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${I7010} ${SIM} ${I7010_OPT} $(CC_OUTSPEC) ${LDFLAGS}
|
||||
|
||||
i704 : $(BIN)i704$(EXE)
|
||||
|
||||
${BIN}i704${EXE} : ${I704} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${I704} ${SIM} ${I704_OPT} $(CC_OUTSPEC) ${LDFLAGS}
|
||||
|
||||
i701 : $(BIN)i701$(EXE)
|
||||
|
||||
${BIN}i701${EXE} : ${I701} ${SIM}
|
||||
${MKDIRBIN}
|
||||
${CC} ${I701} ${SIM} ${I701_OPT} $(CC_OUTSPEC) ${LDFLAGS}
|
||||
|
||||
# Front Panel API Demo/Test program
|
||||
|
||||
frontpaneltest : ${BIN}frontpaneltest${EXE}
|
||||
|
|
Loading…
Add table
Reference in a new issue