mirror of
https://github.com/rcornwell/sims.git
synced 2026-04-29 05:06:42 +00:00
IBM360: Added help and comments.
This commit is contained in:
@@ -83,15 +83,17 @@ 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 *);
|
||||
|
||||
UNIT cdp_unit[] = {
|
||||
{UDATA(cdp_srv, UNIT_CDP, 0), 600, UNIT_ADDR(0x00D) }, /* A */
|
||||
{UDATA(cdp_srv, UNIT_CDP, 0), 600, UNIT_ADDR(0x00D) },
|
||||
#if NUM_DEVS_CDP > 1
|
||||
{UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x01D)}, /* A */
|
||||
{UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x01D)},
|
||||
#if NUM_DEVS_CDP > 2
|
||||
{UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x40D)}, /* A */
|
||||
{UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x40D)},
|
||||
#if NUM_DEVS_CDP > 3
|
||||
{UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x41D)}, /* A */
|
||||
{UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x41D)},
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
@@ -112,19 +114,17 @@ 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_UADDR | DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug
|
||||
&cdp_dib, DEV_UADDR | DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug,
|
||||
NULL, NULL, &cdp_help, NULL, NULL, &cdp_description
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* Card punch routine
|
||||
/*
|
||||
* Start the card punch to punch one card.
|
||||
*/
|
||||
|
||||
Modifiers have been checked by the caller
|
||||
C modifier is recognized (column binary is implemented)
|
||||
*/
|
||||
|
||||
|
||||
uint8 cdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
@@ -253,5 +253,21 @@ cdp_detach(UNIT * uptr)
|
||||
uptr->up7 = 0;
|
||||
return sim_card_detach(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "2540P Card Punch\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 *
|
||||
cdp_description(DEVICE *dptr)
|
||||
{
|
||||
return "2540P Card Punch";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -83,17 +83,18 @@ t_stat cdr_srv(UNIT *);
|
||||
t_stat cdr_reset(DEVICE *);
|
||||
t_stat cdr_attach(UNIT *, CONST char *);
|
||||
t_stat cdr_detach(UNIT *);
|
||||
|
||||
t_stat cdr_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *cdr_description(DEVICE *);
|
||||
|
||||
|
||||
UNIT cdr_unit[] = {
|
||||
{UDATA(cdr_srv, UNIT_CDR, 0), 300, UNIT_ADDR(0x0C)}, /* A */
|
||||
{UDATA(cdr_srv, UNIT_CDR, 0), 300, UNIT_ADDR(0x0C)},
|
||||
#if NUM_DEVS_CDR > 1
|
||||
{UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x1C)}, /* B */
|
||||
{UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x1C)},
|
||||
#if NUM_DEVS_CDR > 2
|
||||
{UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x40C)}, /* B */
|
||||
{UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x40C)},
|
||||
#if NUM_DEVS_CDR > 3
|
||||
{UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x41C)}, /* B */
|
||||
{UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x41C)},
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
@@ -117,6 +118,9 @@ DEVICE cdr_dev = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Start card reader to read in one card.
|
||||
*/
|
||||
uint8 cdr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
@@ -291,5 +295,19 @@ cdr_detach(UNIT * uptr)
|
||||
return sim_card_detach(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "2540R Card Reader\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 *
|
||||
cdr_description(DEVICE *dptr)
|
||||
{
|
||||
return "2540R Card Reader";
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -215,7 +215,7 @@ readbuff(int chan) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
return 1;
|
||||
}
|
||||
if ((ccw_cmd[chan] & CMD_TYPE) == CMD_WRITE) {
|
||||
if ((ccw_cmd[chan] & 1) == 1) {
|
||||
sim_debug(DEBUG_CDATA, &cpu_dev, "Channel write %02x %06x %08x %08x '",
|
||||
chan, addr, chan_buf[chan], ccw_count[chan]);
|
||||
for(k = 24; k >= 0; k -= 8) {
|
||||
@@ -379,7 +379,7 @@ loop:
|
||||
chan_status[chan] |= STATUS_PCI;
|
||||
ccw_flags[chan] &= ~FLAG_PCI;
|
||||
irq_pend = 1;
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "Set PCI %02x\n", chan);
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "Set PCI %02x load\n", chan);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -615,13 +615,17 @@ chan_end(uint16 addr, uint8 flags) {
|
||||
if (chan < 0)
|
||||
return;
|
||||
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x, %x) %x\n", addr, flags, ccw_count[chan]);
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x, %x) %x %04x %04x\n", addr, flags,
|
||||
ccw_count[chan], ccw_flags[chan], chan_status[chan]);
|
||||
#if 0
|
||||
/* If PCI flag set, trigger interrupt */
|
||||
if (ccw_flags[chan] & FLAG_PCI) {
|
||||
chan_status[chan] |= STATUS_PCI;
|
||||
ccw_flags[chan] &= ~FLAG_PCI;
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "Set PCI %02x end\n", chan);
|
||||
irq_pend = 1;
|
||||
}
|
||||
#endif
|
||||
/* Flush buffer if there was any change */
|
||||
if (chan_byte[chan] & BUFF_DIRTY) {
|
||||
(void)(writebuff(chan));
|
||||
@@ -648,6 +652,8 @@ chan_end(uint16 addr, uint8 flags) {
|
||||
ccw_flags[chan] &= ~FLAG_CD;
|
||||
|
||||
irq_pend = 1;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x, %x) %x %04x end\n", addr, flags,
|
||||
chan_status[chan], ccw_flags[chan]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -660,11 +666,11 @@ store_csw(uint16 chan) {
|
||||
key[0] |= 0x6;
|
||||
if (chan_status[chan] & STATUS_PCI) {
|
||||
chan_status[chan] &= ~STATUS_PCI;
|
||||
ccw_flags[chan] &= ~FLAG_PCI;
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "Clr PCI %02x store\n", chan);
|
||||
} else {
|
||||
chan_status[chan] = 0;
|
||||
ccw_flags[chan] &= ~FLAG_PCI;
|
||||
}
|
||||
ccw_flags[chan] &= ~FLAG_PCI;
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Channel store csw %02x %06x %08x\n",
|
||||
chan, M[0x40>>2], M[0x44 >> 2]);
|
||||
}
|
||||
@@ -1083,6 +1089,9 @@ scan_chan(uint16 mask, int irq_en) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Scan all devices and create the device mapping.
|
||||
*/
|
||||
t_stat
|
||||
chan_set_devs()
|
||||
{
|
||||
@@ -1197,6 +1206,7 @@ set_dev_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Display the address of the device */
|
||||
t_stat
|
||||
show_dev_addr(FILE * st, UNIT * uptr, int32 v, CONST void *desc)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "sim_tmxr.h"
|
||||
|
||||
#ifdef NUM_DEVS_COM
|
||||
#define UNIT_COM TT_MODE_7B
|
||||
#define UNIT_COM 0
|
||||
|
||||
|
||||
/* u3 */
|
||||
@@ -81,13 +81,14 @@
|
||||
uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
|
||||
uint8 coml_haltio(UNIT *uptr);
|
||||
t_stat coml_srv(UNIT *uptr);
|
||||
void coml_ini(UNIT *uptr, t_bool);
|
||||
t_stat com_reset(DEVICE *dptr);
|
||||
t_stat com_scan(UNIT *uptr);
|
||||
t_stat com_attach(UNIT *uptr, CONST char *);
|
||||
t_stat com_detach(UNIT *uptr);
|
||||
uint8 com_buf[NUM_UNITS_COM][256];
|
||||
t_stat com_help (FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *com_description (DEVICE *);
|
||||
|
||||
uint8 com_buf[NUM_UNITS_COM][256];
|
||||
TMLN com_ldsc[NUM_UNITS_COM];
|
||||
TMXR com_desc = { NUM_UNITS_COM, 0, 0, com_ldsc};
|
||||
int32 tmxr_poll = 10000;
|
||||
@@ -100,10 +101,6 @@ MTAB com_mod[] = {
|
||||
MTAB coml_mod[] = {
|
||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr,
|
||||
&show_dev_addr, NULL},
|
||||
{ TT_MODE, TT_MODE_KSR, "KSR", "KSR", NULL },
|
||||
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
|
||||
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
|
||||
{ TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
|
||||
{0}
|
||||
};
|
||||
|
||||
@@ -131,13 +128,14 @@ UNIT coml_unit[] = {
|
||||
};
|
||||
|
||||
struct dib com_dib = { 0xF0, NUM_UNITS_COM, NULL, coml_startcmd,
|
||||
coml_haltio, coml_unit, coml_ini};
|
||||
coml_haltio, coml_unit, NULL};
|
||||
|
||||
DEVICE com_dev = {
|
||||
"COM", com_unit, NULL, com_mod,
|
||||
NUM_DEVS_COM, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, com_reset, NULL, &com_attach, &com_detach,
|
||||
NULL, DEV_MUX | DEV_DISABLE | DEV_DEBUG, 0, dev_debug
|
||||
NULL, DEV_MUX | DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &com_help, NULL, NULL, &com_description
|
||||
};
|
||||
|
||||
DEVICE coml_dev = {
|
||||
@@ -252,6 +250,9 @@ static const uint8 com_2741_out[256] = {
|
||||
0xff, 0xff, 0x09, 0xff, 0xff, 0xff, 0xff, 0x7f
|
||||
};
|
||||
|
||||
/*
|
||||
* Issue a command to the 2701 controller.
|
||||
*/
|
||||
uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
@@ -287,6 +288,9 @@ uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle halt I/O instruction by stoping running command.
|
||||
*/
|
||||
uint8 coml_haltio(UNIT *uptr) {
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
@@ -437,8 +441,6 @@ t_stat coml_srv(UNIT * uptr)
|
||||
} else if ((uptr->CMD & ADDR) != 0 && ch == 0x13) {
|
||||
uptr->CMD |= ADDR9;
|
||||
} else if ((uptr->CMD & ADDR) == 0 && data != 0xff) {
|
||||
data = sim_tt_outcvt(data, TT_GET_MODE(uptr->flags) |
|
||||
TTUF_KSR);
|
||||
tmxr_putc_ln( &com_ldsc[unit], data);
|
||||
if (ch == 0x5b)
|
||||
tmxr_putc_ln( &com_ldsc[unit], '\r');
|
||||
@@ -622,11 +624,6 @@ com_reset(DEVICE * dptr)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
coml_ini(UNIT * uptr, t_bool f)
|
||||
{
|
||||
}
|
||||
|
||||
t_stat
|
||||
com_attach(UNIT * uptr, CONST char *cptr)
|
||||
{
|
||||
|
||||
@@ -83,7 +83,8 @@ void con_ini(UNIT *, t_bool);
|
||||
t_stat con_srv(UNIT *);
|
||||
t_stat con_attach(UNIT *, char *);
|
||||
t_stat con_detach(UNIT *);
|
||||
|
||||
t_stat con_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *con_description(DEVICE *d);
|
||||
|
||||
UNIT con_unit[] = {
|
||||
{UDATA(con_srv, UNIT_ATT, 0), 0, UNIT_ADDR(0x1F)}, /* A */
|
||||
@@ -101,7 +102,8 @@ DEVICE con_dev = {
|
||||
"INQ", con_unit, NULL, con_mod,
|
||||
NUM_DEVS_CON, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&con_dib, DEV_UADDR | DEV_DISABLE | DEV_DEBUG, 0, dev_debug
|
||||
&con_dib, DEV_UADDR | DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &con_help, NULL, NULL, &con_description
|
||||
};
|
||||
|
||||
|
||||
@@ -359,6 +361,28 @@ con_srv(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
con_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "1050 Console Terminal\n");
|
||||
fprintf (st, "This is the interface from the operator to the system. To request the\n");
|
||||
fprintf (st, "system to accept input press the <esc> key and wait until the system\n");
|
||||
fprintf (st, "responds with a line with I as the first character. When you have\n");
|
||||
fprintf (st, "finished typing your line, press return or enter key. Backspace will\n");
|
||||
fprintf (st, "delete the last character. All responses from the system are prefixed\n");
|
||||
fprintf (st, "with a R and blank as the first character. Not all operating systems\n");
|
||||
fprintf (st, "require the use of <esc> to enter data\n");
|
||||
fprintf (st, "Pressing control-X will issue a external interrupt to the CPU\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *
|
||||
con_description(DEVICE *dptr)
|
||||
{
|
||||
return "1050 Console Terminal";
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,57 @@
|
||||
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.
|
||||
|
||||
Introduced by IBM on April 7th, 1964. The IBM360 was designed to be a
|
||||
replacement for the IBM7000 series machines, offering on common instruction
|
||||
set to be used over a wide range of system configurations.
|
||||
|
||||
The IBM 360 supported 32 bit memory and 16 32 bit registers. Optionally
|
||||
it could have 4 64 bit floating point registers. Optionally the machine
|
||||
could also process packed decimal numbers directly. There was also a
|
||||
64 bit processor status word. Up to 16MB of memory could be supported,
|
||||
however 1MB or less was much more common. 8MB being the practical max.
|
||||
|
||||
Instructions ranged from 2 bytes to up to 6 bytes. In the following formats:
|
||||
Address are a 12 bit offset and one or two index registers. Index register
|
||||
0 results in a zero value.
|
||||
|
||||
RR format: (Register to Register).
|
||||
|
||||
+----+----+----+----+
|
||||
| op | R1 | R2 |
|
||||
+----+----+----+----+
|
||||
* R1 could be register or 4 bit mask.
|
||||
|
||||
RX format: (Memory to Register).
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| op | R1 | B2 | D2 | Offset2 |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
RS format: (Memory to Register).
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| op | R1 | R3 | D2 | Offset2 |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
* R3 could be register or 4 bit mask.
|
||||
|
||||
SI format: (Immediate to Memory).
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| op | Immed | D1 | Offset1 |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
SS format: (Memory to Memory).
|
||||
+----+----+----+----+----+----+----+----+----+----+----+----+
|
||||
| op | Length | D1 | Offset1 | D2 | Offset2 |
|
||||
+----+----+----+----+----+----+----+----+----+----+----+----+
|
||||
* Length could be either 1 byte or to 4 bit lengths.
|
||||
|
||||
The IBM360/67 was introduced in August 1965, this added Dynamic
|
||||
Address Translation to the IBM360 for support of CP/67 and TSS/360.
|
||||
This also added in 16 32 bit control registers.
|
||||
|
||||
The IBM370 was the successor to the IBM360 which was introduced on
|
||||
June 30th, 1970. This added in some new instructions, DAT and some
|
||||
other options.
|
||||
|
||||
*/
|
||||
|
||||
#include "ibm360_defs.h" /* simulator defns */
|
||||
@@ -204,23 +255,6 @@ struct InstHistory
|
||||
uint8 cc;
|
||||
};
|
||||
|
||||
#if 0
|
||||
#include <math.h>
|
||||
|
||||
double cnvt_float(uint32 l, uint32 h) {
|
||||
t_uint64 t64;
|
||||
double d;
|
||||
int e;
|
||||
e = ((l >> 24) & 0x7f) - 64;
|
||||
t64 = ((t_uint64)l & MMASK) << 32LL | h;
|
||||
d = (double)t64;
|
||||
d *= exp2(-56 + 4*e);
|
||||
if (l & MSIGN)
|
||||
d *= -1.0;
|
||||
return d;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct InstHistory *hst = NULL;
|
||||
|
||||
/* Forward and external declarations */
|
||||
@@ -365,6 +399,7 @@ void storepsw(uint32 addr, uint16 ircode) {
|
||||
(((uint32)ilc) << 14) |
|
||||
(((uint32)cc) << 12) |
|
||||
(((uint32)pmsk) << 8);
|
||||
/* Save code where 360/67 expects it to be */
|
||||
switch(addr) {
|
||||
case OEPSW:
|
||||
M[0xc >> 2] = (M[0xc >> 2] & 0xffff0000) | ircode;
|
||||
@@ -389,6 +424,7 @@ void storepsw(uint32 addr, uint16 ircode) {
|
||||
(((uint32)flags) << 16) |
|
||||
(((uint32)cc) << 12) |
|
||||
(((uint32)pmsk) << 8);
|
||||
/* Save code where 370 expects it to be */
|
||||
switch(addr) {
|
||||
case OEPSW:
|
||||
M[0x84 >> 2] = (M[0x84 >> 2] & 0xffff0000) | ircode;
|
||||
@@ -632,14 +668,22 @@ int ReadFull(uint32 addr, uint32 *data) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update access flag */
|
||||
key[pa >> 11] |= 0x4;
|
||||
|
||||
offset = pa & 0x3;
|
||||
|
||||
/* If not on word boundry and store feature not set */
|
||||
if (offset != 0 && (cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Actual read */
|
||||
*data = M[pa >> 2];
|
||||
|
||||
/* Handle unaligned access */
|
||||
if (offset != 0) {
|
||||
uint32 temp;
|
||||
uint8 k;
|
||||
@@ -658,6 +702,8 @@ int ReadFull(uint32 addr, uint32 *data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Combine result */
|
||||
key[temp >> 11] |= 0x4;
|
||||
temp >>= 2;
|
||||
temp = M[temp];
|
||||
@@ -668,6 +714,11 @@ int ReadFull(uint32 addr, uint32 *data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a byte from memory, checking protection
|
||||
* and alignment restrictions. Return 1 if failure, 0 if
|
||||
* success.
|
||||
*/
|
||||
int ReadByte(uint32 addr, uint32 *data) {
|
||||
|
||||
if (ReadFull(addr & (~0x3), data))
|
||||
@@ -677,7 +728,14 @@ int ReadByte(uint32 addr, uint32 *data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a half word from memory, checking protection
|
||||
* and alignment restrictions. Return 1 if failure, 0 if
|
||||
* success.
|
||||
*/
|
||||
int ReadHalf(uint32 addr, uint32 *data) {
|
||||
|
||||
/* Check if unaligned access */
|
||||
if (addr & 0x1) {
|
||||
if ((cpu_unit[0].flags & FEAT_STOR) == 0) {
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
@@ -709,6 +767,11 @@ int ReadHalf(uint32 addr, uint32 *data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a full word in memory, checking protection
|
||||
* and alignment restrictions. Return 1 if failure, 0 if
|
||||
* success.
|
||||
*/
|
||||
int WriteFull(uint32 addr, uint32 data) {
|
||||
int offset;
|
||||
uint32 pa;
|
||||
@@ -753,6 +816,12 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
}
|
||||
key[pa >> 11] |= 0x6;
|
||||
|
||||
/* Put data in correct locations */
|
||||
if (offset == 0) {
|
||||
M[pa >> 2] = data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa2 = pa + 4;
|
||||
/* Check if we handle unaligned access */
|
||||
if (offset != 0 && (pa2 & 0x7FC) == 0) {
|
||||
@@ -788,6 +857,7 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
pa >>= 2;
|
||||
pa2 >>= 2;
|
||||
|
||||
/* Put data in correct locations */
|
||||
switch (offset) {
|
||||
case 0:
|
||||
M[pa] = data;
|
||||
@@ -814,6 +884,11 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a byte in memory, checking protection
|
||||
* and alignment restrictions. Return 1 if failure, 0 if
|
||||
* success.
|
||||
*/
|
||||
int WriteByte(uint32 addr, uint32 data) {
|
||||
uint32 mask;
|
||||
uint32 pa;
|
||||
@@ -850,8 +925,11 @@ int WriteByte(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flag as modified */
|
||||
key[pa >> 11] |= 0x6;
|
||||
|
||||
/* Do actual update */
|
||||
offset = 8 * (3 - (pa & 0x3));
|
||||
pa >>= 2;
|
||||
mask = 0xff;
|
||||
@@ -863,6 +941,11 @@ int WriteByte(uint32 addr, uint32 data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a half word in memory, checking protection
|
||||
* and alignment restrictions. Return 1 if failure, 0 if
|
||||
* success.
|
||||
*/
|
||||
int WriteHalf(uint32 addr, uint32 data) {
|
||||
uint32 mask;
|
||||
uint32 pa;
|
||||
@@ -907,10 +990,11 @@ int WriteHalf(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flag as modified */
|
||||
key[pa >> 11] |= 0x6;
|
||||
|
||||
pa2 = pa + 4;
|
||||
if (offset == 3 && (pa2 & 0x7FC) == 0) {
|
||||
if (offset == 3) {
|
||||
addr += 4;
|
||||
/* Check if in storage area */
|
||||
if (per_en && (cregs[9] & 0x20000000) != 0) {
|
||||
@@ -925,24 +1009,33 @@ int WriteHalf(uint32 addr, uint32 data) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate address */
|
||||
if (TransAddr(addr, &pa2))
|
||||
return 1;
|
||||
pa2 = pa + 4;
|
||||
if ((pa2 & 0x7FC) == 0) {
|
||||
/* Validate address */
|
||||
if (TransAddr(addr, &pa2))
|
||||
return 1;
|
||||
|
||||
/* Check against storage key */
|
||||
if (st_key != 0) {
|
||||
uint8 k;
|
||||
/* Check against storage key */
|
||||
if (st_key != 0) {
|
||||
uint8 k;
|
||||
|
||||
k = key[(pa2) >> 11];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
k = key[(pa2) >> 11];
|
||||
if ((k & 0xf0) != st_key) {
|
||||
storepsw(OPPSW, IRC_PROT);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
key[pa2 >> 11] |= 0x6;
|
||||
}
|
||||
key[pa2 >> 11] |= 0x6;
|
||||
pa >>= 2;
|
||||
pa2 >>= 2;
|
||||
M[pa] &= 0xffffff00;
|
||||
M[pa] |= 0xff & (data >> 8);
|
||||
M[pa2] &= 0x00ffffff;
|
||||
M[pa2] |= 0xff000000 & (data << 24);
|
||||
return 0;
|
||||
}
|
||||
pa >>= 2;
|
||||
pa2 >>= 2;
|
||||
|
||||
mask = 0xffff;
|
||||
data &= mask;
|
||||
@@ -960,10 +1053,6 @@ int WriteHalf(uint32 addr, uint32 data) {
|
||||
M[pa] |= data;
|
||||
break;
|
||||
case 3:
|
||||
M[pa] &= 0xffffff00;
|
||||
M[pa] |= 0xff & (data >> 8);
|
||||
M[pa2] &= 0x00ffffff;
|
||||
M[pa2] |= 0xff000000 & (data << 24);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -974,33 +1063,34 @@ t_stat
|
||||
sim_instr(void)
|
||||
{
|
||||
t_stat reason;
|
||||
uint32 src1;
|
||||
uint32 src1; /* 1st Source low and high */
|
||||
uint32 src1h;
|
||||
uint32 src2;
|
||||
uint32 src2; /* 2st Source low and high */
|
||||
uint32 src2h;
|
||||
uint32 dest;
|
||||
uint32 dest; /* Destination low and high */
|
||||
uint32 desth;
|
||||
uint32 addr1;
|
||||
uint32 addr2;
|
||||
uint8 op;
|
||||
uint8 fill;
|
||||
uint8 digit;
|
||||
uint8 reg;
|
||||
uint8 reg1;
|
||||
uint8 zone;
|
||||
uint16 irq;
|
||||
int e1, e2;
|
||||
uint32 addr1; /* Address of 1st source */
|
||||
uint32 addr2; /* Address of 2st source */
|
||||
uint16 ops[3]; /* Current instruction */
|
||||
uint8 op; /* Opcode of current instruction */
|
||||
uint8 fill; /* Holds fill and other temp flags */
|
||||
uint8 digit; /* Holds digit during ED instruction */
|
||||
uint8 reg; /* Second byte of instruction */
|
||||
uint8 reg1; /* First register */
|
||||
uint8 zone; /* Holds zone during PACK & ED instructions */
|
||||
uint16 irq; /* Holds current irq code */
|
||||
int e1, e2; /* Exponent 1 & 2 and various flags */
|
||||
int temp;
|
||||
#ifdef USE_64BIT
|
||||
t_uint64 src1L;
|
||||
t_uint64 src1L; /* 64 bit source 1 and 2 */
|
||||
t_uint64 src2L;
|
||||
t_uint64 destL;
|
||||
t_uint64 dest2L;
|
||||
t_uint64 destL; /* 64 bit destination */
|
||||
t_uint64 dest2L; /* Upper 64 bit for product */
|
||||
#endif
|
||||
uint16 ops[3];
|
||||
//double a, b, c;
|
||||
|
||||
/* Initialize DAT translation values */
|
||||
if ((cpu_unit[0].flags & FEAT_370) == 0) {
|
||||
/* 360/67 only supports 4k pages */
|
||||
page_shift = 12;
|
||||
page_mask = 0xfff;
|
||||
seg_shift = 20;
|
||||
@@ -1012,7 +1102,6 @@ sim_instr(void)
|
||||
seg_addr = cregs[0] & AMASK;
|
||||
seg_len = (((cregs[0] >> 24) & 0xff) + 1) << 4;
|
||||
} else {
|
||||
sim_activate(&cpu_unit[1], 1000);
|
||||
switch((cregs[0] >> 22) & 03) {
|
||||
default: /* Generate translation exception */
|
||||
case 1: /* 2K pages */
|
||||
@@ -1062,8 +1151,8 @@ wait_loop:
|
||||
}
|
||||
|
||||
/* Check if we should see if an IRQ is pending */
|
||||
irq= scan_chan(sysmsk, irq_en);
|
||||
if (irq!= 0) {
|
||||
irq = scan_chan(sysmsk, irq_en);
|
||||
if (irq != 0) {
|
||||
ilc = 0;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "IRQ=%04x %08x\n", irq, PC);
|
||||
if (loading) {
|
||||
@@ -1165,6 +1254,7 @@ wait_loop:
|
||||
iPC = PC;
|
||||
ilc = 0;
|
||||
|
||||
/* Fetch the next instruction */
|
||||
if (ReadHalf(PC, &dest))
|
||||
goto supress;
|
||||
if (per_en && (cregs[9] & 0x40000000) != 0) {
|
||||
@@ -1223,8 +1313,6 @@ opr:
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "\n");
|
||||
}
|
||||
|
||||
/* Add in history here */
|
||||
|
||||
/* If RX or RS or SS SI etc compute first address */
|
||||
if (op & 0xc0) {
|
||||
uint32 temp;
|
||||
@@ -1245,6 +1333,7 @@ opr:
|
||||
}
|
||||
}
|
||||
|
||||
/* update history */
|
||||
if (hst_lnt) {
|
||||
hst[hst_p].op = op;
|
||||
hst[hst_p].reg = reg;
|
||||
@@ -3470,7 +3559,6 @@ save_dbl:
|
||||
/* Floating Half register */
|
||||
case OP_HDR:
|
||||
case OP_HER:
|
||||
//fprintf(stderr, "FP HD Op=%0x src2=%08x %08x %.12e\n\r", op, src2, src2h, cnvt_float(src2, src2h));
|
||||
/* Split number apart */
|
||||
e1 = (src2 & EMASK) >> 24;
|
||||
dest = src2 & MSIGN; /* Save sign */
|
||||
@@ -3481,7 +3569,6 @@ save_dbl:
|
||||
/* If not zero, normalize result */
|
||||
if ((src2 | src2h) != 0) {
|
||||
while ((src2 & NMASK) == 0) {
|
||||
//fprintf(stderr, "FP +n res=%08x %08x %x\n\r", src2, src2h, e1);
|
||||
src2 = (src2 << 4) | ((src2h >> 28) & 0xf);
|
||||
src2h <<= 4;
|
||||
e1 --;
|
||||
@@ -3490,7 +3577,6 @@ save_dbl:
|
||||
if (e1 < 0) {
|
||||
if (pmsk & EXPUND) {
|
||||
storepsw(OPPSW, IRC_EXPUND);
|
||||
//fprintf(stderr, "FP under\n\r");
|
||||
} else {
|
||||
dest = e1 = 0;
|
||||
}
|
||||
@@ -3500,7 +3586,6 @@ save_dbl:
|
||||
}
|
||||
/* Restore result */
|
||||
src2 |= ((e1 << 24) & EMASK) | dest;
|
||||
//fprintf(stderr, "FP HD= Op=%0x src2=%08x %08x %.12e\n\r", op, src2, src2h, cnvt_float(src2, src2h));
|
||||
|
||||
/* Fall through */
|
||||
|
||||
@@ -3509,7 +3594,6 @@ save_dbl:
|
||||
case OP_LDR:
|
||||
case OP_LE:
|
||||
case OP_LD:
|
||||
//fprintf(stderr, "FP LD Op=%0x src1=%08x %08x\n\r", op, src1, src1h);
|
||||
if ((op & 0x10) == 0)
|
||||
fpregs[reg1|1] = src2h;
|
||||
fpregs[reg1] = src2;
|
||||
@@ -3524,7 +3608,6 @@ save_dbl:
|
||||
case OP_LNER:
|
||||
case OP_LTER:
|
||||
case OP_LCER:
|
||||
//fprintf(stderr, "FP LD Op=%0x src1=%08x %08x\n\r", op, src1, src1h);
|
||||
if ((op & 0x2) == 0) /* LP, LN */
|
||||
src2 &= ~MSIGN;
|
||||
if ((op & 0x1)) /* LN, LC */
|
||||
@@ -3547,16 +3630,12 @@ save_dbl:
|
||||
/* Fall through */
|
||||
|
||||
case OP_STE:
|
||||
//fprintf(stderr, "FP STD Op=%0x src1=%08x %08x\n\r", op, src1, src1h);
|
||||
WriteFull(addr1, src1);
|
||||
break;
|
||||
|
||||
/* Floating Compare */
|
||||
case OP_CE: /* 79 */
|
||||
case OP_CER: /* 39 */
|
||||
// a = cnvt_float(src1, 0);
|
||||
// b = cnvt_float(src2, 0);
|
||||
//fprintf(stderr, "FP = Op=%0x src1=%08x, src2=%08x %.12e %.12e %.12e\n\r", op, src1, src2, a, b, a-b);
|
||||
/* Extract numbers and adjust */
|
||||
e1 = (src1 & EMASK) >> 24;
|
||||
e2 = (src2 & EMASK) >> 24;
|
||||
@@ -3579,7 +3658,6 @@ save_dbl:
|
||||
while (temp-- != 0) {
|
||||
src2 >>= 4;
|
||||
e2 ++;
|
||||
//fprintf(stderr, "FP =2 Op=%0x src1=%08x, src2=%08x\n\r", op, src1, src2);
|
||||
}
|
||||
}
|
||||
} else if (temp < 0) {
|
||||
@@ -3591,7 +3669,6 @@ save_dbl:
|
||||
while (temp++ != 0) {
|
||||
src1 >>= 4;
|
||||
e1 ++;
|
||||
//fprintf(stderr, "FP =1 Op=%0x src1=%08x, src2=%08x\n\r", op, src1, src2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3614,7 +3691,6 @@ save_dbl:
|
||||
dest = src1 + src2;
|
||||
}
|
||||
/* If src1 not normal shift left + expo */
|
||||
//fprintf(stderr, "FP +n res=%08x %08x\n\r", dest, desth);
|
||||
if (dest & CMASK)
|
||||
dest >>= 4;
|
||||
|
||||
@@ -3622,8 +3698,6 @@ save_dbl:
|
||||
cc = 0;
|
||||
if (dest != 0)
|
||||
cc = (fill & 2) ? 1 : 2;
|
||||
|
||||
//fprintf(stderr, "FP = res=%08x %d\n\r", dest, cc);
|
||||
break;
|
||||
|
||||
/* Floating Subtract */
|
||||
@@ -3639,9 +3713,6 @@ save_dbl:
|
||||
case OP_AU: /* 7E */
|
||||
case OP_AER: /* 3A */
|
||||
case OP_AUR: /* 3E */
|
||||
// a = cnvt_float(src1, 0);
|
||||
// b = cnvt_float(src2, 0);
|
||||
//fprintf(stderr, "FP + Op=%0x src1=%08x, src2=%08x %.12e %.12e %.12e\n\r", op, src1, src2, a, b, a+b);
|
||||
/* Extract numbers and adjust */
|
||||
e1 = (src1 & EMASK) >> 24;
|
||||
e2 = (src2 & EMASK) >> 24;
|
||||
@@ -3664,7 +3735,6 @@ save_dbl:
|
||||
while (temp-- != 0) {
|
||||
src2 >>= 4;
|
||||
e2 ++;
|
||||
//fprintf(stderr, "FP +2 Op=%0x src1=%08x, src2=%08x\n\r", op, src1, src2);
|
||||
}
|
||||
}
|
||||
} else if (temp < 0) {
|
||||
@@ -3676,7 +3746,6 @@ save_dbl:
|
||||
while (temp++ != 0) {
|
||||
src1 >>= 4;
|
||||
e1 ++;
|
||||
//fprintf(stderr, "FP +1 Op=%0x src1=%08x, src2=%08x\n\r", op, src1, src2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3699,13 +3768,11 @@ save_dbl:
|
||||
dest = src1 + src2;
|
||||
}
|
||||
/* If overflow, shift right 4 bits */
|
||||
//fprintf(stderr, "FP +n res=%08x %d\n\r", dest, cc);
|
||||
if (dest & CMASK) {
|
||||
dest >>= 4;
|
||||
e1 ++;
|
||||
if (e1 >= 128) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
// fprintf(stderr, "FP ov %d\n\r", e1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3723,13 +3790,9 @@ save_dbl:
|
||||
dest = e1 = fill = 0;
|
||||
}
|
||||
|
||||
//fprintf(stderr, "FP +p res=%08x %d\n\r", dest, cc);
|
||||
|
||||
|
||||
/* Check signifigance exception */
|
||||
if (cc == 0 && pmsk & SIGMSK) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
// fprintf(stderr, "FP Signifigance\n\r");
|
||||
goto fpstore;
|
||||
}
|
||||
|
||||
@@ -3737,7 +3800,6 @@ save_dbl:
|
||||
if ((op & 0xE) != 0xE) {
|
||||
if (cc != 0) { /* Only if non-zero result */
|
||||
while ((dest & SNMASK) == 0) {
|
||||
//fprintf(stderr, "FP +n res=%08x %08x %x\n\r", dest, desth, e1);
|
||||
dest = dest << 4;
|
||||
e1 --;
|
||||
}
|
||||
@@ -3745,7 +3807,6 @@ save_dbl:
|
||||
if (e1 < 0) {
|
||||
if (pmsk & EXPUND) {
|
||||
storepsw(OPPSW, IRC_EXPUND);
|
||||
// fprintf(stderr, "FP under\n\r");
|
||||
} else {
|
||||
dest = 0;
|
||||
fill = e1 = 0;
|
||||
@@ -3762,15 +3823,11 @@ save_dbl:
|
||||
if (cc != 0 && fill & 2)
|
||||
dest |= MSIGN;
|
||||
fpregs[reg1] = dest;
|
||||
//fprintf(stderr, "FP + res=%08x %d %.12e\n\r", dest, cc, cnvt_float(dest,0));
|
||||
break;
|
||||
|
||||
/* Floating Compare */
|
||||
case OP_CD: /* 69 */
|
||||
case OP_CDR: /* 29 */
|
||||
// a = cnvt_float(src1, src1h);
|
||||
// b = cnvt_float(src2, src2h);
|
||||
//fprintf(stderr, "FP = Op=%0x src1=%08x %08x, src2=%08x %08x %e %e %e\n\r", op, src1, src1h, src2, src2h, a, b, a-b);
|
||||
/* Extract numbers and adjust */
|
||||
e1 = (src1 & EMASK) >> 24;
|
||||
e2 = (src2 & EMASK) >> 24;
|
||||
@@ -3791,8 +3848,6 @@ save_dbl:
|
||||
} else {
|
||||
/* Shift src2 right if src1 larger expo - expo */
|
||||
src2L >>= 4 * temp;
|
||||
// e2 += temp;
|
||||
//fprintf(stderr, "FP =2 Op=%0x src1=%08x %08x, src2=%08x %08x %e %e %e\n\r", op, src1, src1h, src2, src2h, a, b, a+b);
|
||||
}
|
||||
} else if (temp < 0) {
|
||||
if (temp < -15) {
|
||||
@@ -3800,7 +3855,6 @@ save_dbl:
|
||||
} else {
|
||||
/* Shift src1 right if src2 larger expo - expo */
|
||||
src1L >>= 4 * -temp;
|
||||
//fprintf(stderr, "FP =1 Op=%0x src1=%08x %08x, src2=%08x %08x %e %e %e\n\r", op, src1, src1h, src2, src2h, a, b, a+b);
|
||||
}
|
||||
e1 = e2;
|
||||
}
|
||||
@@ -3824,7 +3878,6 @@ save_dbl:
|
||||
destL = src1L + src2L;
|
||||
}
|
||||
/* If overflow, shift right 4 bits */
|
||||
//fprintf(stderr, "FP +n res=%08x %08x\n\r", dest, desth);
|
||||
if (destL & CMASKL) {
|
||||
destL >>= 4;
|
||||
}
|
||||
@@ -3847,8 +3900,6 @@ save_dbl:
|
||||
src2h >>= 4;
|
||||
src2h |= (src2 & 0xf) << 28;
|
||||
src2 >>= 4;
|
||||
// e2 ++;
|
||||
//fprintf(stderr, "FP =2 Op=%0x src1=%08x %08x, src2=%08x %08x %e %e %e\n\r", op, src1, src1h, src2, src2h, a, b, a+b);
|
||||
}
|
||||
}
|
||||
} else if (temp < 0) {
|
||||
@@ -3860,7 +3911,6 @@ save_dbl:
|
||||
src1h >>= 4;
|
||||
src1h |= (src1 & 0xf) << 28;
|
||||
src1 >>= 4;
|
||||
//fprintf(stderr, "FP =1 Op=%0x src1=%08x %08x, src2=%08x %08x %e %e %e\n\r", op, src1, src1h, src2, src2h, a, b, a+b);
|
||||
}
|
||||
}
|
||||
e1 = e2;
|
||||
@@ -3899,7 +3949,6 @@ save_dbl:
|
||||
}
|
||||
|
||||
/* If overflow, shift right 4 bits */
|
||||
//fprintf(stderr, "FP +n res=%08x %08x\n\r", dest, desth);
|
||||
if (dest & CMASK) {
|
||||
desth >>= 4;
|
||||
desth |= (dest & 0xf) << 28;
|
||||
@@ -3909,7 +3958,6 @@ save_dbl:
|
||||
cc = 0;
|
||||
if ((desth | dest) != 0)
|
||||
cc = (fill & 2) ? 1 : 2;
|
||||
//fprintf(stderr, "FP = res=%08x %08x %d\n\r", dest, desth, cc);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -3926,9 +3974,6 @@ save_dbl:
|
||||
case OP_AW: /* 6E */
|
||||
case OP_ADR: /* 2A */
|
||||
case OP_AWR: /* 2E */
|
||||
// a = cnvt_float(src1, src1h);
|
||||
// b = cnvt_float(src2, src2h);
|
||||
//fprintf(stderr, "FP + Op=%0x src1=%08x %08x, src2=%08x %08x %.12e %.12e %.12e\n\r", op, src1, src1h, src2, src2h, a, b, a+b);
|
||||
/* Extract numbers and adjust */
|
||||
e1 = (src1 & EMASK) >> 24;
|
||||
e2 = (src2 & EMASK) >> 24;
|
||||
@@ -3949,8 +3994,6 @@ save_dbl:
|
||||
} else {
|
||||
/* Shift src2 right if src1 larger expo - expo */
|
||||
src2L >>= 4 * temp;
|
||||
// e2 += temp;
|
||||
//fprintf(stderr, "FP =2 Op=%0x src1=%016llx, src2=%016llxx %e %e %e\n\r", op, src1L, src2L, a, b, a+b);
|
||||
}
|
||||
} else if (temp < 0) {
|
||||
if (temp < -15) {
|
||||
@@ -3958,7 +4001,6 @@ save_dbl:
|
||||
} else {
|
||||
/* Shift src1 right if src2 larger expo - expo */
|
||||
src1L >>= 4 * (-temp);
|
||||
//fprintf(stderr, "FP =1 Op=%0x src1=%016llx, src2=%016llxx %e %e %e\n\r", op, src1L, src2L, a, b, a+b);
|
||||
}
|
||||
e1 = e2;
|
||||
}
|
||||
@@ -3982,13 +4024,11 @@ save_dbl:
|
||||
destL = src1L + src2L;
|
||||
}
|
||||
/* If overflow, shift right 4 bits */
|
||||
//fprintf(stderr, "FP +n res=%016llx\n\r", destL);
|
||||
if (destL & CMASKL) {
|
||||
destL >>= 4;
|
||||
e1 ++;
|
||||
if (e1 >= 128) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
// fprintf(stderr, "FP ov %d\n\r", e1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4009,7 +4049,6 @@ save_dbl:
|
||||
/* Check signifigance exception */
|
||||
if (cc == 0 && pmsk & SIGMSK) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
// fprintf(stderr, "FP Signifigance\n\r");
|
||||
e1 = fill = 0;
|
||||
dest = desth = 0;
|
||||
goto fpstore;
|
||||
@@ -4019,7 +4058,6 @@ save_dbl:
|
||||
if ((op & 0xE) != 0xE) {
|
||||
if (cc != 0) { /* Only if non-zero result */
|
||||
while ((destL & SNMASKL) == 0) {
|
||||
//fprintf(stderr, "FP +n res=%016llx %x\n\r", destL, e1);
|
||||
destL <<= 4;
|
||||
e1 --;
|
||||
}
|
||||
@@ -4027,7 +4065,6 @@ save_dbl:
|
||||
if (e1 < 0) {
|
||||
if (pmsk & EXPUND) {
|
||||
storepsw(OPPSW, IRC_EXPUND);
|
||||
// fprintf(stderr, "FP under\n\r");
|
||||
} else {
|
||||
destL = 0;
|
||||
fill = e1 = 0;
|
||||
@@ -4063,8 +4100,6 @@ save_dbl:
|
||||
src2h >>= 4;
|
||||
src2h |= (src2 & 0xf) << 28;
|
||||
src2 >>= 4;
|
||||
// e2 ++;
|
||||
//fprintf(stderr, "FP +2 Op=%0x src1=%08x %08x, src2=%08x %08x %e %e %e\n\r", op, src1, src1h, src2, src2h, a, b, a+b);
|
||||
}
|
||||
}
|
||||
} else if (temp < 0) {
|
||||
@@ -4076,7 +4111,6 @@ save_dbl:
|
||||
src1h >>= 4;
|
||||
src1h |= (src1 & 0xf) << 28;
|
||||
src1 >>= 4;
|
||||
//fprintf(stderr, "FP +1 Op=%0x src1=%08x %08x, src2=%08x %08x %e %e %e\n\r", op, src1, src1h, src2, src2h, a, b, a+b);
|
||||
}
|
||||
}
|
||||
e1 = e2;
|
||||
@@ -4114,7 +4148,6 @@ save_dbl:
|
||||
}
|
||||
|
||||
/* If overflow, shift right 4 bits */
|
||||
//fprintf(stderr, "FP +n res=%08x %08x\n\r", dest, desth);
|
||||
if (dest & CMASK) {
|
||||
desth >>= 4;
|
||||
desth |= (dest & 0xf) << 28;
|
||||
@@ -4122,7 +4155,6 @@ save_dbl:
|
||||
e1 ++;
|
||||
if (e1 >= 128) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
// fprintf(stderr, "FP ov %d\n\r", e1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4143,7 +4175,6 @@ save_dbl:
|
||||
/* Check signifigance exception */
|
||||
if (cc == 0 && pmsk & SIGMSK) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
// fprintf(stderr, "FP Signifigance\n\r");
|
||||
e1 = fill = 0;
|
||||
goto fpstore;
|
||||
}
|
||||
@@ -4152,7 +4183,6 @@ save_dbl:
|
||||
if ((op & 0xE) != 0xE) {
|
||||
if (cc != 0) { /* Only if non-zero result */
|
||||
while ((dest & SNMASK) == 0) {
|
||||
//fprintf(stderr, "FP +n res=%08x %08x %x\n\r", dest, desth, e1);
|
||||
dest = (dest << 4) | ((desth >> 28) & 0xf);
|
||||
desth <<= 4;
|
||||
e1 --;
|
||||
@@ -4161,7 +4191,6 @@ save_dbl:
|
||||
if (e1 < 0) {
|
||||
if (pmsk & EXPUND) {
|
||||
storepsw(OPPSW, IRC_EXPUND);
|
||||
// fprintf(stderr, "FP under\n\r");
|
||||
} else {
|
||||
desth = dest = 0;
|
||||
fill = e1 = 0;
|
||||
@@ -4186,9 +4215,6 @@ fpstore:
|
||||
dest |= MSIGN;
|
||||
fpregs[reg1|1] = desth;
|
||||
fpregs[reg1] = dest;
|
||||
//fprintf(stderr, "FP + res=%08x %08x %d %.12e\n\r", dest, desth, cc, cnvt_float(dest,desth));
|
||||
//fprintf(stderr, "FP o=%02x src1=%08x%08x, src2=%08x%08x dest=%08x%08x\n\r", op, src1, src1h, src2, src2h, dest, desth);
|
||||
//fprintf(stderr, "FP o=%02x src1=%016llx, src2=%016llx dest=%08x%08x %d %.12e\n\r", op, src1L, src2L, dest, desth, cc, cnvt_float(dest,desth));
|
||||
break;
|
||||
|
||||
/* Multiply */
|
||||
@@ -4196,9 +4222,6 @@ fpstore:
|
||||
case OP_MER:
|
||||
case OP_ME:
|
||||
case OP_MD:
|
||||
// a = cnvt_float(src1, src1h);
|
||||
// b = cnvt_float(src2, src2h);
|
||||
//fprintf(stderr, "FP * Op=%0x src1=%08x %08x, src2=%08x %08x %.12e %.12e %.12e\n\r", op, src1, src1h, src2, src2h, a, b, a*b);
|
||||
/* Extract numbers and adjust */
|
||||
e1 = (src1 & EMASK) >> 24;
|
||||
e2 = (src2 & EMASK) >> 24;
|
||||
@@ -4231,7 +4254,6 @@ fpstore:
|
||||
destL = 0;
|
||||
/* Do multiply */
|
||||
for (temp = 0; temp < 56; temp++) {
|
||||
//fprintf(stderr, "FP *s src1=%016llx, src2=%016llx dest=%016llx %d\n\r", src1L, src2L, destL, temp);
|
||||
/* Add if we need too */
|
||||
if (src1L & 1)
|
||||
destL += src2L;
|
||||
@@ -4240,20 +4262,17 @@ fpstore:
|
||||
destL >>= 1;
|
||||
}
|
||||
fpnorm:
|
||||
//fprintf(stderr, "FP *r res=%016llx %x\n\r", destL, e1);
|
||||
/* If overflow, shift right 4 bits */
|
||||
if (destL & EMASKL) {
|
||||
destL >>= 4;
|
||||
e1 ++;
|
||||
if (e1 >= 128) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
//fprintf(stderr, "FP ov\n\r");
|
||||
}
|
||||
}
|
||||
/* Align the results */
|
||||
if ((destL) != 0) {
|
||||
while ((destL & NMASKL) == 0) {
|
||||
//fprintf(stderr, "FP *n res=%016llx %x\n\r", destL, e1);
|
||||
destL <<= 4;
|
||||
e1 --;
|
||||
}
|
||||
@@ -4261,7 +4280,6 @@ fpnorm:
|
||||
if (e1 < 0) {
|
||||
if (pmsk & EXPUND) {
|
||||
storepsw(OPPSW, IRC_EXPUND);
|
||||
// fprintf(stderr, "FP un\n\r");
|
||||
} else {
|
||||
destL = 0;
|
||||
fill = e1 = 0;
|
||||
@@ -4269,7 +4287,6 @@ fpnorm:
|
||||
}
|
||||
} else
|
||||
e1 = fill = 0;
|
||||
//fprintf(stderr, "FP *f res=%016llx %x\n\r", destL, e1);
|
||||
dest = ((uint32)(destL >> 32)) & MMASK;
|
||||
desth = (uint32)(destL & FMASK);
|
||||
#else
|
||||
@@ -4295,7 +4312,6 @@ fpnorm:
|
||||
dest = desth = 0;
|
||||
/* Do multiply */
|
||||
for (temp = 0; temp < 56; temp++) {
|
||||
//fprintf(stderr, "FP *s src1=%08x %08x, src2=%08x %08x dest=%08x %08x %d\n\r", src1, src1h, src2, src2h, dest, desth, temp);
|
||||
/* Add if we need too */
|
||||
if (src1h & 1) {
|
||||
desth += src2h;
|
||||
@@ -4322,13 +4338,11 @@ fpnorm:
|
||||
e1 ++;
|
||||
if (e1 >= 128) {
|
||||
storepsw(OPPSW, IRC_EXPOVR);
|
||||
//fprintf(stderr, "FP ov\n\r");
|
||||
}
|
||||
}
|
||||
/* Align the results */
|
||||
if ((dest | desth) != 0) {
|
||||
while ((dest & NMASK) == 0) {
|
||||
//fprintf(stderr, "FP *n res=%08x %08x %x\n\r", dest, desth, e1);
|
||||
dest = (dest << 4) | ((desth >> 28) & 0xf);
|
||||
desth <<= 4;
|
||||
e1 --;
|
||||
@@ -4337,7 +4351,6 @@ fpnorm:
|
||||
if (e1 < 0) {
|
||||
if (pmsk & EXPUND) {
|
||||
storepsw(OPPSW, IRC_EXPUND);
|
||||
// fprintf(stderr, "FP un\n\r");
|
||||
} else {
|
||||
desth = dest = 0;
|
||||
fill = e1 = 0;
|
||||
@@ -4352,9 +4365,6 @@ fpnorm:
|
||||
if ((op & 0x10) == 0 || (op & 0xF) == 0xC)
|
||||
fpregs[reg1|1] = desth;
|
||||
fpregs[reg1] = dest;
|
||||
//fprintf(stderr, "FP * res=%08x %08x %d %.12e\n\r", dest, desth, cc, cnvt_float(dest,desth));
|
||||
//fprintf(stderr, "FP o=%02x src1=%08x%08x, src2=%08x%08x dest=%08x%08x\n\r", op, src1, src1h, src2, src2h, dest, desth);
|
||||
//fprintf(stderr, "FP o=%02x src1=%016llx, src2=%016llx dest=%08x%08x %d %.12e\n\r", op, src1L, src2L, dest, desth, cc, cnvt_float(dest,desth));
|
||||
break;
|
||||
|
||||
/* Divide */
|
||||
@@ -4362,10 +4372,6 @@ fpnorm:
|
||||
case OP_DDR:
|
||||
case OP_DD:
|
||||
case OP_DE:
|
||||
// a = cnvt_float(src1, src1h);
|
||||
// b = cnvt_float(src2, src2h);
|
||||
//fprintf(stderr, "FP / Op=%0x src1=%08x %08x, src2=%08x %08x %.12e %.12e %.12e\n\r", op, src1, src1h, src2, src2h, a, b, a/b);
|
||||
|
||||
/* Extract numbers and adjust */
|
||||
e1 = (src1 & EMASK) >> 24;
|
||||
e2 = (src2 & EMASK) >> 24;
|
||||
@@ -4407,7 +4413,6 @@ fpnorm:
|
||||
|
||||
/* Check if we need to adjust divsor it larger then dividend */
|
||||
if (src1L > src2L) {
|
||||
//fprintf(stderr, "FP /o src1=%016llx, src2=%016llx dest=%016llx\n\r", src1L, src2L, destL);
|
||||
src1L >>= 4;
|
||||
e1++;
|
||||
}
|
||||
@@ -4420,7 +4425,6 @@ fpnorm:
|
||||
for (temp = 56; temp > 0; temp--) {
|
||||
t_uint64 t;
|
||||
|
||||
//fprintf(stderr, "FP /s src1=%016llx, src2=%016llx dest=%016llx %d\n\r", src1L, src2L, destL, temp);
|
||||
/* Shift left by one */
|
||||
src1L <<= 1;
|
||||
/* Subtract remainder to dividend */
|
||||
@@ -4444,7 +4448,6 @@ fpnorm:
|
||||
|
||||
/* If .5 off, round */
|
||||
if ((src1L & MSIGNL) != 0) {
|
||||
//fprintf(stderr, "FP /rn src1=%016llx, src2=%016llx dest=%016llx %d\n\r", src1L, src2L, destL, temp);
|
||||
destL++;
|
||||
}
|
||||
#else
|
||||
@@ -4469,7 +4472,6 @@ fpnorm:
|
||||
|
||||
/* Check if we need to adjust divsor it larger then dividend */
|
||||
if (src1 > src2 || (src1 == src2 && src1h > src2h)) {
|
||||
//fprintf(stderr, "FP /o src1=%08x %08x, src2=%08x %08x dest=%08x %08x\n\r", src1, src1h, src2, src2h, dest, desth);
|
||||
src1h >>= 4;
|
||||
src1h |= (src1 & 0xf) <<28;
|
||||
src1 >>= 4;
|
||||
@@ -4487,7 +4489,6 @@ fpnorm:
|
||||
for (temp = 56; temp > 0; temp--) {
|
||||
uint32 tlow, thigh;
|
||||
|
||||
//fprintf(stderr, "FP /s src1=%08x %08x, src2=%08x %08x dest=%08x %08x %d\n\r", src1, src1h, src2, src2h, dest, desth, temp);
|
||||
/* Shift left by one */
|
||||
src1 <<= 1;
|
||||
if (src1h & MSIGN)
|
||||
@@ -4527,7 +4528,6 @@ fpnorm:
|
||||
|
||||
/* If .5 off, round */
|
||||
if (src1 & MSIGN) {
|
||||
//fprintf(stderr, "FP /rn src1=%08x%08x, src2=%08x%08x dest=%08x%08x %d\n\r", src1, src1h, src2, src2h, dest, desth, temp);
|
||||
if (desth == FMASK)
|
||||
dest++;
|
||||
desth++;
|
||||
|
||||
@@ -144,10 +144,11 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
|
||||
t_stat mt_srv(UNIT *);
|
||||
t_stat mt_boot(int32, DEVICE *);
|
||||
void mt_ini(UNIT *, t_bool);
|
||||
t_stat mt_reset(DEVICE *);
|
||||
t_stat mt_boot(int32, DEVICE *);
|
||||
t_stat mt_attach(UNIT *, CONST char *);
|
||||
t_stat mt_detach(UNIT *);
|
||||
t_stat mt_boot(int32, DEVICE *);
|
||||
t_stat mt_help (FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||
const char *mt_description (DEVICE *);
|
||||
|
||||
|
||||
/* One buffer per channel */
|
||||
@@ -182,8 +183,9 @@ struct dib mta_dib = { 0xF8, NUM_UNITS_MT, NULL, mt_startcmd, NULL, mta_unit, mt
|
||||
DEVICE mta_dev = {
|
||||
"MTA", mta_unit, NULL, mt_mod,
|
||||
NUM_UNITS_MT, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach,
|
||||
&mta_dib, DEV_BUF_NUM(0) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug
|
||||
NULL, NULL, NULL, &mt_boot, &mt_attach, &mt_detach,
|
||||
&mta_dib, DEV_BUF_NUM(0) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug,
|
||||
NULL, NULL, &mt_help, NULL, NULL, &mt_description
|
||||
};
|
||||
|
||||
#if NUM_DEVS_MT > 1
|
||||
@@ -203,8 +205,9 @@ struct dib mtb_dib = { 0xF8, NUM_UNITS_MT, NULL, mt_startcmd, NULL, mtb_unit, mt
|
||||
DEVICE mtb_dev = {
|
||||
"MTB", mtb_unit, NULL, mt_mod,
|
||||
NUM_UNITS_MT, 8, 15, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach,
|
||||
&mtb_dib, DEV_BUF_NUM(1) | DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_TAPE, 0, dev_debug
|
||||
NULL, NULL, NULL, &mt_boot, &mt_attach, &mt_detach,
|
||||
&mtb_dib, DEV_BUF_NUM(1) | DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_TAPE, 0,
|
||||
dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -674,8 +677,9 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
case 1:
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d %d ",
|
||||
unit, reclen);
|
||||
/* We don't set EOF on BSR */
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->POS++;
|
||||
@@ -712,8 +716,9 @@ t_stat mt_srv(UNIT * uptr)
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d\n", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d %d\n",
|
||||
unit, reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
@@ -746,8 +751,8 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
case 1:
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d %d ", unit, reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->POS = 3;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
@@ -785,8 +790,8 @@ t_stat mt_srv(UNIT * uptr)
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip frec unit=%d %d", unit, reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
@@ -881,9 +886,17 @@ mt_ini(UNIT * uptr, t_bool f)
|
||||
}
|
||||
|
||||
t_stat
|
||||
mt_reset(DEVICE * dptr)
|
||||
mt_boot(int32 unit_num, DEVICE * dptr)
|
||||
{
|
||||
return SCPE_OK;
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
uptr->CMD &= UNIT_ADDR_MASK;
|
||||
uptr->CMD |= MT_ODD|MT_CONV|MT_MDEN_800;
|
||||
}
|
||||
return chan_boot(GET_UADDR(uptr->CMD), dptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
@@ -910,18 +923,21 @@ mt_detach(UNIT * uptr)
|
||||
return sim_tape_detach(uptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
mt_boot(int32 unit_num, DEVICE * dptr)
|
||||
t_stat mt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
UNIT *uptr = &dptr->units[unit_num];
|
||||
fprintf (st, "2400 Magnetic Tape\n\n");
|
||||
fprint_set_help (st, dptr);
|
||||
fprint_show_help (st, dptr);
|
||||
fprintf (st, "\nThe type options can be used only when a unit is not attached to a file. The\n");
|
||||
fprintf (st, "bad block option can be used only when a unit is attached to a file.\n");
|
||||
fprintf (st, "The magtape supports the BOOT command.\n");
|
||||
sim_tape_attach_help (st, dptr, uptr, flag, cptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
uptr->CMD &= UNIT_ADDR_MASK;
|
||||
uptr->CMD |= MT_ODD|MT_CONV|MT_MDEN_800;
|
||||
}
|
||||
return chan_boot(GET_UADDR(uptr->CMD), dptr);
|
||||
const char *mt_description (DEVICE *dptr)
|
||||
{
|
||||
return "2400 magnetic tape" ;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user