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:
Richard Cornwell 2017-12-28 05:05:25 -08:00 committed by Mark Pizzolato
parent e78ef46ccb
commit b5ea9ec38e
51 changed files with 40064 additions and 2 deletions

54
I7000/README.md Normal file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

279
I7000/i7000_con.c Normal file
View 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
View 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

File diff suppressed because it is too large Load diff

992
I7000/i7000_ht.c Normal file
View 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
View 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

File diff suppressed because it is too large Load diff

727
I7000/i7010_chan.c Normal file
View 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

File diff suppressed because it is too large Load diff

133
I7000/i7010_defs.h Normal file
View 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

File diff suppressed because it is too large Load diff

416
I7000/i701_chan.c Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

3001
I7000/i7070_cpu.c Normal file

File diff suppressed because it is too large Load diff

241
I7000/i7070_defs.h Normal file
View 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

File diff suppressed because it is too large Load diff

1250
I7000/i7080_chan.c Normal file

File diff suppressed because it is too large Load diff

3426
I7000/i7080_cpu.c Normal file

File diff suppressed because it is too large Load diff

103
I7000/i7080_defs.h Normal file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

4435
I7000/i7090_cpu.c Normal file

File diff suppressed because it is too large Load diff

437
I7000/i7090_defs.h Normal file
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

View file

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

View 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 &amp; 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 &amp; 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>

View 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 &amp; 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 &amp; 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>

View 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 &amp; 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 &amp; 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>

View 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 &amp; 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 &amp; 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>

View 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 &amp; 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 &amp; 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>

View 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 &amp; 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 &amp; 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>

View file

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

Binary file not shown.

BIN
doc/i701_doc.doc Normal file

Binary file not shown.

BIN
doc/i7070_doc.doc Normal file

Binary file not shown.

BIN
doc/i7080_doc.doc Normal file

Binary file not shown.

BIN
doc/i7090_doc.doc Normal file

Binary file not shown.

View file

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