From 27bd6b81aa1b2011286e09c0555ce5dc71f9ee38 Mon Sep 17 00:00:00 2001 From: Peter Schorn Date: Thu, 30 Mar 2023 14:00:11 +0200 Subject: [PATCH] Fix UTF-8 encoding for five files --- HP2100/hp2100_cpu5.c | 2 +- I650/i650_cpu.c | 714 +++++++++++++++++++++--------------------- Ibm1130/ibm1130_sca.c | 14 +- PDP10/pdp10_tim.c | 48 +-- SIMH-V4-status.md | 290 ++++++++--------- 5 files changed, 534 insertions(+), 534 deletions(-) diff --git a/HP2100/hp2100_cpu5.c b/HP2100/hp2100_cpu5.c index aff55622..5cce3c45 100644 --- a/HP2100/hp2100_cpu5.c +++ b/HP2100/hp2100_cpu5.c @@ -1676,7 +1676,7 @@ if (xidex) { /* is EMA declared? */ } } /* not EMA reference */ ndim = ReadW(dtbl++); -if (ndim<0) goto em15; /* negative ´dimensions */ +if (ndim<0) goto em15; /* negative dimensions */ sum = 0; /* accu for index calc */ while (ndim > 0) { MR = ReadW (atbl++); /* fetch address of A(N) */ diff --git a/I650/i650_cpu.c b/I650/i650_cpu.c index 67404d58..adf7b37b 100644 --- a/I650/i650_cpu.c +++ b/I650/i650_cpu.c @@ -22,40 +22,40 @@ cpu IBM 650 central processor From Wikipedia: The IBM 650 Magnetic Drum Data-Processing Machine is one of - IBM's early computers, and the world’s first mass-produced computer. It was - announced in 1953 and in 1956 enhanced as the IBM 650 RAMAC with the - addition of up to four disk storage units. Almost 2,000 systems were + IBM's early computers, and the world’s first mass-produced computer. It was + announced in 1953 and in 1956 enhanced as the IBM 650 RAMAC with the + addition of up to four disk storage units. Almost 2,000 systems were produced, the last in 1962. The 650 was a two-address, bi-quinary coded decimal computer (both data and - addresses were decimal), with memory on a rotating magnetic drum. Character - support was provided by the input/output units converting punched card - alphabetical and special character encodings to/from a two-digit decimal + addresses were decimal), with memory on a rotating magnetic drum. Character + support was provided by the input/output units converting punched card + alphabetical and special character encodings to/from a two-digit decimal code. - Rotating drum memory provided 1,000, 2,000, or 4,000 words of memory (a - signed 10-digit number or five characters per word) at addresses 0000 to + Rotating drum memory provided 1,000, 2,000, or 4,000 words of memory (a + signed 10-digit number or five characters per word) at addresses 0000 to 0999, 1999, or 3999 respectively. - Instructions read from the drum went to a program register (in current - terminology, an instruction register). Data read from the drum went through - a 10-digit distributor. The 650 had a 20-digit accumulator, divided into - 10-digit lower and upper accumulators with a common sign. Arithmetic was - performed by a one-digit adder. The console (10 digit switches, one sign - switch, and 10 bi-quinary display lights), distributor, lower and upper + Instructions read from the drum went to a program register (in current + terminology, an instruction register). Data read from the drum went through + a 10-digit distributor. The 650 had a 20-digit accumulator, divided into + 10-digit lower and upper accumulators with a common sign. Arithmetic was + performed by a one-digit adder. The console (10 digit switches, one sign + switch, and 10 bi-quinary display lights), distributor, lower and upper accumulators were all addressable; 8000, 8001, 8002, 8003 respectively. - The 650 instructions consisted of a two-digit operation code, a four-digit - data address and the four-digit address of the next instruction. The sign - was ignored on the basic machine, but was used on machines with optional - features. The base machine had 44 operation codes. Additional operation - codes were provided for options, such as floating point, core storage, - index registers and additional I/O devices. With all options installed, + The 650 instructions consisted of a two-digit operation code, a four-digit + data address and the four-digit address of the next instruction. The sign + was ignored on the basic machine, but was used on machines with optional + features. The base machine had 44 operation codes. Additional operation + codes were provided for options, such as floating point, core storage, + index registers and additional I/O devices. With all options installed, there were 97 operation codes. The programmer visible system state for the IBM 650 is: - CSW <10:1> Console Switches + CSW <10:1> Console Switches ACC[0] <10:1> Lower Accumulator register ACC[1] <10:1> Upper Accumulator register DIST <10:1> Distributor @@ -75,9 +75,9 @@ Instruction support as described in BitSavers 22-6060-2_650_OperMan.pdf - IBM 653 Storage Unit can be enabled as an option. This simulates the following + IBM 653 Storage Unit can be enabled as an option. This simulates the following - Immediate Access Storage (IAS) - - Index registers + - Index registers - Floating Point support - Synchronizers 2 & 3 @@ -129,8 +129,8 @@ const char *cpu_description (DEVICE *dptr); // DRUM Memory t_int64 DRUM[MAXDRUMSIZE] = {0}; int DRUM_NegativeZeroFlag[MAXDRUMSIZE] = {0}; -char DRUM_Symbolic_Buffer[MAXDRUMSIZE * 80] = {0}; // does not exists on real hw. Used to keep symbolic info -char IAS_Symbolic_Buffer[60 * 80] = {0}; // does not exists on real hw. Used to keep symbolic info +char DRUM_Symbolic_Buffer[MAXDRUMSIZE * 80] = {0}; // does not exists on real hw. Used to keep symbolic info +char IAS_Symbolic_Buffer[60 * 80] = {0}; // does not exists on real hw. Used to keep symbolic info // IO Synchronizer for card read-punch buffer t_int64 IOSync[10] = {0}; @@ -142,10 +142,10 @@ int IAS_NegativeZeroFlag[60] = {0}; int IAS_TimingRing = 0; // interlock counters -int InterLockCount[8] = {0}; +int InterLockCount[8] = {0}; // address where rotating drum is currently positioned (0-49) -int DrumAddr; +int DrumAddr; // increment umber of word counts elapsed from starting of simulator -> this is the global time measurement t_int64 GlobalWordTimeCount=1; @@ -202,7 +202,7 @@ MTAB cpu_mod[] = { {UNIT_MSIZE, MEMAMOUNT(2), "4K", "4K", &cpu_set_size}, {OPTION_STOR, 0, NULL, "NOSTORAGEUNIT", NULL}, {OPTION_STOR, OPTION_STOR, "Storage Unit", "STORAGEUNIT", NULL}, - {OPTION_CNTRL, 0, NULL, "NOCNTRLUNIT", NULL}, + {OPTION_CNTRL, 0, NULL, "NOCNTRLUNIT", NULL}, {OPTION_CNTRL, OPTION_CNTRL, "Control Unit", "CNTRLUNIT", NULL}, {OPTION_SOAPMNE, 0, NULL, "DEFAULTMNE", NULL}, {OPTION_SOAPMNE, OPTION_SOAPMNE, "Using SOAP Mnemonics", "SOAPMNE", NULL}, @@ -226,34 +226,34 @@ DEVICE cpu_dev = { t_stat cpu_svc (UNIT *uptr) { - // poll kbd to sense ^E to halt cpu execution. + // poll kbd to sense ^E to halt cpu execution. sim_activate_after (uptr, 300*1000); // poll each 300 msec sim_poll_kbd(); return SCPE_OK; -} +} // return 0 if addr invalid, 1 if addr valid depending on allowed addrs given by ValidDA // set the ias TimingRing to AR is IAS is accessed -int IsDrumAddrOk(int AR, int ValidDA) +int IsDrumAddrOk(int AR, int ValidDA) { - // check if AR should be 9000 - if ((STOR) && (ValidDA & vda_9000)) + // check if AR should be 9000 + if ((STOR) && (ValidDA & vda_9000)) return (AR == 9000) ? 1:0; // Drum address - if ((AR >= 0) && (AR < DRUMSIZE)) - return (ValidDA & vda_D) ? 1:0; + if ((AR >= 0) && (AR < DRUMSIZE)) + return (ValidDA & vda_D) ? 1:0; // cpu registers: acc (lo&hi), distibutor, console switch reg: ok to check for Addr validity, ok to read, cannot write to it - if ((AR >= 8000) && (AR <= 8003)) - return (ValidDA & vda_A) ? 1:0; + if ((AR >= 8000) && (AR <= 8003)) + return (ValidDA & vda_A) ? 1:0; // index registers (ir) present if Storage Unit is enabled: ok to check for Addr validity, ok to read, cannot write to it if ((STOR) && (AR >= 8005) && (AR <= 8007)) - return (ValidDA & vda_I) ? 1:0; + return (ValidDA & vda_I) ? 1:0; // tape address present is tapes are enabled: ok to check for Addr validity, cannot read/write to it if ((CNTRL) && (AR >= 8010) && (AR <= 8015)) - return (ValidDA & vda_T) ? 1:0; + return (ValidDA & vda_T) ? 1:0; // inmediate access storage (ias) if Storage Unit is enabled: ok to check for Addr validity, ok to read/write - if ((STOR) && (AR >= 9000) && (AR <= 9059)) { + if ((STOR) && (AR >= 9000) && (AR <= 9059)) { if (ValidDA & vda_S) { IAS_TimingRing = AR - 9000; // set Timing ring on address accesed return 1; @@ -289,27 +289,27 @@ int ReadAddr(int AR, t_int64 * d, int * NegZero) // read from drum? if ((AR >= 0) && (AR < DRUMSIZE)) { - *d = DRUM[AR]; + *d = DRUM[AR]; neg = DRUM_NegativeZeroFlag[AR]; if (*d) DRUM_NegativeZeroFlag[AR] = 0; } else // read from cpu registers? - if (AR == 8000) {*d = CSW; neg=0; } else + if (AR == 8000) {*d = CSW; neg=0; } else if (AR == 8001) {*d = DIST; neg=DistNegativeZeroFlag; } else if (AR == 8002) {*d = ACC[0]; neg=AccNegativeZeroFlag; } else - if (AR == 8003) {*d = ACC[1]; neg=AccNegativeZeroFlag; } else - // read index registers (ir) ? + if (AR == 8003) {*d = ACC[1]; neg=AccNegativeZeroFlag; } else + // read index registers (ir) ? if ((STOR) && (AR == 8005)) {*d = IR[0]; neg=0; } else if ((STOR) && (AR == 8006)) {*d = IR[1]; neg=0; } else if ((STOR) && (AR == 8007)) {*d = IR[2]; neg=0; } else - // tape address ? - if ((CNTRL) && (AR >= 8010) && (AR <= 8015)) { + // tape address ? + if ((CNTRL) && (AR >= 8010) && (AR <= 8015)) { // cannot read/write to tape addresses return 0; - } else + } else // read inmediate access storage (ias)? - if ((STOR) && (AR >= 9000) && (AR <= 9059)) { - IAS_TimingRing = AR - 9000; + if ((STOR) && (AR >= 9000) && (AR <= 9059)) { + IAS_TimingRing = AR - 9000; *d = IAS[IAS_TimingRing]; neg = IAS_NegativeZeroFlag[IAS_TimingRing]; if (*d) IAS_NegativeZeroFlag[IAS_TimingRing] = 0; @@ -322,7 +322,7 @@ int ReadAddr(int AR, t_int64 * d, int * NegZero) return 1; } -// shift acc 1 digit. If direction > 0 to the left, if direction < 0 to the right. +// shift acc 1 digit. If direction > 0 to the left, if direction < 0 to the right. // Return digit going out of acc (with sign) int ShiftAcc(int direction) { @@ -342,13 +342,13 @@ int ShiftAcc(int direction) } else if (direction < 0) { // shift right m = Shift_Digits(&a1, -1); // m = intermediate digit that goes from one acc to the other n = Shift_Digits(&a0, -1); // n = Lower Acc units digit shifted out on the right - a0 = a0 + (t_int64) m * (1000000000L); + a0 = a0 + (t_int64) m * (1000000000L); } if (neg) {a1=-a1; a0=-a0; n=-n;} - ACC[0] = a0; - ACC[1] = a1; - if ((neg == 1) && (a0 == 0) && (a1 == 0)) AccNegativeZeroFlag = 1; + ACC[0] = a0; + ACC[1] = a1; + if ((neg == 1) && (a0 == 0) && (a1 == 0)) AccNegativeZeroFlag = 1; return n; } @@ -356,13 +356,13 @@ int ShiftAcc(int direction) // float value format = mmmmmmmcc = 0.m x 10^(c-50) // mmmmmmm = mantissa // cc = modified characteristic (== exponent) -// get modified characteristic of float d +// get modified characteristic of float d int GetExp(t_int64 d) { return (AbsWord(d) % 100); } -// set modified characteristic of float d +// set modified characteristic of float d t_int64 SetExp(t_int64 d, int exp) { int neg = 0; @@ -374,18 +374,18 @@ t_int64 SetExp(t_int64 d, int exp) } // set result into ACC[1] and ACC[0] for float mult and division -// get a 10 digits mantissa en ACC[1] +// get a 10 digits mantissa en ACC[1] // round to the 8th digit // add the modified characteristic (exp) // add sign, check for zero void MantissaRoundAndNormalizeToFloat(int * CpuStepsUsed, int neg, int exp) { // if high order digit of mantissa is zero, shift left once - if (Get_HiDigit(ACC[1]) == 0) { + if (Get_HiDigit(ACC[1]) == 0) { ShiftAcc(1); *CpuStepsUsed = *CpuStepsUsed + 2; if (exp == 0) { - OV = 1; + OV = 1; } else { exp--; } @@ -397,17 +397,17 @@ void MantissaRoundAndNormalizeToFloat(int * CpuStepsUsed, int neg, int exp) ACC[1] = ACC[1] / 10; *CpuStepsUsed = *CpuStepsUsed + 2; if (exp == 99) { - OV = 1; + OV = 1; } else { exp++; } } } - ACC[1] = SetExp(ACC[1], 0); + ACC[1] = SetExp(ACC[1], 0); // normalize mantissas - while (( ACC[1] != 0) && (Get_HiDigit(ACC[1]) == 0)) { - if (exp == 0) { - OV = 1; + while (( ACC[1] != 0) && (Get_HiDigit(ACC[1]) == 0)) { + if (exp == 0) { + OV = 1; break; // if zero, underflow } else { exp--; @@ -433,7 +433,7 @@ int AddFloatToAcc(int bSubstractFlag, int bAbsFlag, int bNormalizeFlag) int n, neg; t_int64 d; - AccNegativeZeroFlag = 0; + AccNegativeZeroFlag = 0; nSteps = 0; n = GetExp(ACC[1]) - GetExp(DIST); @@ -445,9 +445,9 @@ int AddFloatToAcc(int bSubstractFlag, int bAbsFlag, int bNormalizeFlag) ACC[1] = 0; } else { if (n < 0) { // if between -1 and -8 - n = -n; // just remove sign on number of shifts to be done + n = -n; // just remove sign on number of shifts to be done } else { // if between 1 and 8 - d = ACC[1]; + d = ACC[1]; ACC[1] = DIST; DIST = d; // exchange distrib and upper acc nSteps += 2; } @@ -465,9 +465,9 @@ int AddFloatToAcc(int bSubstractFlag, int bAbsFlag, int bNormalizeFlag) if (bAbsFlag) if (d < 0) d = -d; if (bSubstractFlag) d = -d; - if (((ACC[1] > 0) && (d < 0)) || ((ACC[1] < 0) && (d > 0))) nSteps += 4; + if (((ACC[1] > 0) && (d < 0)) || ((ACC[1] < 0) && (d > 0))) nSteps += 4; - ACC[1] = (ACC[1] / 100) + (d / 100); // add/substract mantissas (positions 10-3) + ACC[1] = (ACC[1] / 100) + (d / 100); // add/substract mantissas (positions 10-3) n = GetExp(DIST); // get modified characteristic from dist if (ACC[1] < 0) { ACC[1] = -ACC[1]; neg=-1; @@ -478,11 +478,11 @@ int AddFloatToAcc(int bSubstractFlag, int bAbsFlag, int bNormalizeFlag) if (ACC[1] >= D8) { // overflow? if ((ACC[1] % 10) >= 5) { // should round? ACC[1] = ACC[1] / 10 + 1; // yes, shift right, keep extra 1 in high pos, add rounding - nSteps += 4; + nSteps += 4; } else { ACC[1] = ACC[1] / 10; // no, just shift } - n++; // add 1 to dist modified characteristic + n++; // add 1 to dist modified characteristic if (n > 99) {OV = 1; n=0;} // overflow. Set modified characteristic to zero nSteps += 4; } @@ -492,31 +492,31 @@ int AddFloatToAcc(int bSubstractFlag, int bAbsFlag, int bNormalizeFlag) bNormalizeFlag = 0; // must not normalize nSteps += 2; } - ACC[1] = SetExp(neg * ACC[1] * 100, n); // insert modified characteristic of dist into upper acc + ACC[1] = SetExp(neg * ACC[1] * 100, n); // insert modified characteristic of dist into upper acc ACC[0] = 0; // lower acc set to zero if (bNormalizeFlag) { - while(Get_HiDigit(ACC[1]) == 0) { // while hi digit (digit 10) is zero -> normalize + while(Get_HiDigit(ACC[1]) == 0) { // while hi digit (digit 10) is zero -> normalize n = GetExp(ACC[1]); // get modified characteristic - if (n == 0) { + if (n == 0) { OV = 1; break; // if zero, underflow } n--; - ACC[1] = SetExp(ACC[1]/100 * 1000, n); // left shift mantissa, set modified characteristic + ACC[1] = SetExp(ACC[1]/100 * 1000, n); // left shift mantissa, set modified characteristic nSteps += 3; } } return nSteps; } -int bAccNegComplement; // flag to signals acc has complemented a negative ass (== sign adjust) +int bAccNegComplement; // flag to signals acc has complemented a negative ass (== sign adjust) // needed to compute execution cycles taken by the intruction // add to accumulator, set Overflow -void AddToAcc(t_int64 a1, t_int64 a0, int bSetOverflow) +void AddToAcc(t_int64 a1, t_int64 a0, int bSetOverflow) { - AccNegativeZeroFlag = 0; + AccNegativeZeroFlag = 0; bAccNegComplement = 0; - + ACC[0] += a0; ACC[1] += a1; @@ -526,25 +526,25 @@ void AddToAcc(t_int64 a1, t_int64 a0, int bSetOverflow) // ajust sign if ((ACC[0] > 0) && (ACC[1] < 0)) { - ACC[0] -= D10; ACC[1]++; + ACC[0] -= D10; ACC[1]++; bAccNegComplement = 1; } if ((ACC[0] < 0) && (ACC[1] > 0)) { - ACC[0] += D10; ACC[1]--; + ACC[0] += D10; ACC[1]--; bAccNegComplement = 1; } // check overflow if (bSetOverflow) { - if ((ACC[1] >= D10) || (ACC[1] <= -D10)) { - ACC[1] = ACC[1] % D10; - OV=1; + if ((ACC[1] >= D10) || (ACC[1] <= -D10)) { + ACC[1] = ACC[1] % D10; + OV=1; } } } -t_int64 SetDA(t_int64 d, int DA) +t_int64 SetDA(t_int64 d, int DA) { int neg = 0; @@ -554,22 +554,22 @@ t_int64 SetDA(t_int64 d, int DA) if (d < 0) {d=-d; neg=1;} // extract parts of word - op = Shift_Digits(&d, 2); + op = Shift_Digits(&d, 2); nn = Shift_Digits(&d, 4); // discard current DA - IA = Shift_Digits(&d, 4); + IA = Shift_Digits(&d, 4); // rebuild word with new DA - d = (t_int64) op * D8 + - (t_int64) DA * D4 + + d = (t_int64) op * D8 + + (t_int64) DA * D4 + (t_int64) IA; if (neg) d=-d; return d; } // set last 4 digits in d with IA contents -t_int64 SetIA(t_int64 d, int IA) +t_int64 SetIA(t_int64 d, int IA) { int neg = 0; - + if (IA < 0) IA=-IA; if (d < 0) {d=-d; neg=1;} d = d - ( d % D4); @@ -579,10 +579,10 @@ t_int64 SetIA(t_int64 d, int IA) } // set last 2 digits in d with IA contents -t_int64 SetIA2(t_int64 d, int n) +t_int64 SetIA2(t_int64 d, int n) { int neg = 0; - + if (n < 0) n=-n; if (d < 0) {d=-d; neg=1;} d = d - ( d % 100); @@ -594,11 +594,11 @@ t_int64 SetIA2(t_int64 d, int n) // normalize to 4 digits, 10 complements void NormalizeAddr(int * addr, int bAllowNegativeValue) { - while (*addr >= 10000) *addr -= 10000; + while (*addr >= 10000) *addr -= 10000; if (bAllowNegativeValue) { - while (*addr <= -10000) *addr += 10000; + while (*addr <= -10000) *addr += 10000; } else { - while (*addr < 0) *addr += 10000; + while (*addr < 0) *addr += 10000; } } @@ -630,7 +630,7 @@ int ApplyIndexRegister(int * addr) int ApplyIndexRegisterModel4(int * DA, int * IA) { int n, tagDA, tagIA, nIndexApplied; - + tagDA = tagIA = 0; nIndexApplied = 0; @@ -640,7 +640,7 @@ int ApplyIndexRegisterModel4(int * DA, int * IA) nIndexApplied += ApplyIndexRegister(IA); } return nIndexApplied; - } + } if ((*DA >= 4000) && (*DA < 8000)) { *DA -= 4000; // remove tag on DA address tagIA = 1; @@ -666,8 +666,8 @@ int ApplyIndexRegisterModel4(int * DA, int * IA) return nIndexApplied; } -// opcode decode -// input: prior to call DecodeOpcode PR cpu register must be loaded with the word to decode +// opcode decode +// input: prior to call DecodeOpcode PR cpu register must be loaded with the word to decode // output: decoded instruction as opcode, DA, IA parts // returns opname: points to opcode name or NULL if undef opcode CONST char * DecodeOpcode(t_int64 d, int * opcode, int * DA, int * IA) @@ -690,7 +690,7 @@ CONST char * DecodeOpcode(t_int64 d, int * opcode, int * DA, int * IA) } else if (opt == opTLE) { // opcode available if Table LookUo Feature is present if ((cpu_unit.flags & OPTION_TLE) == 0) return NULL; - } + } return opname; } @@ -706,26 +706,26 @@ int TransferIAS(CONST char * dir, int bEOB) n = f0 = t0 = f1 = t1 = ec = 0; while (1) { - if (dir[0] == 'D') { + if (dir[0] == 'D') { // copy drum to ias d = IAS[IAS_TimingRing] = DRUM[AR]; ZeroNeg = IAS_NegativeZeroFlag[IAS_TimingRing] = DRUM_NegativeZeroFlag[AR]; - sim_debug(DEBUG_DETAIL, &cpu_dev, "... DRUM %04d to IAS %04d: %06d%04d%c '%s'\n", - AR, IAS_TimingRing+9000, printfw(d,ZeroNeg), + sim_debug(DEBUG_DETAIL, &cpu_dev, "... DRUM %04d to IAS %04d: %06d%04d%c '%s'\n", + AR, IAS_TimingRing+9000, printfw(d,ZeroNeg), word_to_ascii(s, 1, 5, d)); if (n==0) {f0=AR; t0=IAS_TimingRing+9000;} f1=AR; t1=IAS_TimingRing+9000; // copy symbolic info from drum to ias (so code copies to ias to be executed faster // keeps its symbolic info) memset(&IAS_Symbolic_Buffer[IAS_TimingRing * 80], 0, 80); // clear ias symbolic info - sim_strlcpy(&IAS_Symbolic_Buffer[IAS_TimingRing * 80], + sim_strlcpy(&IAS_Symbolic_Buffer[IAS_TimingRing * 80], &DRUM_Symbolic_Buffer[AR * 80], 80); } else { // copy ias to drum d = DRUM[AR] = IAS[IAS_TimingRing]; ZeroNeg = DRUM_NegativeZeroFlag[AR] = IAS_NegativeZeroFlag[IAS_TimingRing]; - sim_debug(DEBUG_DETAIL, &cpu_dev, "... IAS %04d to DRUM %04d: %06d%04d%c '%s'\n", - IAS_TimingRing+9000, AR, printfw(d,ZeroNeg), + sim_debug(DEBUG_DETAIL, &cpu_dev, "... IAS %04d to DRUM %04d: %06d%04d%c '%s'\n", + IAS_TimingRing+9000, AR, printfw(d,ZeroNeg), word_to_ascii(s, 1, 5, d)); if (n==0) {t0=AR; f0=IAS_TimingRing+9000;} t1=AR; f1=IAS_TimingRing+9000; @@ -741,37 +741,37 @@ int TransferIAS(CONST char * dir, int bEOB) sim_debug(DEBUG_DATA, &cpu_dev, " ended by end of %s condition\n", (ec == 0) ? "Drum band" : (ec == 1) ? "IAS" : "IAS Block"); IAS_TimingRing = (IAS_TimingRing + 1) % 60; // incr timing ring at end of transfer - return n; + return n; } -// opcode execution +// opcode execution // input: opcode, DA (data address), DrumAddr (current word under the r/w heads. Needed to calculate time used on instr execution) // prior to call ExecOpcode DIST cpu register must be loaded with the needed data for inst execution // output: bBranchToDA: =1 if next inst must be taken from DA register instead of DA // CpuStepsUsed: number of steps (=word time) used on program execution -t_stat ExecOpcode(int opcode, int DA, - int * bBranchToDA, - int DrumAddr, +t_stat ExecOpcode(int opcode, int DA, + int * bBranchToDA, + int DrumAddr, int * CpuStepsUsed) { t_stat reason = 0; t_int64 d; - int i, n, neg, SvOV; + int i, n, neg, SvOV; int bUsingIAS; - *bBranchToDA = 0; + *bBranchToDA = 0; *CpuStepsUsed = 0; switch(opcode) { - case OP_NOOP : // No operation + case OP_NOOP : // No operation if ((IC == 0) && ((PR % D4) == 0)) reason = STOP_HALT; // if loop on NOOP on addr zero -> machine idle -> stop cpu break; - case OP_STOP : // Stop if console switch is set to stop, otherwise continue as a NO-OP + case OP_STOP : // Stop if console switch is set to stop, otherwise continue as a NO-OP if (CSWProgStop) { reason = STOP_PROG; // stops has the consequence to prevent AR to be set with IA contents (to point to next instruction). - // so must set a flag so next setp/go scp command will take next inst to execute from + // so must set a flag so next setp/go scp command will take next inst to execute from // IA field in PR reg instead of AR ProgStopFlag = 1; } @@ -787,7 +787,7 @@ t_stat ExecOpcode(int opcode, int DA, AccNegativeZeroFlag = 0; ACC[1] = 0; ACC[0] = d; - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); // sequence chart for Add/Substract @@ -798,51 +798,51 @@ t_stat ExecOpcode(int opcode, int DA, // Restart IA to AR Enable PR Search next // Signal Inst *CpuStepsUsed = 1+1+2+1 - +(DrumAddr % 2); // using lower acc -> wait for even + +(DrumAddr % 2); // using lower acc -> wait for even // no need to complement neg sum break; case OP_AL: // Add to Lower case OP_SL: // Subtract from Lower case OP_AABL: // Add Absolute to lower case OP_SABL: // Subtract Absolute from lower - if ((opcode == OP_AL) && (ACC[1] == 0) && (ACC[0] == 0) && (AccNegativeZeroFlag) && + if ((opcode == OP_AL) && (ACC[1] == 0) && (ACC[0] == 0) && (AccNegativeZeroFlag) && (DIST == 0) && (DistNegativeZeroFlag)) { // special case as stated in Operation manual 22(22-6060-2_650_OperMan.pdf), page 95 - // Acc result on minus zero if acc contains minus zero and AU or AL with a drum + // Acc result on minus zero if acc contains minus zero and AU or AL with a drum // location that contains minus zero sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: 0000000000 0000000000- (Minus Zero), OV: 0\n"); // acc keeps the minus zero it already has - break; + break; } d = DIST; if ((opcode == OP_AABL) || (opcode == OP_SABL)) d = AbsWord(d); if ((opcode == OP_SL) || (opcode == OP_SABL)) d = -d; AddToAcc(0,d,1); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); *CpuStepsUsed = 1+1+2+1 - +(DrumAddr % 2) // using lower acc -> wait for even + +(DrumAddr % 2) // using lower acc -> wait for even +(bAccNegComplement ? 2:0); // acc sign change -> need to complement neg sum (two steps) break; case OP_RAU: // Reset and Add into Upper case OP_RSU: // Reset and Subtract into Upper case OP_AU: // Add to Upper case OP_SU: // Substract from Upper - if ((opcode == OP_AU) && (ACC[1] == 0) && (ACC[0] == 0) && (AccNegativeZeroFlag) && + if ((opcode == OP_AU) && (ACC[1] == 0) && (ACC[0] == 0) && (AccNegativeZeroFlag) && (DIST == 0) && (DistNegativeZeroFlag)) { // special case as stated in Operation manual 22(22-6060-2_650_OperMan.pdf), page 95 - // Acc result on minus zero if acc contains minus zero and AU or AL with a drum + // Acc result on minus zero if acc contains minus zero and AU or AL with a drum // location that contains minus zero sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: 0000000000 0000000000- (Minus Zero), OV: 0\n"); // acc keeps the minus zero it already has - break; + break; } d = DIST; if ((opcode == OP_RAU) || (opcode == OP_RSU)) ACC[1] = ACC[0] = 0; if ((opcode == OP_SU) || (opcode == OP_RSU)) d = -d; AddToAcc(d,0,1); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); *CpuStepsUsed = 1+1+2+1 @@ -851,27 +851,27 @@ t_stat ExecOpcode(int opcode, int DA, break; // Multiply/divide case OP_MULT: // Multiply - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Mult ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Mult ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", printfd); if ((ACC[1] == 0) && (ACC[0] == 1) && (DIST == 0) && (DistNegativeZeroFlag)) { // special case as stated in Operation manual 22(22-6060-2_650_OperMan.pdf), page 95 // Acc result on minus zero if a drum location that contains minus zero // is multiplied by +1 sim_debug(DEBUG_DETAIL, &cpu_dev, "... Mult result ACC: 0000000000 0000000000- (Minus Zero), OV: 0\n"); - // acc set to minus zero + // acc set to minus zero ACC[1] = ACC[0] = 0; AccNegativeZeroFlag = 1; - break; + break; } *CpuStepsUsed = 0; SvOV=OV; OV=0; neg = (DIST < 0) ? 1:0; if (AccNegative) neg = 1-neg; - d = AbsWord(DIST); - ACC[0] = AbsWord(ACC[0]); - ACC[1] = AbsWord(ACC[1]); + d = AbsWord(DIST); + ACC[0] = AbsWord(ACC[0]); + ACC[1] = AbsWord(ACC[1]); for(i=0;i<10;i++) { n = ShiftAcc(1); *CpuStepsUsed = *CpuStepsUsed + 2; @@ -883,12 +883,12 @@ t_stat ExecOpcode(int opcode, int DA, if (OV) break; } if (neg) { - ACC[0] = -ACC[0]; - ACC[1] = -ACC[1]; + ACC[0] = -ACC[0]; + ACC[1] = -ACC[1]; } if (SvOV==1) OV=1; // if overflow was set at beginning of opcode execution, keeps its state - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", - printfa, + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + printfa, OV); // sequence chart for Multiply/Divide // (1) (0..49) (1) (0/1) (20..200) (1) @@ -898,15 +898,15 @@ t_stat ExecOpcode(int opcode, int DA, // Restart IA to AR Enable PR Search next // Signal Inst *CpuStepsUsed = 1+1+1+1 - +(DrumAddr % 2) // wait for even + +(DrumAddr % 2) // wait for even +*CpuStepsUsed; // i holds the number of loops done break; case OP_DIV: // Divide case OP_DIVRU: // Divide and reset upper accumulator - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Div ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Div ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", printfd); SvOV=OV; if (DIST == 0) { @@ -921,9 +921,9 @@ t_stat ExecOpcode(int opcode, int DA, *CpuStepsUsed = 0; OV = 0; neg = (DIST < 0) ? 1:0; if (AccNegative) neg = 1-neg; - d = AbsWord(DIST); - ACC[0] = AbsWord(ACC[0]); - ACC[1] = AbsWord(ACC[1]); + d = AbsWord(DIST); + ACC[0] = AbsWord(ACC[0]); + ACC[1] = AbsWord(ACC[1]); for(i=0;i<10;i++) { n = ShiftAcc(1); ACC[1] = ACC[1] + n * D10; @@ -935,18 +935,18 @@ t_stat ExecOpcode(int opcode, int DA, } } if (neg) { - ACC[0] = -ACC[0]; - ACC[1] = -ACC[1]; + ACC[0] = -ACC[0]; + ACC[1] = -ACC[1]; } if (opcode == OP_DIVRU) { ACC[1] = 0; } - *CpuStepsUsed = 1+1+1+1 - +(DrumAddr % 2) // wait for even + *CpuStepsUsed = 1+1+1+1 + +(DrumAddr % 2) // wait for even +*CpuStepsUsed + 40; // i holds the number of loops done } if (SvOV==1) OV=1; // if overflow was set at beginning of opcode execution, keeps its state - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Div result ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Div result ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); break; @@ -964,7 +964,7 @@ t_stat ExecOpcode(int opcode, int DA, if (d <= - 5) AddToAcc(0,-1,0); if (d >= 5) AddToAcc(0,+1,0); } - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); // sequence chart for shift @@ -975,12 +975,12 @@ t_stat ExecOpcode(int opcode, int DA, // Restart IA to AR Enable PR Search next // Signal Inst *CpuStepsUsed = 1+1+1 - +(DrumAddr % 2) // wait for even - + 2*(DA % 10) // number of shifts done + +(DrumAddr % 2) // wait for even + + 2*(DA % 10) // number of shifts done + ((opcode == OP_SRD) ? 1:0); break; - case OP_SCT : // Shift accumulator left and count - n = DA % 10; + case OP_SCT : // Shift accumulator left and count + n = DA % 10; if (n>0) n=10-n; // shift count (ten's complement of unit digit of DA, or zero if digit is zero) neg = AccNegative; // save acc sign ACC[0] = AbsWord(ACC[0]); @@ -1003,12 +1003,12 @@ t_stat ExecOpcode(int opcode, int DA, } AccNegativeZeroFlag = 0; if (neg) {ACC[0] = -ACC[0]; ACC[1] = -ACC[1]; } - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); *CpuStepsUsed = 1+1+1 - +(DrumAddr % 2) // wait for even - + 2*i; // number of shifts done + +(DrumAddr % 2) // wait for even + + 2*i; // number of shifts done break; // load and store case OP_STL: // Store Lower in Mem @@ -1024,50 +1024,50 @@ t_stat ExecOpcode(int opcode, int DA, // (1) (0/1) (1) (0..49) (1) (1) (1) // Enable Wait L/U acc Search Store IA to AR Enable PR // Dist for even to dist data data - // or odd - *CpuStepsUsed = 1+1+1+1+1+ + // or odd + *CpuStepsUsed = 1+1+1+1+1+ + (((opcode == OP_STU) ? DrumAddr:DrumAddr+1) % 2); // wait for odd/even depending on STU/STL opcode break; case OP_STD: // store distributor - *CpuStepsUsed = 1+1+1+1; + *CpuStepsUsed = 1+1+1+1; break; case OP_STDA: // Store Lower Data Address n = ((ACC[0] / D4) % D4); // get data addr xxDDDDxxxx from lower Acc - d = SetDA(DIST, n); // replace it in distributor + d = SetDA(DIST, n); // replace it in distributor if ((d == 0) && ((DIST < 0) || ( (DIST == 0) && (DistNegativeZeroFlag) ))) { - // if dist results in zero but was negative or negative zero before replacing digits - // then it is set to minus zero - DistNegativeZeroFlag = 1; + // if dist results in zero but was negative or negative zero before replacing digits + // then it is set to minus zero + DistNegativeZeroFlag = 1; } else { DistNegativeZeroFlag = 0; } - DIST = d; + DIST = d; *CpuStepsUsed = 1+1+1+1 - +(DrumAddr % 2); // wait for even + +(DrumAddr % 2); // wait for even break; case OP_STIA: // Store Lower Instruction Address n = (ACC[0] % D4); // get inst addr xxyyyyAAAA - d = SetIA(DIST, n); // replace it in distributor + d = SetIA(DIST, n); // replace it in distributor if ((d == 0) && ((DIST < 0) || ( (DIST == 0) && (DistNegativeZeroFlag) ))) { - // if dist results in zero but was negative or negative zero before replacing digits - // then it is set to minus zero - DistNegativeZeroFlag = 1; + // if dist results in zero but was negative or negative zero before replacing digits + // then it is set to minus zero + DistNegativeZeroFlag = 1; } else { DistNegativeZeroFlag = 0; - } - DIST = d; + } + DIST = d; *CpuStepsUsed = 1+1+1+1 - +(DrumAddr % 2); // wait for even + +(DrumAddr % 2); // wait for even break; case OP_LD: // Load Distributor - *CpuStepsUsed = 1+1+1+1; + *CpuStepsUsed = 1+1+1+1; break; case OP_TLE: // Table lookup on equal - case OP_TLU: // Table lookup + case OP_TLU: // Table lookup { char s[6]; - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Search DIST: %06d%04d%c '%s'\n", - printfd, + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Search DIST: %06d%04d%c '%s'\n", + printfd, word_to_ascii(s, 1, 5, DIST)); bUsingIAS = (AR >= 9000) ? 1:0; @@ -1086,12 +1086,12 @@ t_stat ExecOpcode(int opcode, int DA, } if ((bUsingIAS == 0) && ((AR % 50) > 47)) continue; // skip addr 48 & 49 of band that cannot be used for tables ReadAddr(AR, &d, NULL); // read table argument - if ( (opcode == OP_TLU) ? - (AbsWord(d) >= AbsWord(DIST)) : + if ( (opcode == OP_TLU) ? + (AbsWord(d) >= AbsWord(DIST)) : (AbsWord(d) == AbsWord(DIST)) ) { - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Found %04d: %06d%04d%c '%s'\n", - AR, printfw(d,0), + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Found %04d: %06d%04d%c '%s'\n", + AR, printfw(d,0), word_to_ascii(s, 1, 5, d)); break; // found } @@ -1099,21 +1099,21 @@ t_stat ExecOpcode(int opcode, int DA, // if tlu on ias, incr timing ring at end of instr execution if (bUsingIAS) IAS_TimingRing = (IAS_TimingRing + 1) % 60; // set the result as xxNNNNxxxx in lower acc - ACC[0] = SetDA(ACC[0], DA+n); + ACC[0] = SetDA(ACC[0], DA+n); sim_debug(DEBUG_DETAIL, &cpu_dev, "... Result ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); } *CpuStepsUsed = 1+1+1+1+1+1 - +(DrumAddr % 2) // wait for even + +(DrumAddr % 2) // wait for even + n; // number of reads to find the argument searched for break; // branch - case OP_BRD1: case OP_BRD2: case OP_BRD3: case OP_BRD4: case OP_BRD5: // Branch on 8 in distributor positions 1-10 + case OP_BRD1: case OP_BRD2: case OP_BRD3: case OP_BRD4: case OP_BRD5: // Branch on 8 in distributor positions 1-10 case OP_BRD6: case OP_BRD7: case OP_BRD8: case OP_BRD9: case OP_BRD10: - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Check DIST: %06d%04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Check DIST: %06d%04d%c\n", printfd); - d = AbsWord(DIST); + d = AbsWord(DIST); n = opcode - OP_BRD10; if (n == 0) n = 10; while (--n > 0) d = d / 10; d = d % 10; @@ -1129,57 +1129,57 @@ t_stat ExecOpcode(int opcode, int DA, reason = STOP_ERRO; break; } - *CpuStepsUsed = 1+1 + *CpuStepsUsed = 1+1 + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken break; case OP_BRNZU: // Branch on Non-Zero in Upper - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); if (ACC[1] != 0) { sim_debug(DEBUG_DETAIL, &cpu_dev, "Upper ACC not Zero -> Branch Taken\n"); *bBranchToDA = 1; } - *CpuStepsUsed = 1+1 - +(DrumAddr % 2) // wait for even + *CpuStepsUsed = 1+1 + +(DrumAddr % 2) // wait for even + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken break; - case OP_BRNZ: // Branch on Non-Zero - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + case OP_BRNZ: // Branch on Non-Zero + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); if ((ACC[1] != 0) || (ACC[0] != 0)) { sim_debug(DEBUG_DETAIL, &cpu_dev, "Not Zero -> Branch Taken\n"); - *bBranchToDA = 1; + *bBranchToDA = 1; } - *CpuStepsUsed = 1 + *CpuStepsUsed = 1 +((DrumAddr+1) % 2) // wait for odd + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken break; case OP_BRMIN: // Branch on Minus - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); if (AccNegative) { sim_debug(DEBUG_DETAIL, &cpu_dev, "Is Negative -> Branch Taken\n"); - *bBranchToDA = 1; + *bBranchToDA = 1; } - *CpuStepsUsed = 1+1 + *CpuStepsUsed = 1+1 + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken break; case OP_BROV: // Branch on Overflow sim_debug(DEBUG_DETAIL, &cpu_dev, "... Check OV: %d\n", OV); if (OV) { sim_debug(DEBUG_DETAIL, &cpu_dev, "OV Set -> Branch Taken\n"); - *bBranchToDA = 1; + *bBranchToDA = 1; } - *CpuStepsUsed = 1+1 + *CpuStepsUsed = 1+1 + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken // BOV resets overflow OV=0; break; // Card I/O - case OP_RD: // Read a card + case OP_RD: // Read a card case OP_RD2: case OP_RD3: case OP_RC1: @@ -1196,7 +1196,7 @@ t_stat ExecOpcode(int opcode, int DA, nUnit = 3; nIL = IL_RD23; area = 13; } else { nUnit = 1; nIL = IL_RD1; area = 1; - } + } if (bUsingIAS == 0) { AR = (DA / 50) * 50 + area; // Drum Read Band is XX01 to XX10 or XX51 to XX60 @@ -1212,8 +1212,8 @@ t_stat ExecOpcode(int opcode, int DA, // copy card data from IO Sync buffer to drum/ias sim_debug(DEBUG_DETAIL, &cpu_dev, "... Read Card Unit CDR%d\n", nUnit); for (i=0;i<10;i++) { - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Read Card %04d: %06d%04d%c '%s'\n", - AR+i, printfw(IOSync[i],IOSync_NegativeZeroFlag[i]), + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Read Card %04d: %06d%04d%c '%s'\n", + AR+i, printfw(IOSync[i],IOSync_NegativeZeroFlag[i]), word_to_ascii(s, 1, 5, IOSync[i])); if (bUsingIAS == 0) { DRUM[AR + i] = IOSync[i]; @@ -1223,7 +1223,7 @@ t_stat ExecOpcode(int opcode, int DA, IAS[n] = IOSync[i]; IAS_NegativeZeroFlag[n] = IOSync_NegativeZeroFlag[i]; if ((n % 10) == 9) break; // hit ias end of block, terminate read even if transfered less than 10 words - } + } } if (bUsingIAS) IAS_TimingRing = DA; // is using ias, set timing ring on instr completition if (cdr_unit[1].u5 & URCSTA_LOAD) { @@ -1231,11 +1231,11 @@ t_stat ExecOpcode(int opcode, int DA, *bBranchToDA = 1; // load card -> next instr is taken from DA } // 300 msec read cycle, 270 available for computing - *CpuStepsUsed = msec_to_wordtime(30); // 30 msec div 0.096 msec word time; + *CpuStepsUsed = msec_to_wordtime(30); // 30 msec div 0.096 msec word time; InterLockCount[nIL] = msec_to_wordtime(300); // set interlock 300 msec for card read processing } break; - case OP_PCH: // Punch a card + case OP_PCH: // Punch a card case OP_WR2: case OP_WR3: bUsingIAS = (AR >= 9000) ? 1:0; @@ -1249,7 +1249,7 @@ t_stat ExecOpcode(int opcode, int DA, nUnit = 3; nIL = IL_WR23; area = 39; } else { nUnit = 1; nIL = IL_RD1; area = 27; - } + } if (bUsingIAS == 0) { AR = (DA / 50) * 50 + area; // Drum Read Band is XX27 to XX36 or XX77 to XX86 @@ -1268,14 +1268,14 @@ t_stat ExecOpcode(int opcode, int DA, IOSync[i] = IAS[n]; IOSync_NegativeZeroFlag[i] = IAS_NegativeZeroFlag[n]; IAS_TimingRing = n; - } - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Punch Card %04d: %06d%04d%c '%s'\n", - AR+i, printfw(IOSync[i],IOSync_NegativeZeroFlag[i]), + } + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Punch Card %04d: %06d%04d%c '%s'\n", + AR+i, printfw(IOSync[i],IOSync_NegativeZeroFlag[i]), word_to_ascii(s, 1, 5, IOSync[i])); if (bUsingIAS) { - // punching from IAS. If hit ias end of block, terminate even + // punching from IAS. If hit ias end of block, terminate even // if transfered less than 10 words (rest of words were filled with zeroes) - if ((n % 10) == 9) break; + if ((n % 10) == 9) break; } } @@ -1288,29 +1288,29 @@ t_stat ExecOpcode(int opcode, int DA, } if (bUsingIAS) IAS_TimingRing = (IAS_TimingRing + 1) % 60; // incr timing ring at end of pch // 600 msec punch cycle, 565 available for computing - *CpuStepsUsed = msec_to_wordtime(35); // 35 msec div 0.096 msec word time; - InterLockCount[nIL] = msec_to_wordtime(600); // set interlock 600 msec for card punch processing + *CpuStepsUsed = msec_to_wordtime(35); // 35 msec div 0.096 msec word time; + InterLockCount[nIL] = msec_to_wordtime(600); // set interlock 600 msec for card punch processing } break; // IAS - Immediate Access Storage case OP_SET: // Set IAS Timing Ring - *CpuStepsUsed = 1+1+1; + *CpuStepsUsed = 1+1+1; break; case OP_LDI: // Load IAS (from Drum) n = TransferIAS("D->I", 0); // transfer drum to ias, end of ias block does not terminate transfer - *CpuStepsUsed = 1+1+1+n; + *CpuStepsUsed = 1+1+1+n; break; case OP_STI: // Store IAS (to Drum) n = TransferIAS("I->D", 0); // transfer ias to drum, end of ias block does not terminate transfer - *CpuStepsUsed = 1+1+1+n; + *CpuStepsUsed = 1+1+1+n; break; case OP_LIB: // Load IAS Block (from Drum) n = TransferIAS("D->I", 1); // transfer drum to ias, end of ias block does terminate transfer - *CpuStepsUsed = 1+1+1+n; + *CpuStepsUsed = 1+1+1+n; break; case OP_SIB: // Store IAS Block (to Drum) n = TransferIAS("I->D", 1); // transfer ias to drum, end of ias block does terminate transfer - *CpuStepsUsed = 1+1+1+n; + *CpuStepsUsed = 1+1+1+n; break; // Index Register case OP_AXA: // Add/Substract [with reset] to IRA @@ -1323,16 +1323,16 @@ t_stat ExecOpcode(int opcode, int DA, ReadAddr(DA, &d, NULL); DIST=d; DistNegativeZeroFlag=0; sim_debug(DEBUG_DATA, &cpu_dev, "... Read %04d: %06d%04d%c\n", DA, printfd); - i = (int) (d % D4); + i = (int) (d % D4); } else { i = DA; } n = n + (((opcode == OP_AXA) || (opcode == OP_RAA)) ? i : -i); NormalizeAddr(&n, 1); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... IRA: %04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... IRA: %04d%c\n", abs(n), n<0?'-':'+'); IR[0] = n; - *CpuStepsUsed = 1+1+1; + *CpuStepsUsed = 1+1+1; break; case OP_AXB: // Add/Substract [with reset] to IRB case OP_SXB: @@ -1344,16 +1344,16 @@ t_stat ExecOpcode(int opcode, int DA, ReadAddr(DA, &d, NULL); DIST=d; DistNegativeZeroFlag=0; sim_debug(DEBUG_DATA, &cpu_dev, "... Read %04d: %06d%04d%c\n", DA, printfd); - i = (int) (d % D4); + i = (int) (d % D4); } else { i = DA; } n = n + (((opcode == OP_AXB) || (opcode == OP_RAB)) ? i : -i); NormalizeAddr(&n, 1); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... IRB: %04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... IRB: %04d%c\n", abs(n), n<0?'-':'+'); IR[1] = n; - *CpuStepsUsed = 1+1+1; + *CpuStepsUsed = 1+1+1; break; case OP_AXC: // Add/Substract [with reset] to IRC case OP_SXC: @@ -1365,29 +1365,29 @@ t_stat ExecOpcode(int opcode, int DA, ReadAddr(DA, &d, NULL); DIST=d; DistNegativeZeroFlag=0; sim_debug(DEBUG_DATA, &cpu_dev, "... Read %04d: %06d%04d%c\n", DA, printfd); - i = (int) (d % D4); + i = (int) (d % D4); } else { i = DA; } n = n + (((opcode == OP_AXC) || (opcode == OP_RAC)) ? i : -i); NormalizeAddr(&n, 1); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... IRC: %04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... IRC: %04d%c\n", abs(n), n<0?'-':'+'); IR[2] = n; - *CpuStepsUsed = 1+1+1; + *CpuStepsUsed = 1+1+1; break; case OP_BMA: // Branch on IR Minus case OP_BMB: case OP_BMC: i = ((opcode == OP_BMA) ? 0 : (opcode == OP_BMB) ? 1 : 2); n = IR[i]; - sim_debug(DEBUG_DETAIL, &cpu_dev, "... IR%c: %04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... IR%c: %04d%c\n", i+'A', abs(n), n<0?'-':'+'); if (n<0) { sim_debug(DEBUG_DETAIL, &cpu_dev, "Is Negative -> Branch Taken\n"); - *bBranchToDA = 1; + *bBranchToDA = 1; } - *CpuStepsUsed = 1+1 + *CpuStepsUsed = 1+1 + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken break; case OP_NZA: // Branch on IR Zero @@ -1395,13 +1395,13 @@ t_stat ExecOpcode(int opcode, int DA, case OP_NZC: i = ((opcode == OP_NZA) ? 0 : (opcode == OP_NZB) ? 1 : 2); n = IR[i]; - sim_debug(DEBUG_DETAIL, &cpu_dev, "... IR%c: %04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... IR%c: %04d%c\n", i+'A', abs(n), n<0?'-':'+'); if (n!=0) { sim_debug(DEBUG_DETAIL, &cpu_dev, "Is Non Zero -> Branch Taken\n"); - *bBranchToDA = 1; + *bBranchToDA = 1; } - *CpuStepsUsed = 1+1 + *CpuStepsUsed = 1+1 + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken break; // floating point @@ -1414,18 +1414,18 @@ t_stat ExecOpcode(int opcode, int DA, (opcode == OP_FAM) || (opcode == OP_FSM), // absolute value? (opcode != OP_UFA) // normalize? ); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d, DIST: %06d%04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... ACC: %06d%04d %06d%04d%c, OV: %d, DIST: %06d%04d%c\n", printfa, OV, printfd); *CpuStepsUsed = 1+1 +(DrumAddr % 2) // using upper acc -> wait for even +2+2+2+1 - +n; // Float Add steps + +n; // Float Add steps break; case OP_FMP: // Float Multiply - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Mult ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Mult ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", printfd); SvOV=OV; OV = 0; if (((ACC[1] / 100) == 0) || ((DIST / 100) == 0)) { @@ -1435,8 +1435,8 @@ t_stat ExecOpcode(int opcode, int DA, int exp = GetExp(DIST) + GetExp(ACC[1]) - 50; neg = (DIST < 0) ? -1:1; if (AccNegative) neg = -neg; - ACC[1] = SetExp(AbsWord(ACC[1]), 0); - d = SetExp(AbsWord(DIST), 0); + ACC[1] = SetExp(AbsWord(ACC[1]), 0); + d = SetExp(AbsWord(DIST), 0); // mult mantissas for(i=0;i<10;i++) { n = ShiftAcc(1); @@ -1451,18 +1451,18 @@ t_stat ExecOpcode(int opcode, int DA, MantissaRoundAndNormalizeToFloat(CpuStepsUsed, neg, exp); } if (SvOV==1) OV=1; // if overflow was set at beginning of opcode execution, keeps its state - sim_debug(DEBUG_DETAIL, &cpu_dev, "... FP Mult result ACC: %06d%04d %06d%04d%c, OV: %d\n", - printfa, - OV); - *CpuStepsUsed = 1+1+2+2+2+1+ *CpuStepsUsed - +(DrumAddr % 2); // wait for even - break; - case OP_FDV: // Float Divide - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Div ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... FP Mult result ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); - sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", - printfd); + *CpuStepsUsed = 1+1+2+2+2+1+ *CpuStepsUsed + +(DrumAddr % 2); // wait for even + break; + case OP_FDV: // Float Divide + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Div ACC: %06d%04d %06d%04d%c, OV: %d\n", + printfa, + OV); + sim_debug(DEBUG_DETAIL, &cpu_dev, "... by DIST: %06d%04d%c\n", + printfd); SvOV=OV; OV = 0; if ((DIST / 100) == 0) { // check mantissa for zero, not exponent OV = 1; @@ -1472,12 +1472,12 @@ t_stat ExecOpcode(int opcode, int DA, // if dividend is zero -> result = 0 ACC[1] = ACC[0] = 0; } else { - int exp = GetExp(ACC[1]) - GetExp(DIST) + 50; + int exp = GetExp(ACC[1]) - GetExp(DIST) + 50; neg = (DIST < 0) ? -1:1; if (AccNegative) neg = -neg; - ACC[1] = AbsWord(ACC[1]) / 100; - d = AbsWord(DIST) / 100; - // div mantissas + ACC[1] = AbsWord(ACC[1]) / 100; + d = AbsWord(DIST) / 100; + // div mantissas for(i=0;;i++) { while (d <= ACC[1]) { AddToAcc(-d, 0, 0); @@ -1491,14 +1491,14 @@ t_stat ExecOpcode(int opcode, int DA, *CpuStepsUsed = *CpuStepsUsed + 2; } ACC[1] = ACC[0]; - MantissaRoundAndNormalizeToFloat(CpuStepsUsed, neg, exp); + MantissaRoundAndNormalizeToFloat(CpuStepsUsed, neg, exp); } if (SvOV==1) OV=1; // if overflow was set at beginning of opcode execution, keeps its state - sim_debug(DEBUG_DETAIL, &cpu_dev, "... FP Div result ACC: %06d%04d %06d%04d%c, OV: %d\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... FP Div result ACC: %06d%04d %06d%04d%c, OV: %d\n", printfa, OV); - *CpuStepsUsed = 1+1+2+2+16+2+1+ *CpuStepsUsed - +(DrumAddr % 2); // wait for even + *CpuStepsUsed = 1+1+2+2+16+2+1+ *CpuStepsUsed + +(DrumAddr % 2); // wait for even break; // tape opcodes case OP_RTC: // Read Tape Check @@ -1515,7 +1515,7 @@ t_stat ExecOpcode(int opcode, int DA, case OP_WTM: // Write Tape Mark sim_debug(DEBUG_DETAIL, &cpu_dev, "... Tape %d write tape mark\n", DA % 10); goto tape_opcode; - case OP_BST: // BackStep Tape + case OP_BST: // BackStep Tape sim_debug(DEBUG_DETAIL, &cpu_dev, "... Tape %d backspace record\n", DA % 10); goto tape_opcode; case OP_RWD: // rewind @@ -1531,12 +1531,12 @@ t_stat ExecOpcode(int opcode, int DA, if (reason == SCPE_OK) { // tape command terminated } else if (reason == SCPE_OK_INPROGRESS) { - // tape command in progress. + // tape command in progress. // Set interlock on Control Unit. Will be removed by mt_svr when tape operation terminates - InterLockCount[IL_Tape] = msec_to_wordtime(5*60*1000); + InterLockCount[IL_Tape] = msec_to_wordtime(5*60*1000); // Set interlock on IAS if read/write from/to IAS. Will be removed by mt_svr when tape operation terminates if ((opcode == OP_RTN) || (opcode == OP_RTA) || (opcode == OP_WTN) || (opcode == OP_WTA)){ - InterLockCount[IL_IAS] = msec_to_wordtime(5*60*1000); ; + InterLockCount[IL_IAS] = msec_to_wordtime(5*60*1000); ; } reason = SCPE_OK; } else { @@ -1547,16 +1547,16 @@ t_stat ExecOpcode(int opcode, int DA, break; case OP_NTS: // Branch on No Tape Signal case OP_NEF: // Branch on No End of File - sim_debug(DEBUG_DETAIL, &cpu_dev, "... Tape Signal is %s\n", TapeIndicatorStr[LastTapeIndicator]); + sim_debug(DEBUG_DETAIL, &cpu_dev, "... Tape Signal is %s\n", TapeIndicatorStr[LastTapeIndicator]); if ((opcode == OP_NTS) && (LastTapeIndicator == 0)) { sim_debug(DEBUG_DETAIL, &cpu_dev, "No Tape Signal -> Branch Taken\n"); - *bBranchToDA = 1; - } + *bBranchToDA = 1; + } if ((opcode == OP_NEF) && (LastTapeIndicator != MT_IND_EOF)) { sim_debug(DEBUG_DETAIL, &cpu_dev, "No End of File -> Branch Taken\n"); - *bBranchToDA = 1; - } - *CpuStepsUsed = 1+1 + *bBranchToDA = 1; + } + *CpuStepsUsed = 1+1 + ((*bBranchToDA) ? 1:0); // one extra step needed if branch taken break; // disk opcodes @@ -1565,7 +1565,7 @@ t_stat ExecOpcode(int opcode, int DA, case OP_WDS: // seek sim_debug(DEBUG_DETAIL, &cpu_dev, "... DIST: %06d%04d%c\n", printfd); n = abs((int)(DIST % D8)) % 1000000; // ramac operation address - sim_debug(DEBUG_DETAIL, &cpu_dev, "... RAMAC %s on Unit %d, Disk %d, Track %d, Arm %d started\n", + sim_debug(DEBUG_DETAIL, &cpu_dev, "... RAMAC %s on Unit %d, Disk %d, Track %d, Arm %d started\n", (opcode == OP_SDS) ? "SEEK" : (opcode == OP_RDS) ? "READ" : "WRITE", i=(n / 100000) % 10, // unit (n / 1000) % 100, // disk @@ -1575,12 +1575,12 @@ t_stat ExecOpcode(int opcode, int DA, if (neg > 2) { sim_debug(DEBUG_EXP, &cpu_dev, "Arm out of range (should be 0..2)\n"); reason = STOP_IO; // selected arm or unit out of range - break; + break; } if (i > 3) { sim_debug(DEBUG_EXP, &cpu_dev, "Unit out of range (should be 0..3)\n"); reason = STOP_IO; // selected arm or unit out of range - break; + break; } if (cpu_unit.flags & OPTION_1DSKARM) { // if 1 arm per disk enabled, alisase all disck comands to be executed on arm 0 @@ -1590,12 +1590,12 @@ t_stat ExecOpcode(int opcode, int DA, if (reason == SCPE_OK) { // disk command terminated } else if (reason == SCPE_OK_INPROGRESS) { - // disk command in progress. + // disk command in progress. // Set interlock on Ramac Disk Control Unit. Will be removed by dsk_svr when disk operation terminates - InterLockCount[IL_RamacUnit] = msec_to_wordtime(75); + InterLockCount[IL_RamacUnit] = msec_to_wordtime(75); // Set interlock on IAS if read/write from/to IAS. Will be removed by dsk_svr when disk operation terminates if ((opcode == OP_RDS) || (opcode == OP_WDS)){ - InterLockCount[IL_IAS] = msec_to_wordtime(5*60*1000); ; + InterLockCount[IL_IAS] = msec_to_wordtime(5*60*1000); ; } reason = SCPE_OK; } else { @@ -1617,7 +1617,7 @@ t_stat ExecOpcode(int opcode, int DA, int WaitForStorage(int AR) { if ((AR >= 0) && (AR < DRUMSIZE)) { - if ((AR % 50) != DrumAddr) return 2; // yes, must wait for drum + if ((AR % 50) != DrumAddr) return 2; // yes, must wait for drum } else if ((STOR) && (AR >= 9000) && (AR < 9060)) { if (InterLockCount[IL_IAS] > 0) return 1; // yes, IAS was interlocked. Must wait until interlock is released } @@ -1627,7 +1627,7 @@ int WaitForStorage(int AR) // return 1 if must wait for interlock release int WaitForInterlock(int nInterlock) { - int n, arm; + int n, arm; // handle combined interlocks if (nInterlock == IL_Tape_and_Unit_and_IAS) { @@ -1651,11 +1651,11 @@ int WaitForInterlock(int nInterlock) } // handle interlock on tape unit if (nInterlock == -1) { - // get tape unit referenced by current opcode from intruction DA + // get tape unit referenced by current opcode from intruction DA n = (PR / D4) % 10; if ((n < 0) || (n > 5)) return 0; // invalid tape addr -> no interlock wait - return mt_ready(n) ? 0:1; // if tape ready -> return 0 -> no need to wait for tape unit - } + return mt_ready(n) ? 0:1; // if tape ready -> return 0 -> no need to wait for tape unit + } // handle interlock on disk unit arm if (nInterlock == -2) { // get disk unit and arm referenced by current DIST (distributor) value @@ -1667,7 +1667,7 @@ int WaitForInterlock(int nInterlock) // if 1 arm per disk enabled, alisase all disck comands to be executed on arm 0 arm=0; } - return dsk_ready(n, arm) ? 0:1; // if disk unit arm ready -> return 0 -> no need to wait + return dsk_ready(n, arm) ? 0:1; // if disk unit arm ready -> return 0 -> no need to wait } // handle single interlock @@ -1681,17 +1681,17 @@ sim_instr(void) int opcode, halt_cpu_requested; int bReadData, bWriteDrum, bBranchToDA; int instr_count = 0; /* Number of instructions to execute */ - const char * opname; /* points to opcode name */ + const char * opname; /* points to opcode name */ char * Symbolic_Buffer; - int IA = 0; // Instr Address: addr of next inst + int IA = 0; // Instr Address: addr of next inst int DA = 0; // Data Address; addr of data to be used by current inst - int MachineCycle, CpuStepsUsed, il, nInterlock, bInterLockWaitMsg, bFastMode; + int MachineCycle, CpuStepsUsed, il, nInterlock, bInterLockWaitMsg, bFastMode; /* How CPU execution is simulated - A cpu instruction is executed in real hw in several steps. Some os these steps involves waiting for rotating + A cpu instruction is executed in real hw in several steps. Some os these steps involves waiting for rotating drum to be positioned on requested addres (register AR). Other steps can involve waiting a Interlock to be released. The execution of a complete instruction is called a machine cycle @@ -1703,14 +1703,14 @@ sim_instr(void) SimH Real hw equivalent machine cycle half cycle - 0 I-Cycle WAIT FOR INSTR: - wait for drum to be positioned at address given by AR cpu register - 1 I-Cycle FETCH INST: - read the drum to get instr to PR register, - decode PR as opcode, DA, IA, + 0 I-Cycle WAIT FOR INSTR: + wait for drum to be positioned at address given by AR cpu register + 1 I-Cycle FETCH INST: + read the drum to get instr to PR register, + decode PR as opcode, DA, IA, apply index tags if needed, write back to PR check if opcode must wait for interlock release - check if opcode reads data from drum + check if opcode reads data from drum 2 D-Cycle WAIT FOR DATA READ: wait for interlock release if needed wait for drum to be positioned at AR address if decoded opcode reads data from drum @@ -1719,11 +1719,11 @@ sim_instr(void) set interlock if needed execute opcode operation 4 D-Cycle WAIT FOR DATA WRITE: - wait opcode excution time + wait opcode excution time wait for drum to be positioned at AR address if executed opcode writes data to drum 5 D-Cycle WRITEBACK: - if executed opcode writes data to drum, write DIST to drum - set AR=IA to read next instruction + if executed opcode writes data to drum, write DIST to drum + set AR=IA to read next instruction */ @@ -1738,8 +1738,8 @@ sim_instr(void) DrumAddr = 0; CpuStepsUsed = 0; - if ((ProgStopFlag) && - // if last inst was a programmed stop, + if ((ProgStopFlag) && + // if last inst was a programmed stop, // and AR has not been changed (still contains the same value set by stop 01 opcode) // gets instr to execute from IA instead of AR. This is to simulate the D-Cycle on stop opcode resume ((PR / D8) == 01) && @@ -1750,12 +1750,12 @@ sim_instr(void) nInterlock = 0; // clear interlocks memset(&InterLockCount[0], 0, sizeof(InterLockCount)); - bInterLockWaitMsg = 0; + bInterLockWaitMsg = 0; sim_cancel (&cpu_unit); - sim_activate (&cpu_unit, 1); + sim_activate (&cpu_unit, 1); - bFastMode = FAST; + bFastMode = FAST; while (reason == 0) { /* loop until halted */ @@ -1767,7 +1767,7 @@ sim_instr(void) bFastMode = 1; // also set fast mode to avoid wait on Interlocks, thus finishing the current inst asap } if (reason != SCPE_OK) { - break; + break; } } // housekeeping at beggining of inst execution cycle @@ -1783,7 +1783,7 @@ sim_instr(void) } // only check for ^E on fetch and on interlock wait if (halt_cpu_requested) { - reason = SCPE_STOP; + reason = SCPE_STOP; break; } } @@ -1797,7 +1797,7 @@ sim_instr(void) // increment umber of word counts elapsed from starting of simulator -> this is the global time measurement GlobalWordTimeCount++; - // if any interlock set, decrease it + // if any interlock set, decrease it for (il=0;il < sizeof(InterLockCount)/ sizeof(InterLockCount[0]) ;il++) { if (InterLockCount[il] > 0) InterLockCount[il]--; } @@ -1816,22 +1816,22 @@ sim_instr(void) if (bFastMode == 0) { il=WaitForStorage(AR); if ((il==1) && (bInterLockWaitMsg == 0)) { - bInterLockWaitMsg = 1; + bInterLockWaitMsg = 1; sim_debug(DEBUG_DETAIL, &cpu_dev, "Wait for interlock on IAS to fetch opcode at %04d\n", AR); } if (il>0) continue; // yes, wait for storage to fetch inst } // init inst execution - CpuStepsUsed = 0; + CpuStepsUsed = 0; - MachineCycle = 1; + MachineCycle = 1; } // FETCH INST if (MachineCycle == 1) { // get current intruction from storage, save current instr addr in IC IC = AR; if (0==ReadAddr(AR, &PR, NULL)) { - reason = STOP_ADDR; + reason = STOP_ADDR; goto end_of_cycle; } // decode inst @@ -1846,18 +1846,18 @@ sim_instr(void) } else { Symbolic_Buffer = 0; } - sim_debug(DEBUG_CMD, &cpu_dev, "Exec %04d: %02d %-6s %04d %04d %s%s\n", + sim_debug(DEBUG_CMD, &cpu_dev, "Exec %04d: %02d %-6s %04d %04d %s%s\n", IC, opcode, (opname == NULL) ? "???":opname, DA, IA, - (Symbolic_Buffer) ? " symb: ": "", + (Symbolic_Buffer) ? " symb: ": "", (Symbolic_Buffer) ? Symbolic_Buffer : ""); PROP = (uint16) opcode; if (opname == NULL) { - reason = STOP_UUO; + reason = STOP_UUO; goto end_of_cycle; } // if DA or IA tagged, modify DA or IA to remove tag and set the developed address in PR if (STOR) { - int nIndexsApplied; + int nIndexsApplied; if (DRUM4K) { nIndexsApplied = ApplyIndexRegisterModel4(&DA, &IA); } else { @@ -1866,30 +1866,30 @@ sim_instr(void) if (nIndexsApplied > 0) { CpuStepsUsed += nIndexsApplied; PR = (t_int64) opcode * D8 + (t_int64) DA * D4 + (t_int64) IA; - sim_debug(DEBUG_CMD, &cpu_dev, "Exec %04d: %02d %-6s %04d %04d %s\n", - IC, opcode, (opname == NULL) ? "???":opname, DA, IA, + sim_debug(DEBUG_CMD, &cpu_dev, "Exec %04d: %02d %-6s %04d %04d %s\n", + IC, opcode, (opname == NULL) ? "???":opname, DA, IA, " (developed addr)"); } } - AR = DA; // allways trasnfer DA to AR even if drum will be not read. This is why + AR = DA; // allways trasnfer DA to AR even if drum will be not read. This is why // all opcodes must have a valid DA address even if not used to read drum (eg SRT 0003 to shift) - + // simulates the machine working on half cycles if (HalfCycle == 1) { // if I-Half finished, about to exec D-Half HalfCycle = 2; // bump half cycle to exec D-Half on next scp step reason = SCPE_STEP; // then break beacuse I-Half finished - break; - } + break; + } bReadData = (base_ops[opcode].opRW & opReadDA) ? 1:0; // check if opcode should wait for and already set interlock nInterlock = base_ops[opcode].opInterLock; - bInterLockWaitMsg = 0; + bInterLockWaitMsg = 0; - MachineCycle = 2; + MachineCycle = 2; } // WAIT FOR DATA READ if (MachineCycle == 2) { @@ -1899,19 +1899,19 @@ sim_instr(void) if (nInterlock) { if (bFastMode == 0) if (WaitForInterlock(nInterlock)) { if (bInterLockWaitMsg == 0) { - bInterLockWaitMsg = 1; - sim_debug(DEBUG_DETAIL, &cpu_dev, "Wait for interlock on %s\n", - (nInterlock==IL_RD1) ? "RD1" : - (nInterlock==IL_WR1) ? "WR1" : - (nInterlock==IL_RD23) ? "RD23" : - (nInterlock==IL_WR23) ? "WR23" : - (nInterlock==IL_IAS) ? "IAS" : - (nInterlock==IL_Tape) ? "TCI" : - (nInterlock==IL_Tape_and_Unit_and_IAS) ? "IAS+TCI+Tape Unit ready" : - (nInterlock==IL_Tape_and_Unit) ? "TCI+Tape Unit ready" : - (nInterlock==IL_RamacUnit) ? "RAMAC Unit" : - (nInterlock==IL_RamacUnit_and_Arm) ? "RAMAC Unit+Arm" : - (nInterlock==IL_RamacUnit_and_Arm_and_IAS) ? "IAS+RAMAC Unit+Arm" : + bInterLockWaitMsg = 1; + sim_debug(DEBUG_DETAIL, &cpu_dev, "Wait for interlock on %s\n", + (nInterlock==IL_RD1) ? "RD1" : + (nInterlock==IL_WR1) ? "WR1" : + (nInterlock==IL_RD23) ? "RD23" : + (nInterlock==IL_WR23) ? "WR23" : + (nInterlock==IL_IAS) ? "IAS" : + (nInterlock==IL_Tape) ? "TCI" : + (nInterlock==IL_Tape_and_Unit_and_IAS) ? "IAS+TCI+Tape Unit ready" : + (nInterlock==IL_Tape_and_Unit) ? "TCI+Tape Unit ready" : + (nInterlock==IL_RamacUnit) ? "RAMAC Unit" : + (nInterlock==IL_RamacUnit_and_Arm) ? "RAMAC Unit+Arm" : + (nInterlock==IL_RamacUnit_and_Arm_and_IAS) ? "IAS+RAMAC Unit+Arm" : "???"); } continue; // yes, wait for interlock @@ -1922,26 +1922,26 @@ sim_instr(void) if (bFastMode == 0) { il=WaitForStorage(AR); if ((il==1) && (bInterLockWaitMsg == 0)) { - bInterLockWaitMsg = 1; + bInterLockWaitMsg = 1; sim_debug(DEBUG_DETAIL, &cpu_dev, "Wait for interlock on IAS to read at %04d\n",AR); } if (il>0) continue; // yes, wait for drum rotation/IAS ready } } - MachineCycle = 3; + MachineCycle = 3; } // EXEC if (MachineCycle == 3) { - // decode again PR register to reload internal register DA, IA, AR again. Needed if we are executing half cycles + // decode again PR register to reload internal register DA, IA, AR again. Needed if we are executing half cycles opname = DecodeOpcode(PR, &opcode, &DA, &IA); AR = DA; if (opname == NULL) { - reason = STOP_UUO; + reason = STOP_UUO; goto end_of_cycle; } // even if no data is fetched, DA addr must be a valid one for this opcode - if (0==IsDrumAddrOk(AR, base_ops[opcode].validDA)) { + if (0==IsDrumAddrOk(AR, base_ops[opcode].validDA)) { sim_debug(DEBUG_DETAIL, &cpu_dev, "... %04d: Invalid addr ERROR\n", AR); reason = STOP_ADDR; goto end_of_cycle; @@ -1950,17 +1950,17 @@ sim_instr(void) bReadData = (base_ops[opcode].opRW & opReadDA) ? 1:0; if (bReadData) { ReadAddr(AR, &DIST, &DistNegativeZeroFlag); - sim_debug(DEBUG_DATA, &cpu_dev, "... Read %04d: %06d%04d%c\n", + sim_debug(DEBUG_DATA, &cpu_dev, "... Read %04d: %06d%04d%c\n", AR, printfd); } bWriteDrum = (base_ops[opcode].opRW & opWriteDA) ? 1:0; - reason = ExecOpcode(opcode, DA, - &bBranchToDA, + reason = ExecOpcode(opcode, DA, + &bBranchToDA, DrumAddr, &CpuStepsUsed); if (reason != 0) goto end_of_cycle; - if (bBranchToDA) IA = DA; + if (bBranchToDA) IA = DA; MachineCycle = 4; } @@ -1973,27 +1973,27 @@ sim_instr(void) if (bFastMode == 0) { il=WaitForStorage(AR); if ((il==1) && (bInterLockWaitMsg == 0)) { - bInterLockWaitMsg = 1; + bInterLockWaitMsg = 1; sim_debug(DEBUG_DETAIL, &cpu_dev, "Wait for interlock on IAS to write at %04d\n", AR); } if (il>0) continue; // yes } } - MachineCycle = 5; + MachineCycle = 5; } // WRITEBACK if (MachineCycle == 5) { if (bWriteDrum) { - sim_debug(DEBUG_DATA, &cpu_dev, "... Write %04d: %06d%04d%c\n", + sim_debug(DEBUG_DATA, &cpu_dev, "... Write %04d: %06d%04d%c\n", AR, printfd); if (0==WriteAddr(AR, DIST, DistNegativeZeroFlag)) { - reason = STOP_ADDR; + reason = STOP_ADDR; goto end_of_cycle; } } // set AR to point to next instr - AR = IA; + AR = IA; // no more machine cycles } @@ -2001,22 +2001,22 @@ end_of_cycle: if (instr_count != 0 && --instr_count == 0) { if (reason == 0) { - IC = AR; - // if cpu not stoped (just stepped) set IC so next inst to be executed is shown. + IC = AR; + // if cpu not stoped (just stepped) set IC so next inst to be executed is shown. // if cpu stopped because some error (reason != 0), does not advance IC so instr shown is offending one - reason = SCPE_STEP; + reason = SCPE_STEP; break; } } // ready to process to next instr - MachineCycle = 0; + MachineCycle = 0; // reset the message for interlock wait - bInterLockWaitMsg = 0; + bInterLockWaitMsg = 0; } /* end while */ - // flush 407 printout + // flush 407 printout if ((cdp_unit[0].flags & UNIT_ATT) && (cdp_unit[0].fileref)) { fflush(cdp_unit[0].fileref); } @@ -2053,7 +2053,7 @@ t_stat cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr, int32 sw) { t_int64 d; - int NegZero; + int NegZero; t_value val; if (0==ReadAddr(addr, &d, &NegZero)) { @@ -2061,7 +2061,7 @@ cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr, int32 sw) } if (vptr != NULL) { if (NegZero) { - val = NEGZERO_value; // val has this special value to represent -0 (minus zero == negative zero) + val = NEGZERO_value; // val has this special value to represent -0 (minus zero == negative zero) } else { val = (t_value) d; } @@ -2076,7 +2076,7 @@ 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_int64 d; + t_int64 d; int NegZero; if (val == NEGZERO_value) { @@ -2101,8 +2101,8 @@ cpu_set_size(UNIT * uptr, int32 val, CONST char *cptr, void *desc) int32 v; v = val >> UNIT_V_MSIZE; - if (v == 0) {v = 1000;} else - if (v == 1) {v = 2000;} else + if (v == 0) {v = 1000;} else + if (v == 1) {v = 2000;} else if (v == 2) {v = 4000;} else v = 0; if ((v <= 0) || (v > MAXDRUMSIZE)) return SCPE_ARG; @@ -2117,7 +2117,7 @@ cpu_set_size(UNIT * uptr, int32 val, CONST char *cptr, void *desc) cpu_unit.flags &= ~UNIT_MSIZE; cpu_unit.flags |= val; cpu_unit.capac = 9990 + (v / 1000); - for (i=0;i= sca_nrcvd) sca_check_indata(); @@ -927,7 +927,7 @@ void xio_sca (int32 iocc_addr, int32 func, int32 modify) sichar = (uint8) (ReadW(iocc_addr) >> 8); sca_nsyns = 0; /* reset SYN suppression */ } - /* else? does presence of mod bit preclude sending a character? */ + /* else? does presence of mod bit preclude sending a character? */ if ((modify & 0x07) == 0) { /* no modifiers */ /* transmit character -- * note: in write mode, failure to write soon enough after a write response interrupt causes a check diff --git a/PDP10/pdp10_tim.c b/PDP10/pdp10_tim.c index 713fe844..4451695a 100644 --- a/PDP10/pdp10_tim.c +++ b/PDP10/pdp10_tim.c @@ -68,12 +68,12 @@ * The timer merely sets the INTERVAL DONE flag in the APR flags. * Whether that actually causes an interrupt is controlled by the * APR interrupt enable for the flag and by the PI system. - * + * * The flag is readable as an APR condition by RDAPR, and CONSO/Z APR,. * The flag is cleared by WRAPR 1b22!1b30 (clear, count done). * * The timebase is maintained with the 12 LSB zero in a workspace - * register. When read by the OS, the actual value of the 10 MSB of + * register. When read by the OS, the actual value of the 10 MSB of * the hardware counter is inserted into those bits, providing increased * resolution. Although the system reference manual says otherwise, the * two LSB of the counter are read as zero by the microcode (DPM2), so @@ -213,7 +213,7 @@ DEVICE tim_dev = { /* Timebase - the timer is always running at less than hardware frequency, * need to interpolate the value by calculating how much of the current * clock tick has elapsed, and what that equates to in sysfreq units. - * + * * Read the contents of the time base registers, add the current contents of the * millisecond counter to the doubleword read, and place the result in location * E,E+1. @@ -241,10 +241,10 @@ tim_incr_base (tempbase, incr); * that the counter is in a different clock domain from the microcode. * To make the domain crossing, the microcode reads the counter * until two consecutive values match. - * - * Since the microcode cycle time is 300 nsec, the LSBs of the - * counter run too fast (244 nsec) for the strategy to work. - * Ignoring the two LSB ensures that the value can't change any + * + * Since the microcode cycle time is 300 nsec, the LSBs of the + * counter run too fast (244 nsec) for the strategy to work. + * Ignoring the two LSB ensures that the value can't change any * faster than ~976 nsec, which guarantees a stable value can be * obtained in at most three attempts. */ @@ -290,8 +290,8 @@ return FALSE; * This does not clear the harware counter, so the first * completion can come up to ~1 msc later than the new * period. - * - * Load the contents of location E into the interval register in + * + * Load the contents of location E into the interval register in * the workspace. */ @@ -308,13 +308,13 @@ int32 old_clk_tps = clk_tps; int32 old_tick_in_usecs = tick_in_usecs; /* - * The value provided is in hardware clicks. For a frequency of 4.1 + * The value provided is in hardware clicks. For a frequency of 4.1 * MHz, that means that dividing by 4096 (shifting 12 to the right) we get * the aproximate value in milliseconds. If any of the rightmost bits is * one, we add one unit (4096 ticks ). Reference: * AA-H391A-TK_DECsystem-10_DECSYSTEM-20_Processor_Reference_Jun1982.pdf * (page 4-37): - * + * * The timer includes a 12-bit hardware millisecond counter, a doubleword * time base kept from it, and an interval register for timed interrupts. The * millisecond counter runs continuously at 4.1 MHz and represents an @@ -329,26 +329,26 @@ int32 old_tick_in_usecs = tick_in_usecs; * program can initialize the time base as a number of milliseconds (the low * order twelve bits are ignored), and every time the counter overflows the * microcode adds 4096 (2**12) to the base. - * + * * The interval register (in the workspace) holds a period that is specified * by the program and corresponds in magnitude to the low order word of the * time base. This allows a maximum interval of 223 ms, which is almost 140 * minutes. At the end of each interval, the :microcode sets Interval Done * (RDAPR bit 30), requesting an interrupt on the level assigned to the system - * flags (§4.8). In a separate workspace register, the microcode starts with - * the given period, decrements it by 4096 (2**12) every time the millisecond + * flags (§4.8). In a separate workspace register, the microcode starts with + * the given period, decrements it by 4096 (2**12) every time the millisecond * counter overflows, and sets the flag when the contents of this "time to go" - * register reach zero or less. Hence the countdown is by milliseconds, and - * any nonzero quantity in the low order twelve bits of the given period adds - * a whole millisecond to the count. (However, following specification of an - * interval by the program, the first downcount occurs at the first counter + * register reach zero or less. Hence the countdown is by milliseconds, and + * any nonzero quantity in the low order twelve bits of the given period adds + * a whole millisecond to the count. (However, following specification of an + * interval by the program, the first downcount occurs at the first counter * overflow regardless of when the register was loaded.) */ tim_new_period = new_interval & ~TIM_HWRE_MASK; if (new_interval & TIM_HWRE_MASK) tim_new_period += 010000; - + if (tim_new_period == 0) { sim_debug (DEB_TPS, &tim_dev, "update_interval() - ignoring 0 value interval\n"); return FALSE; @@ -363,13 +363,13 @@ if (clk_tps != old_clk_tps) /* tmxr is polled every tim_mult clks. Compute the divisor matching the target. */ tim_mult = (clk_tps <= TIM_TMXR_FREQ) ? 1 : (clk_tps / TIM_TMXR_FREQ) ; - + /* Estimate instructions/tick for fixed timing - just for KLAD */ tim_unit.wait = TIM_WAIT_IPS / clk_tps; tmxr_poll = tim_unit.wait * tim_mult; /* The next tim_svc will update the activation time. - * + * */ return FALSE; } @@ -393,7 +393,7 @@ else { /* tmxr is polled every tim_mult clks. Compute the divisor matching the target. */ tim_mult = (clk_tps <= TIM_TMXR_FREQ) ? 1 : (clk_tps / TIM_TMXR_FREQ) ; - + tmxr_poll = tim_mult * (int32)(sim_timer_inst_per_sec () / clk_tps);/* set mux poll */ tim_incr_base (tim_base, tim_period); /* incr time base based on period of expired interval */ tim_period = tim_new_period; /* If interval has changed, update period */ @@ -456,7 +456,7 @@ t_stat tim_set_mod (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { if (val & (UNIT_T20|UNIT_KLAD)) { clk_tps = TIM_TPS_T20; - update_interval(((d10)(1000*4096))/clk_tps); + update_interval(((d10)(1000*4096))/clk_tps); tmr_poll = tim_unit.wait; uptr->flags = uptr->flags | UNIT_Y2K; } @@ -490,7 +490,7 @@ t_stat st = SCPE_OK; curtim = sim_get_time (NULL); /* get time */ tptr = localtime (&curtim); /* decompose */ if (tptr == NULL) - return SCPE_NXM; + return SCPE_NXM; if ((tptr->tm_year > 99) && !(tim_unit.flags & UNIT_Y2K)) tptr->tm_year = 99; /* Y2K prob? */ diff --git a/SIMH-V4-status.md b/SIMH-V4-status.md index c98bbd21..c97cf982 100644 --- a/SIMH-V4-status.md +++ b/SIMH-V4-status.md @@ -5,45 +5,45 @@ [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/simh/simh)](https://ci.appveyor.com/project/simh/simh/history) ## Table of Contents: -[WHAT'S NEW since simh v3.9](#whats-new-since-simh-v39) -. . [New Simulators](#new-simulators) -. . [Simulator Front Panel API](#simulator-front-panel-api) -. . [New Functionality](#new-functionality) -. . . . [DDCMP Synchronous host physical device support - framer](#ddcmp-synchronous-host-physical-device-support---framer) -. . . . [Remote Console Facility](#remote-console-facility) -. . . . [VAX/PDP11 Enhancements](#vaxpdp11-enhancements) -. . . . [PDP11 Specific Enhancements](#pdp11-specific-enhancements) -. . . . [PDP10 Enhancements](#pdp10-enhancements) -. . . . [SDS 940 Enhancements](#sds-940-enhancements) -. . . . [Terminal Multiplexer additions](#terminal-multiplexer-additions) -. . . . [Video Display Capabilities](#video-display-capabilities) -. . . . [Asynchronous I/O](#asynchronous-io) -. . . . [Clock/Timer Enhancements](#clocktimer-enhancements) -. . . . [Ethernet Transport Enhancements](#ethernet-transport-enhancements) -. . . . [Disk Extensions](#disk-extensions) -. . . . [Embedded ROM support](#embedded-rom-support) -. . . . [Control Flow](#control-flow) -. . . . [Scriptable interactions with running simulators](#scriptable-interactions-with-running-simulators) -. . . . [Help](#help) -. . . . [Generic SCP support Clock Coscheduling as opposed to per simulator implementations](#generic-scp-support-clock-coscheduling-as-opposed-to-per-simulator-implementations) -. . . . [New SCP Commands](#new-scp-commands) -. . . . [Command Processing Enhancements](#command-processing-enhancements) -. . . . . . [Environment variable insertion](#environment-variable-insertion) -. . . . . . [Command aliases](#command-aliases) -. . . . . . [Do command argument manipulation](#do-command-argument-manipulation) -. . [Building and running a simulator](#building-and-running-a-simulator) -. . . . [Use Prebuilt Windows Simulators](#use-prebuilt-windows-simulators) -. . . . [Building simulators yourself](#building-simulators-yourself) -. . . . . . [Linux/OSX other *nix platforms](#linuxosx-other-nix-platforms) -. . . . . . . . [Build Dependencies](#build-dependencies) -. . . . . . . . . . [OS X - Dependencies](#os-x---dependencies) -. . . . . . . . . . [Linux - Dependencies](#linux---dependencies) -. . . . . . [Windows](#windows) -. . . . . . . . [Required related files](#required-related-files) -. . . . . . . . [Visual Studio (Standard or Express) 2008, 2010, 2012, 2013 or Visual Studio Community 2015, 2017, 2019](#visual-studio-standard-or-express-2008-2010-2012-2013-or-visual-studio-community-2015-2017-2019) -. . . . . . . . [MinGW32](#mingw32) -. . . . . . [VMS](#vms) -. . [Problem Reports](#problem-reports) +[WHAT'S NEW since simh v3.9](#whats-new-since-simh-v39) +. . [New Simulators](#new-simulators) +. . [Simulator Front Panel API](#simulator-front-panel-api) +. . [New Functionality](#new-functionality) +. . . . [DDCMP Synchronous host physical device support - framer](#ddcmp-synchronous-host-physical-device-support---framer) +. . . . [Remote Console Facility](#remote-console-facility) +. . . . [VAX/PDP11 Enhancements](#vaxpdp11-enhancements) +. . . . [PDP11 Specific Enhancements](#pdp11-specific-enhancements) +. . . . [PDP10 Enhancements](#pdp10-enhancements) +. . . . [SDS 940 Enhancements](#sds-940-enhancements) +. . . . [Terminal Multiplexer additions](#terminal-multiplexer-additions) +. . . . [Video Display Capabilities](#video-display-capabilities) +. . . . [Asynchronous I/O](#asynchronous-io) +. . . . [Clock/Timer Enhancements](#clocktimer-enhancements) +. . . . [Ethernet Transport Enhancements](#ethernet-transport-enhancements) +. . . . [Disk Extensions](#disk-extensions) +. . . . [Embedded ROM support](#embedded-rom-support) +. . . . [Control Flow](#control-flow) +. . . . [Scriptable interactions with running simulators](#scriptable-interactions-with-running-simulators) +. . . . [Help](#help) +. . . . [Generic SCP support Clock Coscheduling as opposed to per simulator implementations](#generic-scp-support-clock-coscheduling-as-opposed-to-per-simulator-implementations) +. . . . [New SCP Commands](#new-scp-commands) +. . . . [Command Processing Enhancements](#command-processing-enhancements) +. . . . . . [Environment variable insertion](#environment-variable-insertion) +. . . . . . [Command aliases](#command-aliases) +. . . . . . [Do command argument manipulation](#do-command-argument-manipulation) +. . [Building and running a simulator](#building-and-running-a-simulator) +. . . . [Use Prebuilt Windows Simulators](#use-prebuilt-windows-simulators) +. . . . [Building simulators yourself](#building-simulators-yourself) +. . . . . . [Linux/OSX other *nix platforms](#linuxosx-other-nix-platforms) +. . . . . . . . [Build Dependencies](#build-dependencies) +. . . . . . . . . . [OS X - Dependencies](#os-x---dependencies) +. . . . . . . . . . [Linux - Dependencies](#linux---dependencies) +. . . . . . [Windows](#windows) +. . . . . . . . [Required related files](#required-related-files) +. . . . . . . . [Visual Studio (Standard or Express) 2008, 2010, 2012, 2013 or Visual Studio Community 2015, 2017, 2019](#visual-studio-standard-or-express-2008-2010-2012-2013-or-visual-studio-community-2015-2017-2019) +. . . . . . . . [MinGW32](#mingw32) +. . . . . . [VMS](#vms) +. . [Problem Reports](#problem-reports) ## WHAT'S NEW since simh v3.9 @@ -99,7 +99,7 @@ #### CDC 1700 simulator from John Forecast -#### Hans-Ĺke Lund has implemented an SCELBI (SCientic-ELectronics-BIology) simulator. +#### Hans-Ă…ke Lund has implemented an SCELBI (SCientic-ELectronics-BIology) simulator. #### IBM 650 simulator from Roberto Sancho Villa @@ -114,13 +114,13 @@ The sim_frontpanel API provides a programmatic interface to start and control an ### New Functionality #### DDCMP Synchronous host physical device support - framer -Paul Koning has implemented a USB hardware device which can interface transport DDCMP packets across a synchronous line +Paul Koning has implemented a USB hardware device which can interface transport DDCMP packets across a synchronous line to physical host systems with native synchronous devices or other simulators using framer devices. #### Remote Console Facility A new capability has been added which allows a TELNET Connection to a user designated port so that some out of band commands can be entered to manipulate and/or adjust a running simulator. The commands which enable and control this capability are SET REMOTE TELNET=port, SET REMOTE CONNECTIONS=n, SET REMOTE TIMEOUT=seconds, and SHOW REMOTE. -The remote console facility has two modes of operation: 1) single command mode. and 2) multiple command mode. +The remote console facility has two modes of operation: 1) single command mode. and 2) multiple command mode. In single command mode you enter one command at a time and aren't concerned about what the simulated system is doing while you enter that command. The command is executed once you've hit return. In multiple command mode you initiate your activities by entering the WRU character (usually ^E). This will suspend the current simulator execution. You then enter commands as needed and when you are done you enter a CONTINUE command. While entering Multiple Command commands, if you fail to enter a complete command before the timeout (specified by "SET REMOTE TIMEOUT=seconds"), a CONTINUE command is automatically processed and simulation proceeds. @@ -139,18 +139,18 @@ A remote console session will close when an EOF character is entered (i.e. ^D or KDP11 on PDP11 for DECnet DUP11 on PDP11 for DECnet connectivity to talk to DMC, KDP or other DUP devices CH11 on PDP11 and VAX780 for Chaosnet (from Lars Brinkhoff) - DZ on Unibus systems can have up to 256 ports (default of 32), on + DZ on Unibus systems can have up to 256 ports (default of 32), on Qbus systems 128 port limit (default of 16). - DZ devices optionally support full modem control (and port speed settings + DZ devices optionally support full modem control (and port speed settings when connected to serial ports). TU58 device support for all PDP11 and VAX systems. DHU11 (device VH) on Unibus systems now has 16 ports per multiplexer. XQ devices (DEQNA, DELQA and DELQA-T) are bootable on Qbus PDP11 simulators - XQ and XU devices (DEQNA, DELQA, DELQA-T, DEUNA and DELQA) devices can now + XQ and XU devices (DEQNA, DELQA, DELQA-T, DEUNA and DELQA) devices can now directly communicate to a remote device via UDP (i.e. a built-in HECnet bridge). - XQ and XU devices (DEQNA, DELQA, DELQA-T, DEUNA and DELQA) devices can now + XQ and XU devices (DEQNA, DELQA, DELQA-T, DEUNA and DELQA) devices can now optionally throttle outgoing packets which is useful when communicating with - legacy systems (real hardware) on a local LAN which can easily get over run + legacy systems (real hardware) on a local LAN which can easily get over run when packets arrive too fast. MicroVAX 3900 has QVSS (VCB01) board available. MicroVAX 3900 and MicroVAX II have SET CPU AUTOBOOT option @@ -175,12 +175,12 @@ A remote console session will close when an EOF character is entered (i.e. ^D or #### Terminal Multiplexer additions Added support for TCP connections using IPv4 and/or IPv6. - Logging - Traffic going out individual lines can be optionally logged to + Logging - Traffic going out individual lines can be optionally logged to files - Buffering - Traffic going to a multiplexor (or Console) line can + Buffering - Traffic going to a multiplexor (or Console) line can optionally be buffered while a telnet session is not connected - and the buffered contents will be sent out a newly connecting - telnet session. This allows a user to review what may have + and the buffered contents will be sent out a newly connecting + telnet session. This allows a user to review what may have happened before they connect to that session. Serial Port support based on work by J David Bryan and Holger Veit @@ -191,48 +191,48 @@ A remote console session will close when an EOF character is entered (i.e. ^D or Input character rates reflect the natural character arrival time based on the line speed. #### Video Display Capabilities -Added support for monochrome and color displays with optional keyboards and mice. +Added support for monochrome and color displays with optional keyboards and mice. The VAXstation QVSS device (VCB01) and QDSS device (VCB02) simulations use these capabilities. Host platforms which have libSDL2 available can leverage this functionality. #### Asynchronous I/O - * Disk and Tape I/O can be asynchronous. Asynchronous support exists - for pdp11_rq, pdp11_rp and pdp11_tq devices (used by VAX and PDP11 + * Disk and Tape I/O can be asynchronous. Asynchronous support exists + for pdp11_rq, pdp11_rp and pdp11_tq devices (used by VAX and PDP11 simulators). - * Multiplexer I/O (Telnet and/or Serial) can be asynchronous. - Asynchronous support exists for console I/O and most multiplexer + * Multiplexer I/O (Telnet and/or Serial) can be asynchronous. + Asynchronous support exists for console I/O and most multiplexer devices. (Still experimental - not currently by default) #### Clock/Timer Enhancements - * Asynchronous clocks ticks exist to better support modern processors - that have variable clock speeds. The initial clock calibration model - presumed a constant simulated instruction execution rate. - Modern processors have variable processor speeds which breaks this - key assumption. + * Asynchronous clocks ticks exist to better support modern processors + that have variable clock speeds. The initial clock calibration model + presumed a constant simulated instruction execution rate. + Modern processors have variable processor speeds which breaks this + key assumption. * Strategies to make up for missed clock ticks are now available (independent of asynchronous tick generation). These strategies - generate catch-up clock ticks to keep the simulator passage of - time consistent with wall clock time. Simulator time while idling - or throttling is now consistent. Reasonable idling behavior is + generate catch-up clock ticks to keep the simulator passage of + time consistent with wall clock time. Simulator time while idling + or throttling is now consistent. Reasonable idling behavior is now possible without requiring that the host system clock tick be 10ms or less. - * Simulator writers have access to timing services and explicit wall + * Simulator writers have access to timing services and explicit wall clock delays where appropriate. #### Ethernet Transport Enhancements - * UDP packet transport. Direct simulator connections to HECnet can be + * UDP packet transport. Direct simulator connections to HECnet can be made without running a local packet bridge program. * NAT packet transport. Simulators which only speak TCP/IP (No DECnet) - and want to communicate with their host systems and/or directly to - the Internet can use NAT packet transport. This also works for WiFi + and want to communicate with their host systems and/or directly to + the Internet can use NAT packet transport. This also works for WiFi connected host systems. - * Packet Transmission Throttling. When connected to a LAN which has + * Packet Transmission Throttling. When connected to a LAN which has legacy network adapters (DEQNA, DEUNA) on legacy systems, it is very easy for a simulated system to overrun the receiving capacity of the - older systems. Throttling of simulated traffic delivered to the LAN + older systems. Throttling of simulated traffic delivered to the LAN can be used to mitigate this problem. - * Reliable MAC address conflict detection. - * Automatic unique default MAC address assignment. + * Reliable MAC address conflict detection. + * Automatic unique default MAC address assignment. #### Disk Extensions RAW Disk Access (including CDROM) @@ -246,15 +246,15 @@ Host platforms which have libSDL2 available can leverage this functionality. ANSI-VMS, ANSI-RSX11, ANSI-RSTS, ANSI-RT11 format tape support #### Embedded ROM support - Simulators which have boot commands which load constant files as part of - booting have those files imbedded into the simulator executable. The - imbedded files are used if the normal boot file isn't found when the + Simulators which have boot commands which load constant files as part of + booting have those files imbedded into the simulator executable. The + imbedded files are used if the normal boot file isn't found when the simulator boots. Specific examples are: - + VAX (MicroVAX 3900 - ka655x.bin) VAX8600 (VAX 8600 - vmb.exe) VAX780 (VAX 11/780 - vmb.exe) - VAX750 (VAX 11/750 - vmb.exe, ka750_old.bin, ka750_new.bin), + VAX750 (VAX 11/750 - vmb.exe, ka750_old.bin, ka750_new.bin), VAX730 (VAX 11/730 - vmb.exe) VAX610 (MicroVAX I - ka610.bin) VAX620 (rtVAX 1000 - ka620.bin) @@ -264,74 +264,74 @@ Host platforms which have libSDL2 available can leverage this functionality. The following extensions to the SCP command language without affecting prior behavior: - GOTO