From 5d081f8d931a134472f4b2f6cc224ff6b18a8ba7 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sat, 12 May 2012 14:25:34 -0700 Subject: [PATCH] Revised HP2100 from Dave Bryan with his fixes to cleanup compiling under the LLVM clang compiler --- HP2100/hp2100_baci.c | 18 +++---- HP2100/hp2100_bugfixes.txt | 28 ++++++++++- HP2100/hp2100_cpu.c | 44 ++++++++-------- HP2100/hp2100_cpu0.c | 47 +++++++++-------- HP2100/hp2100_cpu1.c | 50 +++++++++++-------- HP2100/hp2100_cpu2.c | 30 +++++++---- HP2100/hp2100_cpu3.c | 36 ++++++++----- HP2100/hp2100_cpu4.c | 19 ++++--- HP2100/hp2100_cpu5.c | 17 ++++--- HP2100/hp2100_cpu6.c | 28 +++++++---- HP2100/hp2100_cpu7.c | 19 ++++--- HP2100/hp2100_defs.h | 9 ++++ HP2100/hp2100_di.c | 38 +++++++------- HP2100/hp2100_di_da.c | 18 +++++-- HP2100/hp2100_dp.c | 24 ++++++--- HP2100/hp2100_dq.c | 25 +++++++--- HP2100/hp2100_ipl.c | 4 +- HP2100/hp2100_mpx.c | 4 +- HP2100/hp2100_ms.c | 27 +++++++--- HP2100/hp2100_mt.c | 16 ++++-- HP2100/hp2100_stddev.c | 7 ++- HP2100/hp2100_sys.c | 1 + HP2100/hp_disclib.c | 100 +++++++++++++++++++++++++------------ HP2100/hp_disclib.h | 7 ++- 24 files changed, 401 insertions(+), 215 deletions(-) diff --git a/HP2100/hp2100_baci.c b/HP2100/hp2100_baci.c index 878a6eff..063705a6 100644 --- a/HP2100/hp2100_baci.c +++ b/HP2100/hp2100_baci.c @@ -1157,11 +1157,11 @@ if (baci_edsiw & (baci_status ^ baci_dsrw) & IN_MODEM) /* device interrupt? */ baci_status = baci_status | IN_DEVINT; /* set flag */ if ((baci_status & IN_STDIRQ) || /* standard interrupt? */ - (!(baci_icw & OUT_DCPC) && /* or under program control */ - (baci_status & IN_FIFOIRQ)) || /* and FIFO interrupt? */ - ((IO_MODE == RECV) && /* or receiving */ + !(baci_icw & OUT_DCPC) && /* or under program control */ + (baci_status & IN_FIFOIRQ) || /* and FIFO interrupt? */ + (IO_MODE == RECV) && /* or receiving */ (baci_edsiw & OUT_ENCM) && /* and char mode */ - (baci_fget != baci_fput))) { /* and FIFO not empty? */ + (baci_fget != baci_fput)) { /* and FIFO not empty? */ if (baci.lockout) { /* interrupt lockout? */ if (DEBUG_PRI (baci_dev, DEB_CMDS)) @@ -1185,8 +1185,8 @@ if ((baci_status & IN_STDIRQ) || /* standard interrupt? * } if ((baci_icw & OUT_DCPC) && /* DCPC enabled? */ - (((IO_MODE == XMIT) && (baci_fcount < 128)) || /* and xmit and room in FIFO */ - ((IO_MODE == RECV) && (baci_fcount > 0)))) { /* or recv and data in FIFO? */ + ((IO_MODE == XMIT) && (baci_fcount < 128) || /* and xmit and room in FIFO */ + (IO_MODE == RECV) && (baci_fcount > 0))) { /* or recv and data in FIFO? */ if (baci.lockout) { /* interrupt lockout? */ if (DEBUG_PRI (baci_dev, DEB_CMDS)) @@ -1472,9 +1472,9 @@ if (baci_uart_clk > 0) { /* transfer in progress? if ((IO_MODE == XMIT) && /* transmit mode? */ ((baci_uart_clk == 0) || /* and end of character? */ - ((baci_uart_clk == 8) && /* or last stop bit */ - (baci_cfcw & OUT_STBITS) && /* and extra stop bit requested */ - ((baci_cfcw & OUT_CHARSIZE) == 0)))) { /* and 1.5 stop bits used? */ + (baci_uart_clk == 8) && /* or last stop bit */ + (baci_cfcw & OUT_STBITS) && /* and extra stop bit requested */ + ((baci_cfcw & OUT_CHARSIZE) == 0))) { /* and 1.5 stop bits used? */ baci_uart_clk = 0; /* clear clock count */ diff --git a/HP2100/hp2100_bugfixes.txt b/HP2100/hp2100_bugfixes.txt index 80793696..117dd525 100644 --- a/HP2100/hp2100_bugfixes.txt +++ b/HP2100/hp2100_bugfixes.txt @@ -1,6 +1,6 @@ HP 2100 SIMULATOR BUG FIX WRITEUPS ================================== - Last update: 2012-03-25 + Last update: 2012-05-07 1. PROBLEM: Booting from magnetic tape reports "HALT instruction, P: 77756 @@ -6280,3 +6280,29 @@ (hp2100_mt.c). STATUS: Fixed in version 3.9-0. + + + +247. PROBLEM: The ICD disc read end-of-track delay is not optimal. + + VERSION: 3.9-0 + + OBSERVATION: To avoid End of Cylinder errors when reading the last sector + of a track, the ICD controller must delay more than the usual intersector + time to allow the OS driver to send an Untalk if a read is to be + terminated. Currently, the longer delay is used if an end-of-cylinder + condition is present. However, the delay is needed only if the resulting + seek attempt would cause an error if the read is continued; the normal + delay should be used if the seek is permitted and would succeed. + + Also, if the host does send an Untalk during this time, the longer delay + should be cancelled, and command termination should be scheduled for + immediate processing. + + CAUSE: Suboptimal implementation. + + RESOLUTION: Modify "end_read" (hp_disclib.c) to use the longer time only + if the seek would fail, and modify "complete_read" (hp2100_di_da.c) to + cancel the intersector delay and schedule the completion phase immediately. + + STATUS: Patches prepared 2012-05-07. diff --git a/HP2100/hp2100_cpu.c b/HP2100/hp2100_cpu.c index 5fba8699..3dbe7bf8 100644 --- a/HP2100/hp2100_cpu.c +++ b/HP2100/hp2100_cpu.c @@ -29,6 +29,7 @@ DMA1,DMA2 12607B/12578A/12895A direct memory access controller DCPC1,DCPC2 12897B dual channel port controller + 09-May-12 JDB Separated assignments from conditional expressions 13-Jan-12 JDB Minor speedup in "is_mapped" Added casts to cpu_mod, dmasio, dmapio, cpu_reset, dma_reset 07-Apr-11 JDB Fixed I/O return status bug for DMA cycles @@ -1054,7 +1055,8 @@ for (i = OPTDEV; i <= MAXDEV; i++) /* default optional devi dtab [PWR] = &pwrf_dib; /* for now, powerfail is always present */ -for (i = 0; (dptr = sim_devices [i]); i++) { /* loop thru dev */ +for (i = 0; sim_devices [i] != NULL; i++) { /* loop thru dev */ + dptr = sim_devices [i]; dibptr = (DIB *) dptr->ctxt; /* get DIB */ if (dibptr && !(dptr->flags & DEV_DIS)) { /* handler exists and device is enabled? */ @@ -1464,17 +1466,17 @@ while (reason == SCPE_OK) { /* loop until halted */ */ if ((sim_idle_enab) && (intrq == 0)) /* idle enabled w/o pending irq? */ - if ((((PC == err_PC) || /* RTE through RTE-IVB */ - ((PC == (err_PC - 1)) && /* RTE-6/VM */ - ((ReadW (PC) & I_MRG) == I_ISZ))) && /* RTE jump target */ - (mp_fence == CLEAR) && (M [xeqt] == 0) && /* RTE idle indications */ - (M [tbg] == clk_dib.select_code)) || /* RTE verification */ + if (((PC == err_PC) || /* RTE through RTE-IVB */ + ((PC == (err_PC - 1)) && /* RTE-6/VM */ + ((ReadW (PC) & I_MRG) == I_ISZ))) && /* RTE jump target */ + (mp_fence == CLEAR) && (M [xeqt] == 0) && /* RTE idle indications */ + (M [tbg] == clk_dib.select_code) || /* RTE verification */ - ((PC == (err_PC - 3)) && /* DOS through DOS-III */ - (ReadW (PC) == I_STF) && /* DOS jump target */ - (AR == 0177777) && (BR == 0177777) && /* DOS idle indication */ - (M [m64] == 0177700) && /* DOS verification */ - (M [p64] == 0000100))) /* DOS verification */ + (PC == (err_PC - 3)) && /* DOS through DOS-III */ + (ReadW (PC) == I_STF) && /* DOS jump target */ + (AR == 0177777) && (BR == 0177777) && /* DOS idle indication */ + (M [m64] == 0177700) && /* DOS verification */ + (M [p64] == 0000100)) /* DOS verification */ sim_idle (TMR_POLL, FALSE); /* idle the simulator */ break; @@ -3351,7 +3353,7 @@ t_stat status; uint32 ioresult; IOCYCLE signals; -if ((bytes && !even) || (dma [ch].cw3 != DMASK)) { /* normal cycle? */ +if (bytes && !even || dma [ch].cw3 != DMASK) { /* normal cycle? */ if (input) /* input cycle? */ signals = ioIOI | ioCLF; /* assert IOI and CLF */ else /* output cycle */ @@ -3609,30 +3611,32 @@ DEVICE *dptr; DIB *dibptr; uint32 i, j, k; t_bool is_conflict = FALSE; -uint32 conflicts[MAXDEV + 1] = { 0 }; +uint32 conflicts [MAXDEV + 1] = { 0 }; -for (i = 0; (dptr = sim_devices[i]); i++) { +for (i = 0; sim_devices [i] != NULL; i++) { + dptr = sim_devices [i]; dibptr = (DIB *) dptr->ctxt; if (dibptr && !(dptr->flags & DEV_DIS)) - if (++conflicts[dibptr->select_code] > 1) + if (++conflicts [dibptr->select_code] > 1) is_conflict = TRUE; } if (is_conflict) { sim_ttcmd(); for (i = 0; i <= MAXDEV; i++) { - if (conflicts[i] > 1) { - k = conflicts[i]; + if (conflicts [i] > 1) { + k = conflicts [i]; printf ("Select code %o conflict:", i); if (sim_log) fprintf (sim_log, "Select code %o conflict:", i); - for (j = 0; (dptr = sim_devices[j]); j++) { + for (j = 0; sim_devices [j] != NULL; j++) { + dptr = sim_devices [j]; dibptr = (DIB *) dptr->ctxt; - if (dibptr && !(dptr->flags & DEV_DIS) && (i == dibptr->select_code)) { - if (k < conflicts[i]) { + if (dibptr && !(dptr->flags & DEV_DIS) && i == dibptr->select_code) { + if (k < conflicts [i]) { printf (" and"); if (sim_log) diff --git a/HP2100/hp2100_cpu0.c b/HP2100/hp2100_cpu0.c index f2506c97..a7769901 100644 --- a/HP2100/hp2100_cpu0.c +++ b/HP2100/hp2100_cpu0.c @@ -1,6 +1,6 @@ /* hp2100_cpu0.c: HP 1000 user microcode and unimplemented instruction set stubs - Copyright (c) 2006-2010, J. David Bryan + Copyright (c) 2006-2012, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ CPU0 User microcode and unimplemented firmware options + 09-May-12 JDB Separated assignments from conditional expressions 04-Nov-10 JDB Removed DS note regarding PIF card (is now implemented) 18-Sep-08 JDB .FLUN and self-tests for VIS and SIGNAL are NOP if not present 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h @@ -129,9 +130,11 @@ uint32 entry; entry = IR & 017; /* mask to entry point */ -if (op_ds[entry] != OP_N) - if ((reason = cpu_ops (op_ds[entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_ds [entry] != OP_N) { + reason = cpu_ops (op_ds[entry], op, intrq); /* get instruction operands */ + if (reason != SCPE_OK) /* did the evaluation fail? */ + return reason; /* return the reason for failure */ + } switch (entry) { /* decode IR<3:0> */ @@ -191,23 +194,23 @@ switch (IR) { switch ((IR >> 4) & 037) { /* decode IR<8:4> */ -/* case 000: *//* 105000-105017 */ -/* return cpu_user_00 (IR, intrq); *//* uncomment to handle instruction */ +/* case 000: ** 105000-105017 */ +/* return cpu_user_00 (IR, intrq); ** uncomment to handle instruction */ -/* case 001: *//* 105020-105037 */ -/* return cpu_user_01 (IR, intrq); *//* uncomment to handle instruction */ +/* case 001: ** 105020-105037 */ +/* return cpu_user_01 (IR, intrq); ** uncomment to handle instruction */ -/* case 0nn: *//* other cases as needed */ -/* return cpu_user_nn (IR, intrq); *//* uncomment to handle instruction */ +/* case 0nn: ** other cases as needed */ +/* return cpu_user_nn (IR, intrq); ** uncomment to handle instruction */ case 020: /* 10x400-10x417 */ return cpu_user_20 (IR, intrq); /* call sample dispatcher */ -/* case 021: *//* 10x420-10x437 */ -/* return cpu_user_21 (IR, intrq); *//* uncomment to handle instruction */ +/* case 021: ** 10x420-10x437 */ +/* return cpu_user_21 (IR, intrq); ** uncomment to handle instruction */ -/* case 0nn: *//* other cases as needed */ -/* return cpu_user_nn (IR, intrq); *//* uncomment to handle instruction */ +/* case 0nn: ** other cases as needed */ +/* return cpu_user_nn (IR, intrq); ** uncomment to handle instruction */ default: /* others undefined */ reason = stop_inst; @@ -243,20 +246,22 @@ uint32 entry; entry = IR & 017; /* mask to entry point */ -if (op_user_20 [entry] != OP_N) - if ((reason = cpu_ops (op_user_20 [entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_user_20 [entry] != OP_N) { + reason = cpu_ops (op_user_20 [entry], op, intrq); /* get instruction operands */ + if (reason != SCPE_OK) /* did the evaluation fail? */ + return reason; /* return the reason for failure */ + } switch (entry) { /* decode IR<4:0> */ case 000: /* 10x400 */ -/* break; *//* uncomment to handle instruction */ +/* break; ** uncomment to handle instruction */ case 001: /* 10x401 */ -/* break; *//* uncomment to handle instruction */ +/* break; ** uncomment to handle instruction */ -/* case 0nn: *//* other cases as needed */ -/* break; *//* uncomment to handle instruction */ +/* case 0nn: ** other cases as needed */ +/* break; ** uncomment to handle instruction */ default: /* others undefined */ reason = stop_inst; diff --git a/HP2100/hp2100_cpu1.c b/HP2100/hp2100_cpu1.c index 338d1ba9..0096e6e6 100644 --- a/HP2100/hp2100_cpu1.c +++ b/HP2100/hp2100_cpu1.c @@ -1,6 +1,6 @@ /* hp2100_cpu1.c: HP 2100/1000 EAU simulator and UIG dispatcher - Copyright (c) 2005-2008, Robert M. Supnik + Copyright (c) 2005-2012, 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"), @@ -25,6 +25,7 @@ CPU1 Extended arithmetic and optional microcode dispatchers + 09-May-12 JDB Separated assignments from conditional expressions 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h 05-Sep-08 JDB Moved option-present tests to UIG dispatchers Call "user microcode" dispatcher for unclaimed UIG instructions @@ -245,14 +246,15 @@ switch ((IR >> 8) & 0377) { /* decode IR<15:8> */ case 010: /* MPY 100200 (OP_K) */ MPY: - if ((reason = cpu_ops (OP_K, op, intrq))) /* get operand */ - break; - sop1 = SEXT (AR); /* sext AR */ - sop2 = SEXT (op[0].word); /* sext mem */ - sop1 = sop1 * sop2; /* signed mpy */ - BR = (sop1 >> 16) & DMASK; /* to BR'AR */ - AR = sop1 & DMASK; - O = 0; /* no overflow */ + reason = cpu_ops (OP_K, op, intrq); /* get operand */ + if (reason == SCPE_OK) { /* successful eval? */ + sop1 = SEXT (AR); /* sext AR */ + sop2 = SEXT (op[0].word); /* sext mem */ + sop1 = sop1 * sop2; /* signed mpy */ + BR = (sop1 >> 16) & DMASK; /* to BR'AR */ + AR = sop1 & DMASK; + O = 0; /* no overflow */ + } break; default: /* others undefined */ @@ -262,9 +264,11 @@ switch ((IR >> 8) & 0377) { /* decode IR<15:8> */ break; case 0201: /* DIV 100400 (OP_K) */ - if ((reason = cpu_ops (OP_K, op, intrq))) /* get operand */ + reason = cpu_ops (OP_K, op, intrq); /* get operand */ + if (reason != SCPE_OK) /* eval failed? */ break; - if ((rs = qs = BR & SIGN)) { /* save divd sign, neg? */ + rs = qs = BR & SIGN; /* save divd sign */ + if (rs) { /* neg? */ AR = (~AR + 1) & DMASK; /* make B'A pos */ BR = (~BR + (AR == 0)) & DMASK; /* make divd pos */ } @@ -317,17 +321,19 @@ switch ((IR >> 8) & 0377) { /* decode IR<15:8> */ break; case 0210: /* DLD 104200 (OP_D) */ - if ((reason = cpu_ops (OP_D, op, intrq))) /* get operand */ - break; - AR = (op[0].dword >> 16) & DMASK; /* load AR */ - BR = op[0].dword & DMASK; /* load BR */ + reason = cpu_ops (OP_D, op, intrq); /* get operand */ + if (reason == SCPE_OK) { /* successful eval? */ + AR = (op[0].dword >> 16) & DMASK; /* load AR */ + BR = op[0].dword & DMASK; /* load BR */ + } break; case 0211: /* DST 104400 (OP_A) */ - if ((reason = cpu_ops (OP_A, op, intrq))) /* get operand */ - break; - WriteW (op[0].word, AR); /* store AR */ - WriteW ((op[0].word + 1) & VAMASK, BR); /* store BR */ + reason = cpu_ops (OP_A, op, intrq); /* get operand */ + if (reason == SCPE_OK) { /* successful eval? */ + WriteW (op[0].word, AR); /* store AR */ + WriteW ((op[0].word + 1) & VAMASK, BR); /* store BR */ + } break; default: /* should never get here */ @@ -733,9 +739,11 @@ uint32 i, MA; for (i = 0; i < OP_N_F; i++) { flags = pattern & OP_M_FLAGS; /* get operand pattern */ - if (flags >= OP_ADR) /* address operand? */ - if ((reason = resolve (ReadW (PC), &MA, irq))) /* resolve indirects */ + if (flags >= OP_ADR) { /* address operand? */ + reason = resolve (ReadW (PC), &MA, irq); /* resolve indirects */ + if (reason != SCPE_OK) /* resolution failed? */ return reason; + } switch (flags) { case OP_NUL: /* null operand */ diff --git a/HP2100/hp2100_cpu2.c b/HP2100/hp2100_cpu2.c index 464452ae..a55cf656 100644 --- a/HP2100/hp2100_cpu2.c +++ b/HP2100/hp2100_cpu2.c @@ -1,6 +1,6 @@ /* hp2100_cpu2.c: HP 2100/1000 FP/DMS/EIG/IOP instructions - Copyright (c) 2005-2008, Robert M. Supnik + Copyright (c) 2005-2012, 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"), @@ -26,6 +26,7 @@ CPU2 Floating-point, dynamic mapping, extended, and I/O processor instructions + 09-May-12 JDB Separated assignments from conditional expressions 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h 05-Sep-08 JDB Removed option-present tests (now in UIG dispatchers) 05-Aug-08 JDB Updated mp_dms_jmp calling sequence @@ -243,9 +244,12 @@ uint32 i, t, mapi, mapj; absel = (IR & I_AB)? 1: 0; /* get A/B select */ entry = IR & 037; /* mask to entry point */ -if (op_dms[entry] != OP_N) - if ((reason = cpu_ops (op_dms[entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_dms [entry] != OP_N) { + reason = cpu_ops (op_dms [entry], op, intrq); /* get instruction operands */ + + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } switch (entry) { /* decode IR<3:0> */ @@ -609,9 +613,12 @@ int32 sop1, sop2; absel = (IR & I_AB)? 1: 0; /* get A/B select */ entry = IR & 037; /* mask to entry point */ -if (op_eig[entry] != OP_N) - if ((reason = cpu_ops (op_eig[entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_eig [entry] != OP_N) { + reason = cpu_ops (op_eig [entry], op, intrq); /* get instruction operands */ + + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } switch (entry) { /* decode IR<4:0> */ @@ -988,9 +995,12 @@ else if (entry <= 057) /* IR = 10x440-457? */ entry = entry - 060; /* offset 10x460-477 */ -if (op_iop[entry] != OP_N) - if ((reason = cpu_ops (op_iop[entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_iop [entry] != OP_N) { + reason = cpu_ops (op_iop [entry], op, intrq); /* get instruction operands */ + + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } switch (entry) { /* decode IR<5:0> */ diff --git a/HP2100/hp2100_cpu3.c b/HP2100/hp2100_cpu3.c index 036a3d82..3e201aea 100644 --- a/HP2100/hp2100_cpu3.c +++ b/HP2100/hp2100_cpu3.c @@ -25,6 +25,7 @@ CPU3 Fast FORTRAN and Double Integer instructions + 09-May-12 JDB Separated assignments from conditional expressions 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h 05-Sep-08 JDB Removed option-present tests (now in UIG dispatchers) 05-Aug-08 JDB Updated mp_dms_jmp calling sequence @@ -185,17 +186,23 @@ int32 i; entry = IR & 037; /* mask to entry point */ if (UNIT_CPU_MODEL != UNIT_1000_F) { /* 2100/M/E-Series? */ - if (op_ffp_e[entry] != OP_N) - if ((reason = cpu_ops (op_ffp_e[entry], op, intrq)))/* get instruction operands */ - return reason; + if (op_ffp_e [entry] != OP_N) { + reason = cpu_ops (op_ffp_e [entry], op, intrq); /* get instruction operands */ + + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } } #if defined (HAVE_INT64) /* int64 support available */ else { /* F-Series */ - if (op_ffp_f[entry] != OP_N) - if ((reason = cpu_ops (op_ffp_f[entry], op, intrq)))/* get instruction operands */ - return reason; + if (op_ffp_f [entry] != OP_N) { + reason = cpu_ops (op_ffp_f [entry], op, intrq); /* get instruction operands */ + + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } switch (entry) { /* decode IR<4:0> */ @@ -417,7 +424,8 @@ switch (entry) { /* decode IR<4:0> */ sa = op[0].word - 1; da = ReadW (sa); /* get jump target */ - if ((reason = resolve (da, &MA, intrq))) { /* resolve indirects */ + reason = resolve (da, &MA, intrq); /* resolve indirects */ + if (reason != SCPE_OK) { /* resolution failed? */ PC = err_PC; /* irq restarts instruction */ break; } @@ -435,7 +443,8 @@ switch (entry) { /* decode IR<4:0> */ op[1].word = op[1].word + /* compute element offset */ (op[2].word - 1) * op[3].word; else { /* 3-dim access */ - if ((reason = cpu_ops (OP_KK, op2, intrq))) {/* get 1st, 2nd ranges */ + reason = cpu_ops (OP_KK, op2, intrq); /* get 1st, 2nd ranges */ + if (reason != SCPE_OK) { /* evaluation failed? */ PC = err_PC; /* irq restarts instruction */ break; } @@ -461,7 +470,8 @@ switch (entry) { /* decode IR<4:0> */ for (j = 0; j < sc; j++) { MA = ReadW (sa++); /* get addr of actual */ - if ((reason = resolve (MA, &MA, intrq))) { /* resolve indirect */ + reason = resolve (MA, &MA, intrq); /* resolve indirect */ + if (reason != SCPE_OK) { /* resolution failed? */ PC = err_PC; /* irq restarts instruction */ break; } @@ -643,9 +653,11 @@ t_stat reason = SCPE_OK; entry = IR & 017; /* mask to entry point */ -if (op_dbi[entry] != OP_N) - if ((reason = cpu_ops (op_dbi[entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_dbi[entry] != OP_N) { + reason = cpu_ops (op_dbi [entry], op, intrq); /* get instruction operands */ + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } switch (entry) { /* decode IR<3:0> */ diff --git a/HP2100/hp2100_cpu4.c b/HP2100/hp2100_cpu4.c index 2f8cba77..ea294664 100644 --- a/HP2100/hp2100_cpu4.c +++ b/HP2100/hp2100_cpu4.c @@ -25,6 +25,7 @@ CPU4 Floating Point Processor and Scientific Instruction Set + 09-May-12 JDB Separated assignments from conditional expressions 06-Feb-12 JDB Added OPSIZE casts to fp_accum calls in .FPWR/.TPWR 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h 05-Sep-08 JDB Removed option-present tests (now in UIG dispatchers) @@ -260,9 +261,12 @@ else entry = opcode & 0177; /* map to <6:0> */ -if (op_fpp[entry] != OP_N) - if ((reason = cpu_ops (op_fpp[entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_fpp [entry] != OP_N) { + reason = cpu_ops (op_fpp [entry], op, intrq); /* get instruction operands */ + + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } switch (entry) { /* decode IR<6:0> */ case 0000: /* FAD 105000 (OP_RF) */ @@ -599,9 +603,12 @@ static const OP t_one = { { 0040000, 0000000, 0000000, 0000002 } }; /* DEY 1. entry = IR & 017; /* mask to entry point */ -if (op_sis[entry] != OP_N) - if ((reason = cpu_ops (op_sis[entry], op, intrq))) /* get instruction operands */ - return reason; +if (op_sis [entry] != OP_N) { + reason = cpu_ops (op_sis [entry], op, intrq); /* get instruction operands */ + + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } switch (entry) { /* decode IR<3:0> */ diff --git a/HP2100/hp2100_cpu5.c b/HP2100/hp2100_cpu5.c index 3e70d92d..31c381c6 100644 --- a/HP2100/hp2100_cpu5.c +++ b/HP2100/hp2100_cpu5.c @@ -26,6 +26,7 @@ CPU5 RTE-6/VM and RTE-IV firmware option instructions + 09-May-12 JDB Separated assignments from conditional expressions 23-Mar-12 JDB Added sign extension for dim count in "cpu_ema_resolve" 28-Dec-11 JDB Eliminated unused variable in "cpu_ema_vset" 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h @@ -649,9 +650,11 @@ t_bool debug = DEBUG_PRI (cpu_dev, DEB_VMA); entry = IR & 017; /* mask to entry point */ pattern = op_vma[entry]; /* get operand pattern */ -if (pattern != OP_N) - if ((reason = cpu_ops (pattern, op, intrq))) /* get instruction operands */ - return reason; +if (pattern != OP_N) { + reason = cpu_ops (pattern, op, intrq); /* get instruction operands */ + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } if (debug) { /* debugging? */ fprintf (sim_deb, ">>CPU VMA: IR = %06o (", IR); /* print preamble and IR */ @@ -1360,9 +1363,11 @@ t_bool debug = DEBUG_PRI (cpu_dev, DEB_EMA); entry = IR & 017; /* mask to entry point */ pattern = op_ema[entry]; /* get operand pattern */ -if (pattern != OP_N) - if ((reason = cpu_ops (pattern, op, intrq))) /* get instruction operands */ - return reason; +if (pattern != OP_N) { + reason = cpu_ops (pattern, op, intrq); /* get instruction operands */ + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } if (debug) { /* debugging? */ fprintf (sim_deb, ">>CPU EMA: PC = %06o, IR = %06o (", err_PC,IR); /* print preamble and IR */ diff --git a/HP2100/hp2100_cpu6.c b/HP2100/hp2100_cpu6.c index 4baa952f..b3dc34aa 100644 --- a/HP2100/hp2100_cpu6.c +++ b/HP2100/hp2100_cpu6.c @@ -1,6 +1,6 @@ /* hp2100_cpu6.c: HP 1000 RTE-6/VM OS instructions - Copyright (c) 2006-2010, J. David Bryan + Copyright (c) 2006-2012, J. David Bryan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ CPU6 RTE-6/VM OS instructions + 09-May-12 JDB Separated assignments from conditional expressions 29-Oct-10 JDB DMA channels renamed from 0,1 to 1,2 to match documentation 18-Sep-08 JDB Corrected .SIP debug formatting 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h @@ -393,11 +394,14 @@ static t_bool tbg_tick = FALSE; /* set if processing TBG entry = IR & 017; /* mask to entry point */ pattern = op_os[entry]; /* get operand pattern */ -if (pattern != OP_N) - if ((reason = cpu_ops (pattern, op, intrq))) /* get instruction operands */ - return reason; +if (pattern != OP_N) { + reason = cpu_ops (pattern, op, intrq); /* get instruction operands */ -tbg_tick = tbg_tick || ((IR == 0105357) && iotrap); /* set TBG interrupting flag */ + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } + +tbg_tick = tbg_tick || (IR == 0105357) && iotrap; /* set TBG interrupting flag */ debug_print = (DEBUG_PRI (cpu_dev, DEB_OS) && !tbg_tick) || (DEBUG_PRI (cpu_dev, DEB_OSTBG) && tbg_tick); @@ -544,7 +548,9 @@ switch (entry) { /* decode IR<3:0> */ for (i = 0; i < count; i++) { ma = ReadW (PC); /* get operand address */ - if ((reason = resolve (ma, &ma, intrq))) { /* resolve indirect */ + reason = resolve (ma, &ma, intrq); /* resolve indirect */ + + if (reason != SCPE_OK) { /* resolution failed? */ PC = err_PC; /* IRQ restarts instruction */ break; } @@ -620,8 +626,8 @@ switch (entry) { /* decode IR<3:0> */ while ((AR != 0) && ((AR & SIGN) == 0)) { /* end of list or bad list? */ key = ReadW ((AR + op[1].word) & VAMASK); /* get key value */ - if (((E == 0) && (key == op[0].word)) || /* for E = 0, key = arg? */ - ((E != 0) && (key > op[0].word))) /* for E = 1, key > arg? */ + if ((E == 0) && (key == op[0].word) || /* for E = 0, key = arg? */ + (E != 0) && (key > op[0].word)) /* for E = 1, key > arg? */ break; /* search is done */ BR = AR; /* B = last link */ @@ -710,8 +716,10 @@ switch (entry) { /* decode IR<3:0> */ ma = ReadW (sa); /* get addr of actual */ sa = (sa + 1) & VAMASK; /* increment address */ - if ((reason = resolve (ma, &ma, intrq))) { /* resolve indirect */ - PC = err_PC; /* irq restarts instruction */ + reason = resolve (ma, &ma, intrq); /* resolve indirect */ + + if (reason != SCPE_OK) { /* resolution failed? */ + PC = err_PC; /* irq restarts instruction */ break; } diff --git a/HP2100/hp2100_cpu7.c b/HP2100/hp2100_cpu7.c index cf3f2c76..84fb1163 100644 --- a/HP2100/hp2100_cpu7.c +++ b/HP2100/hp2100_cpu7.c @@ -26,6 +26,7 @@ CPU7 Vector Instruction Set and SIGNAL firmware + 09-May-12 JDB Separated assignments from conditional expressions 06-Feb-12 JDB Corrected "opsize" parameter type in vis_abs 11-Sep-08 JDB Moved microcode function prototypes to hp2100_cpu1.h 05-Sep-08 JDB Removed option-present tests (now in UIG dispatchers) @@ -383,16 +384,18 @@ if (entry==0) { /* retrieve sub opcode subcode = AR; /* for reentry */ PC = (PC + 1) & VAMASK; /* bump to real argument list */ pattern = (subcode & 0400) ? OP_AAKAKK : OP_AKAKAKK; /* scalar or vector operation */ -} + } -if (pattern != OP_N) +if (pattern != OP_N) { if (op_ftnret[entry]) { /* most VIS instrs ignore RTN addr */ ret = ReadOp(PC, in_s); rtn = rtn1 = ret.word; /* but save it just in case */ PC = (PC + 1) & VAMASK; /* move to next argument */ + } + reason = cpu_ops (pattern, op, intrq); /* get instruction operands */ + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ } - if ((reason = cpu_ops (pattern, op, intrq))) /* get instruction operands */ - return reason; if (debug) { /* debugging? */ fprintf (sim_deb, ">>CPU VIS: IR = %06o/%06o (", /* print preamble and IR */ @@ -652,9 +655,11 @@ t_bool debug = DEBUG_PRI (cpu_dev, DEB_SIG); entry = IR & 017; /* mask to entry point */ -if (op_signal[entry] != OP_N) - if ((reason = cpu_ops (op_signal[entry], op, intrq)))/* get instruction operands */ - return reason; +if (op_signal [entry] != OP_N) { + reason = cpu_ops (op_signal [entry], op, intrq); /* get instruction operands */ + if (reason != SCPE_OK) /* evaluation failed? */ + return reason; /* return reason for failure */ + } if (debug) { /* debugging? */ fprintf (sim_deb, ">>CPU SIG: IR = %06o (", IR); /* print preamble and IR */ diff --git a/HP2100/hp2100_defs.h b/HP2100/hp2100_defs.h index 3118e2d1..24dd613b 100644 --- a/HP2100/hp2100_defs.h +++ b/HP2100/hp2100_defs.h @@ -23,6 +23,7 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 09-May-12 JDB Added pragmas to suppress logical operator precedence warnings 10-Feb-12 JDB Added hp_setsc, hp_showsc functions to support SC modifier 28-Mar-11 JDB Tidied up signal handling 29-Oct-10 JDB DMA channels renamed from 0,1 to 1,2 to match documentation @@ -72,6 +73,14 @@ #include "sim_defs.h" /* simulator defns */ +/* Required to quell Mark's Mystery Compiler's precedence warnings */ + +#if defined (__GNUC__) +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wlogical-op-parentheses" +#endif + + /* Simulator stop and notification codes */ #define STOP_RSRV 1 /* must be 1 */ diff --git a/HP2100/hp2100_di.c b/HP2100/hp2100_di.c index 2238d356..98cc4ef0 100644 --- a/HP2100/hp2100_di.c +++ b/HP2100/hp2100_di.c @@ -1466,10 +1466,10 @@ if (assert != deny) /* was there any change previous_state = di_card->srq; /* save the current SRQ state */ -if (((di_card->cntl_register & CNTL_LSTN) && /* if the card is a listener */ - (di_card->status_register & STAT_IRL)) || /* and the input register is loaded, */ - ((di_card->cntl_register & CNTL_TALK) && /* or the card is a talker */ - ! FIFO_FULL)) /* and the FIFO is not full */ +if (di_card->cntl_register & CNTL_LSTN /* if the card is a listener */ + && di_card->status_register & STAT_IRL /* and the input register is loaded, */ + || di_card->cntl_register & CNTL_TALK /* or the card is a talker */ + && ! FIFO_FULL) /* and the FIFO is not full */ di_card->srq = SET; /* then request a DCPC cycle */ else di_card->srq = CLEAR; /* otherwise, DCPC service is not needed */ @@ -1481,21 +1481,21 @@ if (DEBUG_PRJ (dptrs [card], DEB_CMDS) dptrs [card]->name, di_card->srq == SET ? "set" : "cleared"); -if (((di_card->status_register & STAT_IRL) && /* is the input register loaded */ - (di_card->cntl_register & CNTL_IRL)) || /* and notification is wanted? */ - ((di_card->status_register & STAT_LBO) && /* or is the last byte out */ - (di_card->cntl_register & CNTL_LBO)) || /* and notification is wanted? */ - ((di_card->eor == SET) && /* or was the end of record seen */ - !(di_card->status_register & STAT_IRL)) || /* and the input register was unloaded? */ - ((di_card->bus_cntl & BUS_SRQ) && /* or is SRQ asserted on the bus */ - (di_card->cntl_register & CNTL_SRQ) && /* and notification is wanted */ - (di_card->cntl_register & CNTL_CIC)) || /* and the card is not controller? */ - (!SW8_SYSCTL && /* or is the card not the system controller */ - (di_card->bus_cntl & BUS_REN) && /* and REN is asserted on the bus */ - (di_card->cntl_register & CNTL_REN)) || /* and notification is wanted? */ - (!SW8_SYSCTL && /* or is the card not the system controller */ - (di_card->status_register & STAT_IFC) && /* and IFC is asserted on the bus */ - (di_card->cntl_register & CNTL_IFC))) { /* and notification is wanted? */ +if (di_card->status_register & STAT_IRL /* is the input register loaded */ + && di_card->cntl_register & CNTL_IRL /* and notification is wanted? */ + || di_card->status_register & STAT_LBO /* or is the last byte out */ + && di_card->cntl_register & CNTL_LBO /* and notification is wanted? */ + || di_card->eor == SET /* or was the end of record seen */ + && !(di_card->status_register & STAT_IRL) /* and the input register was unloaded? */ + || di_card->bus_cntl & BUS_SRQ /* or is SRQ asserted on the bus */ + && di_card->cntl_register & CNTL_SRQ /* and notification is wanted */ + && di_card->cntl_register & CNTL_CIC /* and the card is not controller? */ + || !SW8_SYSCTL /* or is the card not the system controller */ + && di_card->bus_cntl & BUS_REN /* and REN is asserted on the bus */ + && di_card->cntl_register & CNTL_REN /* and notification is wanted? */ + || !SW8_SYSCTL /* or is the card not the system controller */ + && di_card->status_register & STAT_IFC /* and IFC is asserted on the bus */ + && di_card->cntl_register & CNTL_IFC) { /* and notification is wanted? */ if (DEBUG_PRJ (dptrs [card], DEB_CMDS)) fprintf (sim_deb, ">>%s cmds: Flag set\n", diff --git a/HP2100/hp2100_di_da.c b/HP2100/hp2100_di_da.c index eea57d72..9ce38860 100644 --- a/HP2100/hp2100_di_da.c +++ b/HP2100/hp2100_di_da.c @@ -25,6 +25,7 @@ DA 12821A Disc Interface with Amigo disc drives + 07-May-12 JDB Cancel the intersector delay if an untalk is received 29-Mar-12 JDB First release 04-Nov-11 JDB Created DA device @@ -1594,10 +1595,10 @@ if (di [da].bus_cntl & BUS_ATN) { /* is it a bus comma da_unit [unit].wait = icd_cntlr [unit].cmd_time; /* these are always scheduled and */ initiated = TRUE; /* logged as initiated */ - if (((if_state [unit] == read_wait) && /* if we're waiting for a send data secondary */ - (message_address != 0x00)) || /* but it's not there */ - ((if_state [unit] == status_wait) && /* or a send status secondary, */ - (message_address != 0x08))) /* but it's not there */ + if (if_state [unit] == read_wait /* if we're waiting for a send data secondary */ + && message_address != 0x00 /* but it's not there */ + || if_state [unit] == status_wait /* or a send status secondary, */ + && message_address != 0x08) /* but it's not there */ abort_command (unit, io_program_error, /* then abort the pending command */ idle); /* and process the new command */ @@ -1962,6 +1963,11 @@ return; 2. There is no need to test if we are processing a disc command, as the controller would not be busy otherwise. + + 3. If an auto-seek will be needed to continue the read, but the seek will + fail, then an extra delay is inserted before the service call to start + the next sector. Once an Untalk is received, this delay is no longer + needed, so it is cancelled before rescheduling the service routine. */ static void complete_read (uint32 unit) @@ -1974,7 +1980,9 @@ if ((if_state [unit] == command_exec /* is a command exec if_state [unit] = command_exec; /* set to execute */ da_unit [unit].PHASE = end_phase; /* the completion phase */ - da_unit [unit].wait = icd_cntlr [unit].data_time; /* ensure that the controller will finish */ + + sim_cancel (&da_unit [unit]); /* cancel the EOT delay */ + da_unit [unit].wait = icd_cntlr [unit].data_time; /* reschedule for completion */ } return; diff --git a/HP2100/hp2100_dp.c b/HP2100/hp2100_dp.c index c6877dca..3b3f2bcc 100644 --- a/HP2100/hp2100_dp.c +++ b/HP2100/hp2100_dp.c @@ -26,6 +26,7 @@ DP 12557A 2871 disk subsystem 13210A 7900 disk subsystem + 09-May-12 JDB Separated assignments from conditional expressions 10-Feb-12 JDB Deprecated DEVNO in favor of SC Added CNTLR_TYPE cast to dp_settype 28-Mar-11 JDB Tidied up signal handling @@ -190,7 +191,7 @@ #define STA_PROT 0002000 /* protected (13210) */ #define STA_SKI 0001000 /* incomplete NI (u) */ #define STA_SKE 0000400 /* seek error */ -/* 0000200 *//* unused */ +/* 0000200 (unused) */ #define STA_NRDY 0000100 /* not ready (d) */ #define STA_EOC 0000040 /* end of cylinder */ #define STA_AER 0000020 /* addr error */ @@ -694,7 +695,8 @@ void dp_goc (int32 fnc, int32 drv, int32 time) { int32 t; -if ((t = sim_is_active (&dpc_unit[drv]))) { /* still seeking? */ +t = sim_is_active (&dpc_unit[drv]); +if (t) { /* still seeking? */ sim_cancel (&dpc_unit[drv]); /* stop seek */ dpc_sta[drv] = dpc_sta[drv] & ~STA_BSY; /* clear busy */ time = time + t; /* include seek time */ @@ -906,10 +908,13 @@ switch (uptr->FNC) { /* case function */ dpc_rarh = dpc_rarh ^ 1; /* incr head */ dpc_eoc = ((dpc_rarh & 1) == 0); /* calc eoc */ } - if ((err = fseek (uptr->fileref, da * sizeof (int16), - SEEK_SET))) break; + err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); + if (err) /* error? */ + break; fxread (dpxb, sizeof (int16), DP_NUMWD, uptr->fileref); - if ((err = ferror (uptr->fileref))) break; + err = ferror (uptr->fileref); + if (err) /* error? */ + break; } dpd_ibuf = dpxb[dp_ptr++]; /* get word */ if (dp_ptr >= DP_NUMWD) { /* end of sector? */ @@ -953,10 +958,13 @@ switch (uptr->FNC) { /* case function */ dpc_rarh = dpc_rarh ^ 1; /* incr head */ dpc_eoc = ((dpc_rarh & 1) == 0); /* calc eoc */ } - if ((err = fseek (uptr->fileref, da * sizeof (int16), - SEEK_SET))) break; + err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); + if (err) /* error? */ + break; fxwrite (dpxb, sizeof (int16), DP_NUMWD, uptr->fileref); - if ((err = ferror (uptr->fileref))) break; /* error? */ + err = ferror (uptr->fileref); + if (err) /* error? */ + break; dp_ptr = 0; /* next sector */ } if (dpd.command && dpd_xfer) /* dch on, xfer? */ diff --git a/HP2100/hp2100_dq.c b/HP2100/hp2100_dq.c index 24b8f303..4ca85689 100644 --- a/HP2100/hp2100_dq.c +++ b/HP2100/hp2100_dq.c @@ -26,6 +26,7 @@ DQ 12565A 2883 disk system + 09-May-12 JDB Separated assignments from conditional expressions 10-Feb-12 JDB Deprecated DEVNO in favor of SC 28-Mar-11 JDB Tidied up signal handling 26-Oct-10 JDB Changed I/O signal handler for revised signal model @@ -100,7 +101,7 @@ #define CW_V_FNC 12 /* function */ #define CW_M_FNC 017 #define CW_GETFNC(x) (((x) >> CW_V_FNC) & CW_M_FNC) -/* 000 *//* unused */ +/* 000 (unused) */ #define FNC_STA 001 /* status check */ #define FNC_RCL 002 /* recalibrate */ #define FNC_SEEK 003 /* seek */ @@ -530,7 +531,9 @@ void dq_goc (int32 fnc, int32 drv, int32 time) { int32 t; -if ((t = sim_is_active (&dqc_unit[drv]))) { /* still seeking? */ +t = sim_is_active (&dqc_unit[drv]); + +if (t) { /* still seeking? */ sim_cancel (&dqc_unit[drv]); /* cancel */ time = time + t; /* include seek time */ } @@ -740,10 +743,13 @@ switch (uptr->FNC) { /* case function */ dqc_rars = (dqc_rars + 1) % DQ_NUMSC; /* incr sector */ if (dqc_rars == 0) /* wrap? incr head */ dqc_uhed[drv] = dqc_rarh = dqc_rarh + 1; - if ((err = fseek (uptr->fileref, da * sizeof (int16), - SEEK_SET))) break; + err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); + if (err) + break; fxread (dqxb, sizeof (int16), DQ_NUMWD, uptr->fileref); - if ((err = ferror (uptr->fileref))) break; + err = ferror (uptr->fileref); + if (err) + break; } dqd_ibuf = dqxb[dq_ptr++]; /* get word */ if (dq_ptr >= DQ_NUMWD) { /* end of sector? */ @@ -786,10 +792,13 @@ switch (uptr->FNC) { /* case function */ dqc_rars = (dqc_rars + 1) % DQ_NUMSC; /* incr sector */ if (dqc_rars == 0) /* wrap? incr head */ dqc_uhed[drv] = dqc_rarh = dqc_rarh + 1; - if ((err = fseek (uptr->fileref, da * sizeof (int16), - SEEK_SET))) return TRUE; + err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); + if (err) + break; fxwrite (dqxb, sizeof (int16), DQ_NUMWD, uptr->fileref); - if ((err = ferror (uptr->fileref))) break; + err = ferror (uptr->fileref); + if (err) + break; dq_ptr = 0; } if (dqd.command && dqd_xfer) { /* dch on, xfer? */ diff --git a/HP2100/hp2100_ipl.c b/HP2100/hp2100_ipl.c index a01b4881..32e77f17 100644 --- a/HP2100/hp2100_ipl.c +++ b/HP2100/hp2100_ipl.c @@ -25,6 +25,7 @@ IPLI, IPLO 12875A interprocessor link + 09-May-12 JDB Separated assignments from conditional expressions 10-Feb-12 JDB Deprecated DEVNO in favor of SC Added CARD_INDEX casts to dib.card_index 07-Apr-11 JDB A failed STC may now be retried @@ -623,7 +624,8 @@ uptr->filename = tptr; /* save */ sim_activate (uptr, POLL_FIRST); /* activate first poll "immediately" */ if (sim_switches & SWMASK ('W')) { /* wait? */ for (i = 0; i < 30; i++) { /* check for 30 sec */ - if ((t = ipl_check_conn (uptr))) /* established? */ + t = ipl_check_conn (uptr); + if (t) /* established? */ break; if ((i % 10) == 0) /* status every 10 sec */ printf ("Waiting for connnection\n"); diff --git a/HP2100/hp2100_mpx.c b/HP2100/hp2100_mpx.c index b61572dd..a4d91dd9 100644 --- a/HP2100/hp2100_mpx.c +++ b/HP2100/hp2100_mpx.c @@ -1926,8 +1926,8 @@ if (fast_binary_read) { /* fast binary read else { /* normal service */ tmxr_poll_tx (&mpx_desc); /* output any accumulated characters */ - if (((buf_avail (iowrite, port) < 2) && /* more to transmit? */ - !(mpx_flags [port] & (FL_WAITACK | FL_XOFF))) || /* and transmission not suspended */ + if ((buf_avail (iowrite, port) < 2) && /* more to transmit? */ + !(mpx_flags [port] & (FL_WAITACK | FL_XOFF)) || /* and transmission not suspended */ tmxr_rqln (&mpx_ldsc [port])) /* or more to receive? */ sim_activate (uptr, uptr->wait); /* reschedule service */ else diff --git a/HP2100/hp2100_ms.c b/HP2100/hp2100_ms.c index bc24f172..daf35448 100644 --- a/HP2100/hp2100_ms.c +++ b/HP2100/hp2100_ms.c @@ -26,6 +26,7 @@ MS 13181A 7970B 800bpi nine track magnetic tape 13183A 7970E 1600bpi nine track magnetic tape + 09-May-12 JDB Separated assignments from conditional expressions 10-Feb-12 JDB Deprecated DEVNO in favor of SC Added CNTLR_TYPE cast to ms_settype 28-Mar-11 JDB Tidied up signal handling @@ -737,7 +738,8 @@ switch (uptr->FNC) { /* case on function */ fprintf (sim_deb, ">>MSC svc: Unit %d wrote initial gap\n", unum); - if ((st = ms_write_gap (uptr))) { /* write initial gap; error? */ + st = ms_write_gap (uptr); /* write initial gap*/ + if (st != MTSE_OK) { /* error? */ r = ms_map_err (uptr, st); /* map error */ break; /* terminate operation */ } @@ -747,13 +749,15 @@ switch (uptr->FNC) { /* case on function */ fprintf (sim_deb, ">>MSC svc: Unit %d wrote file mark\n", unum); - if ((st = sim_tape_wrtmk (uptr))) /* write tmk, err? */ + st = sim_tape_wrtmk (uptr); /* write tmk */ + if (st != MTSE_OK) /* error? */ r = ms_map_err (uptr, st); /* map error */ msc_sta = STA_EOF; /* set EOF status */ break; case FNC_FSR: /* space forward */ - if ((st = sim_tape_sprecf (uptr, &tbc))) /* space rec fwd, err? */ + st = sim_tape_sprecf (uptr, &tbc); /* space rec fwd */ + if (st != MTSE_OK) /* error? */ r = ms_map_err (uptr, st); /* map error */ if (tbc & 1) msc_sta = msc_sta | STA_ODD; @@ -761,7 +765,8 @@ switch (uptr->FNC) { /* case on function */ break; case FNC_BSR: /* space reverse */ - if ((st = sim_tape_sprecr (uptr, &tbc))) /* space rec rev, err? */ + st = sim_tape_sprecr (uptr, &tbc); /* space rec rev*/ + if (st != MTSE_OK) /* error? */ r = ms_map_err (uptr, st); /* map error */ if (tbc & 1) msc_sta = msc_sta | STA_ODD; @@ -831,7 +836,8 @@ switch (uptr->FNC) { /* case on function */ fprintf (sim_deb, ">>MSC svc: Unit %d wrote initial gap\n", unum); - if ((st = ms_write_gap (uptr))) { /* write initial gap; error? */ + st = ms_write_gap (uptr); /* write initial gap */ + if (st != MTSE_OK) { /* error? */ r = ms_map_err (uptr, st); /* map error */ break; /* terminate operation */ } @@ -855,7 +861,8 @@ switch (uptr->FNC) { /* case on function */ fprintf (sim_deb, ">>MSC svc: Unit %d wrote %d word record\n", unum, ms_ptr / 2); - if ((st = sim_tape_wrrecf (uptr, msxb, ms_ptr))) { /* write, err? */ + st = sim_tape_wrrecf (uptr, msxb, ms_ptr); /* write */ + if (st != MTSE_OK) { r = ms_map_err (uptr, st); /* map error */ break; } @@ -894,7 +901,9 @@ t_stat st; uint32 gap_len = ms_ctype ? GAP_13183 : GAP_13181; /* establish gap length */ uint32 tape_bpi = ms_ctype ? BPI_13183 : BPI_13181; /* establish nominal bpi */ -if ((st = sim_tape_wrgap (uptr, gap_len, tape_bpi))) /* write gap */ +st = sim_tape_wrgap (uptr, gap_len, tape_bpi); /* write gap */ + +if (st != MTSE_OK) return ms_map_err (uptr, st); /* map error if failure */ else return SCPE_OK; @@ -974,7 +983,9 @@ for (i = 0; i < MS_NUMDR; i++) { /* look for write in pro fprintf (sim_deb, ">>MSC rws: Unit %d wrote %d word partial record\n", i, ms_ptr / 2); - if ((st = sim_tape_wrrecf (uptr, msxb, ms_ptr | MTR_ERF))) + st = sim_tape_wrrecf (uptr, msxb, ms_ptr | MTR_ERF); + + if (st != MTSE_OK) ms_map_err (uptr, st); /* discard any error */ ms_ptr = 0; /* clear partial */ diff --git a/HP2100/hp2100_mt.c b/HP2100/hp2100_mt.c index ecdfbf80..3e7cc1cf 100644 --- a/HP2100/hp2100_mt.c +++ b/HP2100/hp2100_mt.c @@ -25,6 +25,7 @@ MT 12559A 3030 nine track magnetic tape + 09-May-12 JDB Separated assignments from conditional expressions 25-Mar-12 JDB Removed redundant MTAB_VUN from "format" MTAB entry 10-Feb-12 JDB Deprecated DEVNO in favor of SC 28-Mar-11 JDB Tidied up signal handling @@ -495,7 +496,8 @@ switch (mtc_fnc) { /* case on function */ return sim_tape_detach (uptr); /* don't set cch flg */ case FNC_WFM: /* write file mark */ - if ((st = sim_tape_wrtmk (uptr))) /* write tmk, err? */ + st = sim_tape_wrtmk (uptr); /* write tmk */ + if (st != MTSE_OK) /* error? */ r = mt_map_err (uptr, st); /* map error */ mtc_sta = STA_EOF; /* set EOF status */ break; @@ -504,12 +506,14 @@ switch (mtc_fnc) { /* case on function */ break; case FNC_FSR: /* space forward */ - if ((st = sim_tape_sprecf (uptr, &tbc))) /* space rec fwd, err? */ + st = sim_tape_sprecf (uptr, &tbc); /* space rec fwd */ + if (st != MTSE_OK) /* error? */ r = mt_map_err (uptr, st); /* map error */ break; case FNC_BSR: /* space reverse */ - if ((st = sim_tape_sprecr (uptr, &tbc))) /* space rec rev, err? */ + st = sim_tape_sprecr (uptr, &tbc); /* space rec rev */ + if (st != MTSE_OK) /* error? */ r = mt_map_err (uptr, st); /* map error */ break; @@ -558,7 +562,8 @@ switch (mtc_fnc) { /* case on function */ return SCPE_OK; } if (mt_ptr) { /* write buffer */ - if ((st = sim_tape_wrrecf (uptr, mtxb, mt_ptr))) { /* write, err? */ + st = sim_tape_wrrecf (uptr, mtxb, mt_ptr); /* write */ + if (st != MTSE_OK) { /* error? */ r = mt_map_err (uptr, st); /* map error */ break; /* done */ } @@ -627,7 +632,8 @@ t_stat st; if (sim_is_active (&mtc_unit) && /* write in prog? */ (mtc_fnc == FNC_WC) && (mt_ptr > 0)) { /* yes, bad rec */ - if ((st = sim_tape_wrrecf (&mtc_unit, mtxb, mt_ptr | MTR_ERF))) + st = sim_tape_wrrecf (&mtc_unit, mtxb, mt_ptr | MTR_ERF); + if (st != MTSE_OK) mt_map_err (&mtc_unit, st); } diff --git a/HP2100/hp2100_stddev.c b/HP2100/hp2100_stddev.c index 9664be58..edf44c2c 100644 --- a/HP2100/hp2100_stddev.c +++ b/HP2100/hp2100_stddev.c @@ -28,6 +28,7 @@ TTY 12531C buffered teleprinter interface CLK 12539C time base generator + 09-May-12 JDB Separated assignments from conditional expressions 12-Feb-12 JDB Add TBG as a logical name for the CLK device 10-Feb-12 JDB Deprecated DEVNO in favor of SC 28-Mar-11 JDB Tidied up signal handling @@ -942,7 +943,9 @@ t_stat r; if (tty_mode & TM_PRI) { /* printing? */ c = sim_tt_outcvt (c, TT_GET_MODE (tty_unit[TTO].flags)); if (c >= 0) { /* valid? */ - if ((r = sim_putchar_s (c))) return r; /* output char */ + r = sim_putchar_s (c); /* output char */ + if (r != SCPE_OK) + return r; tty_unit[TTO].pos = tty_unit[TTO].pos + 1; } } @@ -1114,7 +1117,7 @@ while (working_set) { if ((clk_unit.flags & UNIT_DIAG) == 0) /* calibrated? */ if (clk_select == 2) /* 10 msec. interval? */ - clk_tick = sync_poll (INITIAL); /* sync poll */ + clk_tick = sync_poll (INITIAL); /* sync poll */ else sim_rtcn_init (clk_tick, TMR_CLK); /* initialize timer */ diff --git a/HP2100/hp2100_sys.c b/HP2100/hp2100_sys.c index e47687c0..c8681731 100644 --- a/HP2100/hp2100_sys.c +++ b/HP2100/hp2100_sys.c @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 09-May-12 JDB Quieted warnings for assignments in conditional expressions 10-Feb-12 JDB Deprecated DEVNO in favor of SC Added hp_setsc, hp_showsc functions to support SC modifier 15-Dec-11 JDB Added DA and dummy DC devices diff --git a/HP2100/hp_disclib.c b/HP2100/hp_disclib.c index 7f69af4c..ea51945e 100644 --- a/HP2100/hp_disclib.c +++ b/HP2100/hp_disclib.c @@ -24,7 +24,8 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. - 28-Mar-12 JDB First release + 07-May-12 JDB Corrected end-of-track delay time logic + 02-May-12 JDB First release 09-Nov-11 JDB Created disc controller common library from DS simulator References: @@ -761,8 +762,8 @@ else { /* for an ICD controller uptr = units + unit_limit; /* and we use the indicated unit */ } -if ((props->unit_check && !uptr) || /* if the unit number is checked and is invalid */ - (props->seek_wait && (drive_status (uptr) & DL_S2STOPS))) { /* or if we're waiting for an offline drive */ +if (props->unit_check && !uptr /* if the unit number is checked and is invalid */ + || props->seek_wait && (drive_status (uptr) & DL_S2STOPS)) { /* or if we're waiting for an offline drive */ dl_end_command (cvptr, status_2_error); /* then the command ends with a Status-2 error */ uptr = NULL; /* prevent the command from starting */ } @@ -1817,28 +1818,61 @@ return SCPE_OK; /* the read was successf On entry, the end-of-data flag is checked. If it is set, the current read is completed. Otherwise, the command phase is reset to start the next sector, - and the disc service is scheduled to allow for the intersector delay. + and the disc service is set to allow for the intersector delay. Implementation notes: - 1. The intersector time is required to allow the ICD interface to set the - end-of-data flag before the next sector begins. The CPU must have enough - time to receive the last byte of the current sector and then unaddress - the disc controller before the first byte of the next sector is sent. If - the time is not long enough, the sector address will be incremented twice - (e.g., a 128-word read of sector 0 will terminate with sector 2 as the - next sector instead of sector 1). + 1. The CPU indicates the end of a read data transfer to an ICD controller by + untalking the drive. The untalk is done by the driver as soon as the + DCPC completion interrupt is processed. However, the time from the final + DCPC transfer through driver entry to the point where the untalk is + asserted on the bus varies from 80 instructions (RTE-6/VM with OS + microcode and the buffer in the system map) to 152 instructions (RTE-IVB + with the buffer in the user map). The untalk must occur before the start + of the next sector, or the drive will begin the data transfer. + + Normally, this is not a problem, as the driver clears the FIFO of any + received data after DCPC completion. However, if the read terminates + after the last sector of a track, and accessing the next sector would + require an intervening seek, and the file mask disables auto-seeking or + an enabled seek would move the positioner beyond the drive limits, then + the controller will indicate an End of Cylinder error if the untalk does + not arrive before the seek is initiated. + + The RTE driver (DVA32) and various utilities that manage the disc + directly (e.g., SWTCH) do not appear to account for these bogus errors, + so the ICD controller hardware must avoid them in some unknown manner. + We work around the issue by extending the intersector delay to allow time + for a potential untalk whenever the next access would otherwise fail. + + Note that this issue does not occur with writes because DCPC completion + asserts EOI concurrently with the final data byte to terminate the + command. */ static void end_read (CVPTR cvptr, UNIT *uptr) { +uint32 limit; + if (cvptr->eod == SET) /* is the end of data indicated? */ dl_end_command (cvptr, normal_completion); /* complete the command */ else { /* reading continues */ uptr->PHASE = start_phase; /* reset to the start phase */ uptr->wait = cvptr->sector_time; /* delay for the intersector time */ + + if (cvptr->eoc == SET && cvptr->type == ICD) { /* seek will be required and controller is ICD? */ + if (!(cvptr->file_mask & DL_FAUTSK)) /* if auto-seek is disabled */ + limit = cvptr->cylinder; /* then the limit is the current cylinder */ + else if (cvptr->file_mask & DL_FDECR) /* else if enabled and decremental seek */ + limit = 0; /* then the limit is cylinder 0 */ + else /* else the enabled limit is the last cylinder */ + limit = drive_props [GET_MODEL (uptr->flags)].cylinders; + + if (cvptr->cylinder == limit) /* is positioner at the limit? */ + uptr->wait = cvptr->eot_time; /* seek will fail; delay to allow CPU to untalk */ + } } return; @@ -1879,8 +1913,8 @@ static void start_write (CVPTR cvptr, UNIT *uptr) { const t_bool verify = (CNTLR_OPCODE) uptr->OP == write; /* only Write verifies the sector address */ -if ((uptr->flags & UNIT_WPROT) || /* is the unit write protected, */ - (!verify && !(uptr->flags & UNIT_FMT))) /* or is formatting required but not enabled? */ +if ((uptr->flags & UNIT_WPROT) /* is the unit write protected, */ + || !verify && !(uptr->flags & UNIT_FMT)) /* or is formatting required but not enabled? */ dl_end_command (cvptr, status_2_error); /* terminate the write with an error */ else if (position_sector (cvptr, uptr, verify)) { /* writing is permitted; position the sector */ @@ -1964,12 +1998,12 @@ return SCPE_OK; /* Position the disc image file at the current sector. - The image file is positioned at the byte address corresponding to the - controller's current cylinder, head, and sector address. Positioning may - involve an auto-seek if a prior read or write addressed the final sector in a - cylinder. If a seek is initiated or an error is detected, the routine - returns FALSE to indicate that the positioning was not performed. If the - file was positioned, the routine returns TRUE. + The image file is positioned at the byte address corresponding to the drive's + current cylinder and the controller's current head and sector addresses. + Positioning may involve an auto-seek if a prior read or write addressed the + final sector of a cylinder. If a seek is initiated or an error is detected, + the routine returns FALSE to indicate that the positioning was not performed. + If the file was positioned, the routine returns TRUE. On entry, if the controller's end-of-cylinder flag is set, a prior read or write addressed the final sector in the current cylinder. If the file mask @@ -1983,21 +2017,23 @@ return SCPE_OK; seek completion and the command state unchanged. When the service is reentered, the read or write will continue on the new cylinder. - If the EOC flag was not set, the drive position is checked against the - controller position. If they are different (as may occur with an Address - Record command that specified a different location than the last Seek - command), a seek is started to the correct cylinder, and the routine returns - with the disc service scheduled for seek completion as above. + If the EOC flag was not set, the drive's position is checked against the + controller's position if address verification is requested. If they are + different (as may occur with an Address Record command that specified a + different location than the last Seek command), a seek is started to the + correct cylinder, and the routine returns with the disc service scheduled for + seek completion as above. - If the drive and controller positions agree, the controller CHS address is - validated against the drive limits. If they are invalid, Seek Check status - is set, and the command is terminated with an error. + If the drive and controller positions agree or verification is not requested, + the CHS addresses are validated against the drive limits. If they are + invalid, Seek Check status is set, and the command is terminated with an + error. - If the address is valid, the drive is checked to ensure that it is ready for - positioning. If it is, the the byte offset in the image file is calculated - from the CHS address, and the file is positioned. The disc service is - scheduled to begin the data transfer, and the routine returns TRUE to - indicate that the file position was set. + If the addresses are valid, the drive is checked to ensure that it is ready + for positioning. If it is, the the byte offset in the image file is + calculated from the CHS address, and the file is positioned. The disc + service is scheduled to begin the data transfer, and the routine returns TRUE + to indicate that the file position was set. Implementation notes: diff --git a/HP2100/hp_disclib.h b/HP2100/hp_disclib.h index 315fc6ec..90b2d82b 100644 --- a/HP2100/hp_disclib.h +++ b/HP2100/hp_disclib.h @@ -24,7 +24,8 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. - 30-Mar-12 JDB First release + 07-May-12 JDB Added end-of-track delay time as a controller variable + 02-May-12 JDB First release 09-Nov-11 JDB Created disc controller common library from DS simulator @@ -53,6 +54,7 @@ /* Default controller times */ +#define DL_EOT_TIME 160 /* end-of-track delay time */ #define DL_SEEK_TIME 100 /* seek delay time (per cylinder) */ #define DL_SECTOR_TIME 27 /* intersector delay time */ #define DL_CMD_TIME 3 /* command start delay time */ @@ -330,6 +332,7 @@ typedef struct { uint32 index; /* data buffer current index */ uint32 length; /* data buffer valid length */ UNIT *aux; /* MAC auxiliary units (controller and timer) */ + int32 eot_time; /* end-of-track read delay time */ int32 seek_time; /* per-cylinder seek delay time */ int32 sector_time; /* intersector delay time */ int32 cmd_time; /* command response time */ @@ -354,7 +357,7 @@ typedef CNTLR_VARS *CVPTR; /* pointer to controller CLEAR, CLEAR, \ 0, 0, 0, 0, 0, 0, 0, 0, \ (bufptr), 0, 0, (auxptr), \ - DL_SEEK_TIME, DL_SECTOR_TIME, \ + DL_EOT_TIME, DL_SEEK_TIME, DL_SECTOR_TIME, \ DL_CMD_TIME, DL_DATA_TIME, DL_WAIT_TIME