1
0
mirror of https://github.com/simh/simh.git synced 2026-05-01 05:48:35 +00:00

Notes For V3.8

The makefile now works for Linux and most Unix's. Howevr, for Solaris
and MacOS, you must first export the OSTYPE environment variable:

> export OSTYPE
> make

Otherwise, you will get build errors.

1. New Features

1.1 3.8-0

1.1.1 SCP and Libraries

- BREAK, NOBREAK, and SHOW BREAK with no argument will set, clear, and
  show (respectively) a breakpoint at the current PC.

1.1.2 GRI

- Added support for the GRI-99 processor.

1.1.3 HP2100

- Added support for the BACI terminal interface.
- Added support for RTE OS/VMA/EMA, SIGNAL, VIS firmware extensions.

1.1.4 Nova

- Added support for 64KW memory (implemented in third-party CPU's).

1.1.5 PDP-11

- Added support for DC11, RC11, KE11A, KG11A.
- Added modem control support for DL11.
- Added ASCII character support for all 8b devices.

1.2 3.8-1

1.2.1 SCP and libraries

- Added capability to set line connection order for terminal multiplexers.

1.2.2 HP2100

- Added support for 12620A/12936A privileged interrupt fence.
- Added support for 12792C eight-channel asynchronous multiplexer.

2. Bugs Fixed

Please see the revision history on http://simh.trailing-edge.com or
in the source module sim_rev.h.
This commit is contained in:
Bob Supnik
2009-02-08 09:06:00 -08:00
committed by Mark Pizzolato
parent 59aa4a73b1
commit 9c4779c061
286 changed files with 40587 additions and 19094 deletions

View File

@@ -1,6 +1,6 @@
/* lgp_cpu.c: LGP CPU simulator
Copyright (c) 2004-2005, Robert M. Supnik
Copyright (c) 2004-2008, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -279,7 +279,8 @@ PC = PC & AMASK; /* mask PC */
sim_cancel_step (); /* defang SCP step */
if (lgp21_sov) { /* stop sense pending? */
lgp21_sov = 0;
if (!OVF) PC = (PC + 1) & AMASK; /* ovf off? skip */
if (!OVF) /* ovf off? skip */
PC = (PC + 1) & AMASK;
else OVF = 0; /* on? reset */
}
@@ -287,7 +288,8 @@ if (lgp21_sov) { /* stop sense pending? *
do {
if (sim_interval <= 0) { /* check clock queue */
if (r = sim_process_event ()) break;
if (r = sim_process_event ())
break;
}
if (delay > 0) { /* delay to next instr */
@@ -374,7 +376,7 @@ switch (op) { /* case on opcode */
case OP_T: /* conditional transfer */
if ((A & SIGN) || /* A < 0 or */
((ir & SIGN) && t_switch)) { /* -T and Tswitch set? */
((ir & SIGN) && t_switch)) { /* -T and Tswitch set? */
PCQ_ENTRY;
PC = ea; /* transfer */
}
@@ -416,7 +418,8 @@ switch (op) { /* case on opcode */
case OP_D: /* divide */
dat = Read (ea); /* get operand */
if (Div32 (A, dat, &A)) ovf_this_cycle = TRUE; /* divide; overflow? */
if (Div32 (A, dat, &A)) /* divide; overflow? */
ovf_this_cycle = TRUE;
delay = I_delay (opc, ea, op);
break;
@@ -431,7 +434,8 @@ switch (op) { /* case on opcode */
case OP_P: /* output */
if (Q_LGP21) { /* LGP-21 */
ch = A >> 26; /* char, 6b */
if (ir & SIGN) ch = (ch & 0x3C) | 2; /* 4b? convert */
if (ir & SIGN) /* 4b? convert */
ch = (ch & 0x3C) | 2;
dev = I_GETTK (ir); /* device select */
}
else { /* LGP-30 */
@@ -468,7 +472,8 @@ switch (op) { /* case on opcode */
((ea & 0x100) && !bp4) || /* or if */
((ir & SIGN) && !OVF)) /* ovf sel and off */
PC = (PC + 1) & AMASK;
if (ir & SIGN) OVF = 0; /* -Z? clr overflow */
if (ir & SIGN) /* -Z? clr overflow */
OVF = 0;
}
else { /* stop */
lgp21_sov = (ir & SIGN)? 1: 0; /* pending sense? */
@@ -476,12 +481,14 @@ switch (op) { /* case on opcode */
}
}
else { /* LGP-30 */
if (out_done) out_done = 0; /* P complete? */
if (out_done) /* P complete? */
out_done = 0;
else if (((ea & 0x800) && bp32) || /* bpt switch set? */
((ea & 0x400) && bp16) ||
((ea & 0x200) && bp8) ||
((ea & 0x100) && bp4)) ; /* don't stop or stall */
else if (out_strt) reason = STOP_STALL; /* P pending? stall */
else if (out_strt) /* P pending? stall */
reason = STOP_STALL;
else reason = STOP_STOP; /* no, stop */
}
delay = I_delay (sim_grtime (), ea, op); /* next instruction */
@@ -489,7 +496,8 @@ switch (op) { /* case on opcode */
}
if (ovf_this_cycle) {
if (Q_LGP21) OVF = 1; /* LGP-21? set OVF */
if (Q_LGP21) /* LGP-21? set OVF */
OVF = 1;
else reason = STOP_OVF; /* LGP-30? stop */
}
return reason;
@@ -512,7 +520,8 @@ return;
uint32 shift_in (uint32 a, uint32 dat, uint32 sh4)
{
if (sh4) return (((a << 4) | (dat >> 2)) & DMASK);
if (sh4)
return (((a << 4) | (dat >> 2)) & DMASK);
return (((a << 6) | dat) & DMASK);
}
@@ -524,7 +533,8 @@ uint32 sgn = a ^ b;
uint32 ah, bh, al, bl, rhi, rlo, rmid1, rmid2;
if ((a == 0) || (b == 0)) { /* zero argument? */
if (low) *low = 0;
if (low)
*low = 0;
return 0;
}
a = ABS (a);
@@ -539,14 +549,17 @@ rmid2 = al * bh;
rlo = al * bl;
rhi = rhi + ((rmid1 >> 16) & M16) + ((rmid2 >> 16) & M16);
rmid1 = (rlo + (rmid1 << 16)) & M32; /* add mid1 to lo */
if (rmid1 < rlo) rhi = rhi + 1; /* carry? incr hi */
if (rmid1 < rlo) /* carry? incr hi */
rhi = rhi + 1;
rmid2 = (rmid1 + (rmid2 << 16)) & M32; /* add mid2 to to */
if (rmid2 < rmid1) rhi = rhi + 1; /* carry? incr hi */
if (rmid2 < rmid1) /* carry? incr hi */
rhi = rhi + 1;
if (sgn & SIGN) { /* result negative? */
rmid2 = NEG (rmid2); /* negate */
rhi = (~rhi + (rmid2 == 0)) & M32;
}
if (low) *low = rmid2; /* low result */
if (low) /* low result */
*low = rmid2;
return rhi & M32;
}
@@ -559,7 +572,8 @@ uint32 i, quo;
dvd = ABS (dvd);
dvr = ABS (dvr);
if (dvd >= dvr) return TRUE;
if (dvd >= dvr)
return TRUE;
for (i = quo = 0; i < 31; i++) { /* 31 iterations */
quo = quo << 1; /* shift quotient */
dvd = dvd << 1; /* shift dividend */
@@ -569,8 +583,10 @@ for (i = quo = 0; i < 31; i++) { /* 31 iterations */
}
}
quo = (quo + 1) & MMASK; /* round low bit */
if (sgn & SIGN) quo = NEG (quo); /* result -? */
if (q) *q = quo; /* return quo */
if (sgn & SIGN) /* result -? */
quo = NEG (quo);
if (q) /* return quo */
*q = quo;
return FALSE; /* no overflow */
}
@@ -599,10 +615,12 @@ else {
opdelta = (oprp - curp + NSC_30) & SCMASK_30;
}
if (tmax == 0) { /* skip ea calc? */
if (pcdelta >= tmin) return pcdelta - 1; /* new PC >= min? */
if (pcdelta >= tmin) /* new PC >= min? */
return pcdelta - 1;
return pcdelta + nsc - 1;
}
if ((opdelta >= tmin) && (opdelta <= tmax)) return pcdelta - 1;
if ((opdelta >= tmin) && (opdelta <= tmax))
return pcdelta - 1;
return pcdelta + nsc - 1;
}
@@ -619,7 +637,8 @@ lgp21_sov = 0;
delay = 0;
lgp_vm_init ();
pcq_r = find_reg ("CQ", NULL, dptr);
if (pcq_r) pcq_r->qptr = 0;
if (pcq_r)
pcq_r->qptr = 0;
else return SCPE_IERR;
sim_brk_types = sim_brk_dflt = SWMASK ('E');
return SCPE_OK;
@@ -629,7 +648,8 @@ return SCPE_OK;
t_stat cpu_set_30opt (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (Q_LGP21) return SCPE_ARG;
if (Q_LGP21)
return SCPE_ARG;
return SCPE_OK;
}
@@ -637,9 +657,12 @@ return SCPE_OK;
t_stat cpu_set_30opt_i (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (Q_LGP21 || (cptr == NULL)) return SCPE_ARG;
if (strcmp (cptr, "TTI") == 0) uptr->flags = uptr->flags & ~UNIT_INPT;
else if (strcmp (cptr, "PTR") == 0) uptr->flags = uptr->flags | UNIT_INPT;
if (Q_LGP21 || (cptr == NULL))
return SCPE_ARG;
if (strcmp (cptr, "TTI") == 0)
uptr->flags = uptr->flags & ~UNIT_INPT;
else if (strcmp (cptr, "PTR") == 0)
uptr->flags = uptr->flags | UNIT_INPT;
else return SCPE_ARG;
return SCPE_OK;
}
@@ -648,9 +671,12 @@ return SCPE_OK;
t_stat cpu_set_30opt_o (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (Q_LGP21 || (cptr == NULL)) return SCPE_ARG;
if (strcmp (cptr, "TTO") == 0) uptr->flags = uptr->flags & ~UNIT_OUTPT;
else if (strcmp (cptr, "PTP") == 0) uptr->flags = uptr->flags | UNIT_OUTPT;
if (Q_LGP21 || (cptr == NULL))
return SCPE_ARG;
if (strcmp (cptr, "TTO") == 0)
uptr->flags = uptr->flags & ~UNIT_OUTPT;
else if (strcmp (cptr, "PTP") == 0)
uptr->flags = uptr->flags | UNIT_OUTPT;
else return SCPE_ARG;
return SCPE_OK;
}
@@ -659,7 +685,8 @@ return SCPE_OK;
t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (val) uptr->flags = uptr->flags & ~(UNIT_IN4B|UNIT_INPT|UNIT_OUTPT);
if (val)
uptr->flags = uptr->flags & ~(UNIT_IN4B|UNIT_INPT|UNIT_OUTPT);
return reset_all (0);
}
@@ -668,8 +695,10 @@ return reset_all (0);
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fputs (Q_LGP21? "LGP-21": "LGP-30", st);
if (uptr->flags & UNIT_TTSS_D) fputs (", track/sector", st);
if (uptr->flags & UNIT_LGPH_D) fputs (", LGP hex", st);
if (uptr->flags & UNIT_TTSS_D)
fputs (", track/sector", st);
if (uptr->flags & UNIT_LGPH_D)
fputs (", LGP hex", st);
fputs (Q_MANI? ", manual": ", tape", st);
if (!Q_LGP21) {
fputs (Q_IN4B? ", 4b": ", 6b", st);
@@ -683,8 +712,10 @@ return SCPE_OK;
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
{
if (addr >= MEMSIZE) return SCPE_NXM;
if (vptr != NULL) *vptr = Read (addr);
if (addr >= MEMSIZE)
return SCPE_NXM;
if (vptr != NULL)
*vptr = Read (addr);
return SCPE_OK;
}
@@ -692,7 +723,8 @@ return SCPE_OK;
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
{
if (addr >= MEMSIZE) return SCPE_NXM;
if (addr >= MEMSIZE)
return SCPE_NXM;
Write (addr, val);
return SCPE_OK;
}
@@ -706,12 +738,14 @@ t_stat r;
if (cptr) {
inst = get_uint (cptr, 16, DMASK, &r);
if (r != SCPE_OK) return r;
if (r != SCPE_OK)
return r;
}
else inst = IR;
while ((r = cpu_one_inst (PC, inst)) == STOP_STALL) {
sim_interval = 0;
if (r = sim_process_event ()) return r;
if (r = sim_process_event ())
return r;
}
return r;
}
@@ -725,7 +759,8 @@ t_stat r;
if (cptr) {
inst = get_uint (cptr, 16, DMASK, &r);
if (r != SCPE_OK) return r;
if (r != SCPE_OK)
return r;
IR = inst;
}
else IR = A;