From 21285ca17b141a94d090ff14dc2df9148732678c Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Thu, 28 Jun 2018 13:03:08 -0400 Subject: [PATCH] B5500: Fixed disconneting from DTC and processor switching. --- B5500/b5500_cpu.c | 34 +++++++++++++++------------------- B5500/b5500_dtc.c | 44 +++++++++++++++++++++++++++++--------------- B5500/b5500_sys.c | 4 ++-- 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/B5500/b5500_cpu.c b/B5500/b5500_cpu.c index 9245b9e..1de374c 100644 --- a/B5500/b5500_cpu.c +++ b/B5500/b5500_cpu.c @@ -213,7 +213,7 @@ uint16 l_reg[2]; /* L current syllable pointer */ uint8 ncsf_reg[2]; /* True if normal state */ uint8 salf_reg[2]; /* True if subrogram mode */ uint8 cwmf_reg[2]; /* True if character mode */ -uint8 hltf[2]; /* True if processor halted */ +uint16 hltf[2]; /* True if processor halted */ uint8 msff_reg[2]; /* Mark stack flag Word mode */ #define TFFF MSFF /* True state in Char mode */ uint8 varf_reg[2]; /* Variant Flag */ @@ -960,10 +960,10 @@ void storeInterrupt(int forced, int test) { } AROF = 0; B = ICW; /* Set ICW into B */ - next_addr(S); /* Save B */ + next_addr(S); /* Save B */ memory_cycle(11); B = RCW(f); /* Save IRCW */ - next_addr(S); /* Save B */ + next_addr(S); /* Save B */ memory_cycle(11); if (CWMF) { /* Get the correct value of R */ @@ -1994,7 +1994,6 @@ sim_instr(void) if (P1_run == 0) return SCPE_STOP; while (loading) { - sim_interval = -1; reason = sim_process_event(); if (reason != SCPE_OK) { break; /* process */ @@ -2027,20 +2026,15 @@ sim_instr(void) } /* Toggle between two CPU's. */ + if (TROF == 0 && NCSF) { + if (Q != 0 || ((cpu_index)? HLTF : IAR) != 0) + storeInterrupt(1,0); + } + if (cpu_index == 0 && P2_run == 1) { cpu_index = 1; - /* Check if interrupt pending. */ - if (TROF == 0 && NCSF && ((Q != 0) || HLTF)) - /* Force a SFI */ - storeInterrupt(1,0); } else { cpu_index = 0; - - /* Check if interrupt pending. */ - if (TROF == 0 && NCSF && ((Q != 0) || - (IAR != 0))) - /* Force a SFI */ - storeInterrupt(1,0); } if (TROF == 0) next_prog(); @@ -3678,15 +3672,17 @@ control: R = 0; F = S; /* Set F and X */ X = toF(S); - S = CF(B); if (B & FLAG) { - if ((B & PRESENT) == 0 && NCSF) - Q |= PRES_BIT; - else - KV = 0; + if ((B & PRESENT) == 0) { + if (NCSF) + Q |= PRES_BIT; + break; + } + KV = 0; } else { KV = (uint8)((B >> (FFIELD_V - 3)) & 070); } + S = CF(B); break; case VARIANT(WMOP_MKS): /* Mark Stack */ diff --git a/B5500/b5500_dtc.c b/B5500/b5500_dtc.c index 560b936..229dad9 100644 --- a/B5500/b5500_dtc.c +++ b/B5500/b5500_dtc.c @@ -76,6 +76,7 @@ #define BufAbnormal 010 /* Abnornmal flag */ #define BufGM 020 /* Buffer term with GM */ #define BufIRQ 040 /* Buffer ready */ +#define BufDisco 0100 /* Buffer disconnecting */ /* Not connected line: BufNotReady. @@ -350,7 +351,7 @@ t_stat dtc_srv(UNIT * uptr) } /* Process for each unit */ if (uptr->u5 & DTC_WR) { - if (line > dtc_desc.lines || line == -1) { + if (line > dtc_desc.lines || line == -1 || dtc_lstatus[line] & BufDisco) { sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm write invalid %d\n", line); chan_set_notrdy(chan); @@ -434,7 +435,7 @@ t_stat dtc_srv(UNIT * uptr) } if (uptr->u5 & DTC_RD) { - if (line > dtc_desc.lines || line == -1) { + if (line > dtc_desc.lines || line == -1 || dtc_lstatus[line] & BufDisco) { sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm read nothing %d\n", line); chan_set_notrdy(chan); @@ -489,7 +490,7 @@ t_stat dtc_srv(UNIT * uptr) if (dtc_lstatus[line] & BufAbnormal) chan_set_wcflg(chan); if (dtc_ldsc[line].conn == 0) /* connected? */ - dtc_lstatus[line] = BufIRQ|BufNotReady; + dtc_lstatus[line] = BufIRQ|BufAbnormal|BufIRQ|BufIdle; else dtc_lstatus[line] = BufIRQ|BufIdle; dtc_bsize[line] = 0; @@ -524,6 +525,7 @@ dtco_srv(UNIT * uptr) sim_clock_coschedule(uptr, tmxr_poll); ln = tmxr_poll_conn(&dtc_desc); /* look for connect */ if (ln >= 0) { /* got one? */ + dtc_ldsc[ln].rcve = 1; dtc_blimit[ln] = dtc_bufsize-1; dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufWriteRdy; IAR |= IRQ_12; @@ -532,32 +534,43 @@ dtco_srv(UNIT * uptr) /* For each line that is in idle state enable recieve */ for (ln = 0; ln < dtc_desc.lines; ln++) { - if (dtc_ldsc[ln].conn && - (dtc_lstatus[ln] & BufSMASK) == BufIdle) { + dtc_ldsc[ln].rcve = 0; + if (dtc_ldsc[ln].conn && + (dtc_lstatus[ln] & BufSMASK) < BufWrite) { dtc_ldsc[ln].rcve = 1; } } tmxr_poll_rx(&dtc_desc); /* poll for input */ for (ln = 0; ln < DTC_MLINES; ln++) { /* loop thru mux */ /* Check for disconnect */ - if (dtc_ldsc[ln].conn == 0) { /* connected? */ + if (dtc_ldsc[ln].conn == 0 && (dtc_lstatus[ln] & BufDisco) == 0) { /* connected? */ + dtc_ldsc[ln].rcve = 0; switch(dtc_lstatus[ln] & BufSMASK) { - case BufIdle: /* Idle, throw in EOT */ - /* Fall through */ + case BufIdle: /* Idle Flag as disconnected */ + dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufIdle|BufDisco; + dtc_bsize[ln] = 0; + IAR |= IRQ_12; + sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d idle\n", ln); + break; + case BufWriteRdy: /* Awaiting output, terminate */ dtc_bufptr[ln] = 0; /* Fall through */ case BufInputBusy: /* reading, terminate with EOT */ dtc_buf[ln][dtc_bufptr[ln]++] = 017; - dtc_bsize[ln] = dtc_bufptr[ln]; + dtc_bsize[ln] = dtc_bufptr[ln]+1; dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufReadRdy; IAR |= IRQ_12; + sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d write\n", ln); break; + case BufOutBusy: /* Terminate Output */ - dtc_lstatus[ln] = BufIRQ|BufIdle; + dtc_lstatus[ln] = BufIRQ|BufIdle|BufAbnormal; dtc_bsize[ln] = 0; IAR |= IRQ_12; + sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d out\n", ln); break; + default: /* Other cases, ignore until in better state */ break; @@ -568,9 +581,10 @@ dtco_srv(UNIT * uptr) switch(dtc_lstatus[ln] & BufSMASK) { case BufIdle: /* If we have any data to receive */ - if (tmxr_rqln(&dtc_ldsc[ln]) > 0) - dtc_lstatus[ln] = BufInputBusy; - else + if (tmxr_rqln(&dtc_ldsc[ln]) > 0) { + dtc_lstatus[ln] &= ~(BufSMASK); + dtc_lstatus[ln] |= BufInputBusy; + } else break; /* Nothing to do */ sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm recieve %d idle\n", ln); @@ -580,9 +594,9 @@ dtco_srv(UNIT * uptr) case BufInputBusy: t = 1; - while (t && tmxr_rqln(&dtc_ldsc[ln]) != 0) { + while (t) { c = tmxr_getc_ln(&dtc_ldsc[ln]); /* get char */ - if ((c & TMXR_VALID) == 0) + if (c == 0) break; c &= 0x7f; c1 = ascii_to_con[c]; diff --git a/B5500/b5500_sys.c b/B5500/b5500_sys.c index 0b65161..3eda265 100644 --- a/B5500/b5500_sys.c +++ b/B5500/b5500_sys.c @@ -136,7 +136,7 @@ const char ascii_to_con[128] = { /* Control */ -1, -1, -1, -1, -1, -1, -1, -1, /*sp ! " # $ % & ' */ - 020, 032, 037, 013, 053, 017, 060, 014, /* 40 - 77 */ + 020, 032, 037, 013, 053, 034, 060, 014, /* 40 - 77 */ /* ( ) * + , - . / */ 075, 055, 054, 072, 033, 040, 073, 021, /* 0 1 2 3 4 5 6 7 */ @@ -158,7 +158,7 @@ const char ascii_to_con[128] = { /* p q r s t u v w */ 047, 050, 051, 022, 023, 024, 025, 026, /* x y z { | } ~ del*/ - 027, 030, 031, 057, 077, 017, -1, -1 + 027, 030, 031, 057, 052, 017, -1, -1 };