From f82d3f8994666ab8e6ac296b0790a9316f2464b7 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 31 Aug 2016 08:10:38 -0700 Subject: [PATCH] SCP: Breakpoint enhancements - Reliable support for multiple breakpoint types - Optional separate breakpoint types defined concurrently with the same address --- doc/simh_breakpoints.doc | Bin 39424 -> 41984 bytes scp.c | 261 ++++++++++++++++++++++++++++----------- scp.h | 5 +- sim_defs.h | 3 + 4 files changed, 195 insertions(+), 74 deletions(-) diff --git a/doc/simh_breakpoints.doc b/doc/simh_breakpoints.doc index f40b6b6197378c84a57f99d6e3b4885b6ecd5e2e..80b75cde92a165456601e42ffb312fdd41478cba 100644 GIT binary patch delta 5447 zcmb`LdvH|M9mmgZHX$J45h3BtjUgmp5)x7r&>~MOpdw18brjg_Uf3m@-E|+qi1tDO zDV=r-Ibfaf0otiN21m(i#SWt#6$Gg*phcl$a2%Y0ii#P~!hq@LcXv10gkt@pcjvR` zp7-y3f9JKk;$`QG{m%7O#vLm4^igUKuMYUGt*uQ`Z-+$R$6sP;=D;p z{d>Ue_Y2!f^aj^39dI^TLnyhsK&f)VrwHZwv`DEvG$?_1& z^IyWzS7eMJ<(Xoo{zT1rBbC}nd@T+1*K?iM_V`uGq&EtQ7F^f0$FA|UMfy_KFe^O( zyEDEd{!hZEXjd9^4^HNE4W+q#4yDq)rrYTnmw{$J>2^|S`a9RCinM80D=T#-Qem!v zGqgK*wsnj*dD6Y&Tidx+O;+)StRvW!eA4M_1}fD|(xZk_JyLlR+<|rd2%8D32*thf ztTmLnoA4AW%X8x(rAE`L#3`Spjv4xE*R8X}4ym6mCuQYHtMG-P)FR^P5vIem3h6jL z+u#~`RiBBI<-unZbGiphFrlMzGB+Jh4KweH$L zqfu)b?uL-xYkG~SKj<-yn9npGr`$4s%;PisQ6nBDueQ<7(D&RnXTCA@?io{NQ)r{% z3DwuTgI*&RGQ9q1IN)wHJn=}x48~~M@|uhNL8;tsMbvOd)0LveGM}F=Jno=aK^-$f zVSmtY8_{@e)O;{b8u5mZ#~t&Bf<|buZA8>x9}l==p@?)FF+H>%OWGZE*P9)^Wyg%D z8B6@7@1I?X#)4OziHd>G=2+9suo?9FgG&rrl)-vJUek!iB5_YF9x=OgBC<3_V`jZ! z50m0ycO>TbU;y2Vq!`sPzH)5uh#B?h!O&vvI#b5DI21801H0Xe8LJF4YZ ziTNA+u|~s})F&J;W2U##FlH_`{AdvE)P`+#C~QWOvPc~oh`R%}Kk14r`l>g*C1FC z`qyO)E#`B_jAitk99&u*e=w<}xGUK!3VK3u9BEr(SIdwvqs8{d>|yJol0gd@1eVZI zMloA-5hP^GV7okR_0_Eqdy-~IRop1`bgv>q&n{YL&17yxytsr$88q^tWHcTQ+ge0S zdt!Ik5KZ~SUmp%dVs2SnVx%-%8w%CcnPyn#mz{`{+o!8HWZHH!XX(x^Z|haU)Wg6G zFSbh;3^91q@P>k>c)>!OdE%PPeuzrGtWmdjX*?RMXWiHx(e*;sz8Pt72kZ%)v93H! zm-a#o+JoB{nhjK~WYT4t9WhxLShqM5vg&0xw27C?Mj75XlbcDC=^xXN4&pX8mUe5T zR3~Fn+fZs~=>-u8WVYn-nVvd(p(dNd4mOvd5eO||$=K@p@OS`GGkue4Iv!l+XJ>K; z@nk0%GK>ee9NtpT}e=&2Qj{U44rt8uw2=ge}d zxp05($_2BWdS1oE()I;H8~R@_&3p!@Tk5~X18Mg8^BicyY{ zO_kp6yBP8jxTv?(4AhT~$cgLKbvdHVIL?Y!sd zCDl{(1I}LhXgBq@EELxom^91fW5E}p5@~69Q>TC=zY)to8T2V3LiqRp-T0I zYM28d2*VoK1#iPKI1QIOY}D4+-i~i|-w z;52mO4pa?yfgh|QOQ{!mnSY&9KZ6;?+z??YEQcrH4{#VhhFM&n=fiR+W_3fXQg5xcZwKTRUr3MuEntNBK=D&Wc zqR1ND-#61cR2A6Y8S6r3KXY30x-N)?3py`|)ZD+KT>hL%SEOy|cSEN%ODcQwmv>53 zIY~1mPt5IPKtX};Z#S$^(`NM}-NhPqsRf`&m$F^c$H;X09K@wwT$y(3dftC&;2QB` z+BFZSWIs@%)Vt6N>C-NFg!gA*2ke3O;R6_oD~7>`Z~=|mpYNHK?Pc`#nm*PKDM*d~ zZ?UuOHXxoltEY?`=j%WGa4DY}}_zEsV zKQtcz#ZU=5N|b)RcDa79b_g2)e{f`@6zuCpT`2C(?{^r5I@f0?l+R!Wz*4A(=RgMC z47=fN*bm3x1YBmRJzN#5 z78E@J=Md~0xCSFdw1Kb{c9iI9?{&kol#9O=u1aF8_sML_p>C<$I-S8MAI@J+6W(3G z*wkmqbk&zo?pJc8aD7s8+{i92$Alaoav!@h7FKdX$gVHzFn9VNm0Z6rjo78+GAGMy za>-kEi?X;7ccL9}@ZB~!YlXx1tN2zP2cPtNI&`A1{cI~qj9q%rQ8a8lm7T8atZY|K zmebYdRG+ksP*YQ-)Mkes78qZ%|H5rcB&nymp20nn&0jW#Tr^nTB2XU@pmXZ<#Ja#j zN6se9+*BfeQzXiRA2@V4cT02leuuMqtX}Y7>G(Hy?^);M{!Ddsvd^Z`XWw+#?~7jR zC;u5`kxXBBA=$iy(s5Rzdi=CrO)Fl?myRV>43ThCN#e~FJ9_`f-Yba9-h$ihzZz3h zlnJ2J2*5POsisOn{)*IF){lSSMk3>30*JUbfn@%ea1z`ClVJ*oO4C5{XAs^BKY`m| zCd`7_Ao-W!PF=L&U{h0|`{bT$?f=B?((xwCVd(QsR!$iOFOAd>Ys)c7U(^pfZr1UQ NmScM2{Kjjt{{w~L=Gp)N delta 3026 zcmai$4Qy5Q6~NEE@4fQ)sQsX{wY25(T4=|h&=10lmd{dt*2I~%vZPae*QEt8w2#XdGe0i?EXkrM_D zWWU9+72d8+wyRaRlo8ACEmeR!eU zji${%mE6XXyJ6YI=<(jaYrbR6@1J(7$WeM8V%@O#n2OJ^(~x&NB2$o>UTtmk-;LZh zE@sN7tX~tinIDkuG5B%UY=69OR(~|qKZj2LX1?@qgG*OeRG4;(zvMw#ldde*j(S_tZ1rVX^Qj4SgTD<{wQ-e&&i2Re6Xppeq&2)iyP;j z&fD&_jo%eEnUg;;8^XuJVUb*zX%eSQcK?zjat@kDl3*B5CJUexwm=jvLvWNx5w%|h zAHqivB{~N(Mg9PHjix_aSpTmZ+B5%QR9?d!!%cEHY6;KKD3q=+c$}(AsvK}@= z6nfz5rH^Bu_qt!bbd}FbCoUa~e-7-%R&>rm*mh9=`jX!N-<+J8Js~}P)zPFPsa=pJ zixvcBG1P&i_Vo|wGhb9@8>cwetSG+M{I@vMD(Ng~2pzgbH!W0Ux814ZV+96p}lrsJX|3$trDHSV;cw&r0IPdEN<@D-AlT*>kCBo+X)Zymc z>YUQiy4TC_3Y>nnP>~4c{n8j1$={-!et01 z@=&r<735LHMKBM346ni&cnde)fe+yVd=3}k3h38F8sxxgXoW{$J3I=Hr->^aD0|^a zH~=rfpW(0Y1{~*3e*%O5dmx!Rq(PWFjDUI6>q3Z7XGM@g5oEwLir_ZrfZgCYBKa^M zmcn|7IzvUiMj0YO^Z6Rr6&h<}5wWSeB)FA$Mj)5lIsn z3Egl8mc}dgdE_BD$3gEy{Cs>UHQ}bornIRrvYZRmK?N78ggfzZ5j4V=@U>&EHATGp z*F{6FEo2ICQT_wkEYNq`#MI+4TkA#7(WYa)HCDSNbI=rR79U^trOi*lSkvXdBJ@(D z<)#}9ktNbBYr%V=<#$$6>MqL?I~WRtf(ZdT$ginPv$eIP^nrKgKc`zHNCrNB3PZV0 zh^^G=Kyo$m#@=f0lh*sKgbNP!nRVP$laJ*AHo=+;%pSvU`RsmFu zI4~A?MMxg#_&6jFloS9Dm6-i|E0^d%CB`(U0zF_l+y*m1$7_(YU^djk?Vy343p#!c zeiYZ$zTUC;OlMcq(BzT5v7cuPO>38HWt*?M+=P7Qb&WI8r(CPtTzM*LRhZU&t~Jy9 JYTxkC{{anUN2mY* diff --git a/scp.c b/scp.c index f5762b4d..f8a0fb61 100644 --- a/scp.c +++ b/scp.c @@ -393,7 +393,9 @@ t_stat sim_brk_clrall (int32 sw); t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw); t_stat sim_brk_showall (FILE *st, int32 sw); CONST char *sim_brk_getact (char *buf, int32 size); -BRKTAB *sim_brk_new (t_addr loc); +BRKTAB *sim_brk_new (t_addr loc, uint32 btyp); +char *sim_brk_clract (void); + FILE *stdnul; /* Command support routines */ @@ -475,12 +477,10 @@ uint32 sim_brk_types = 0; uint32 sim_brk_dflt = 0; char *sim_brk_act[MAX_DO_NEST_LVL]; char *sim_brk_act_buf[MAX_DO_NEST_LVL]; -BRKTAB *sim_brk_tab = NULL; +BRKTAB **sim_brk_tab = NULL; int32 sim_brk_ent = 0; int32 sim_brk_lnt = 0; int32 sim_brk_ins = 0; -t_bool sim_brk_pend[SIM_BKPT_N_SPC] = { FALSE }; -t_addr sim_brk_ploc[SIM_BKPT_N_SPC] = { 0 }; int32 sim_quiet = 0; int32 sim_step = 0; static double sim_time; @@ -4604,7 +4604,8 @@ t_stat r; if (cptr && (*cptr != 0)) r = ssh_break (st, cptr, 1); /* more? */ -else r = sim_brk_showall (st, sim_switches); +else + r = sim_brk_showall (st, sim_switches); return r; } @@ -5045,7 +5046,7 @@ t_addr lo, hi, max = uptr->capac - 1; int32 cnt; if (sim_brk_types == 0) - return SCPE_NOFNC; + return sim_messagef (SCPE_NOFNC, "No breakpoint support in this simulator\n"); if ((dptr == NULL) || (uptr == NULL)) return SCPE_IERR; abuf[sizeof(abuf)-1] = '\0'; @@ -5077,9 +5078,11 @@ while (*cptr) { if ((lo == 0) && (hi == max)) { if (flg == SSH_CL) sim_brk_clrall (sim_switches); - else if (flg == SSH_SH) - sim_brk_showall (st, sim_switches); - else return SCPE_ARG; + else + if (flg == SSH_SH) + sim_brk_showall (st, sim_switches); + else + return SCPE_ARG; } else { for ( ; lo <= hi; lo = lo + 1) { @@ -5094,6 +5097,8 @@ return SCPE_OK; t_stat ssh_break_one (FILE *st, int32 flg, t_addr lo, int32 cnt, CONST char *aptr) { +if (!sim_brk_types) + return sim_messagef (SCPE_NOFNC, "No breakpoint support in this simulator\n"); switch (flg) { case SSH_ST: @@ -8917,7 +8922,7 @@ return cnt; instruction breakpoint capability. Breakpoints are stored in table sim_brk_tab, which is ordered by address for - efficient binary searching. A breakpoint consists of a four entry structure: + efficient binary searching. A breakpoint consists of a six entry structure: addr address of the breakpoint type types of breakpoints set on the address @@ -8925,10 +8930,12 @@ return cnt; cnt number of iterations before breakp is taken action pointer command string to be executed when break is taken + next list of other breakpoints with the same addr specifier + time_fired array of when this breakpoint was fired for each class sim_brk_summ is a summary of the types of breakpoints that are currently set (it is the bitwise OR of all the type fields). A simulator need only check for - a breakpoint of type X if bit SWMASK('X') is set in sim_brk_sum. + a breakpoint of type X if bit SWMASK('X') is set in sim_brk_summ. The package contains the following public routines: @@ -8948,10 +8955,25 @@ return cnt; t_stat sim_brk_init (void) { +int32 i; + +for (i=0; inext; + + free (bp->act); + free (bp); + bp = bpt; + } + } +memset (sim_brk_tab, 0, sim_brk_lnt*sizeof (BRKTAB*)); sim_brk_lnt = SIM_BRK_INILNT; -sim_brk_tab = (BRKTAB *) calloc (sim_brk_lnt, sizeof (BRKTAB)); +sim_brk_tab = (BRKTAB **) realloc (sim_brk_tab, sim_brk_lnt*sizeof (BRKTAB*)); if (sim_brk_tab == NULL) return SCPE_MEM; +memset (sim_brk_tab, 0, sim_brk_lnt*sizeof (BRKTAB*)); sim_brk_ent = sim_brk_ins = 0; sim_brk_clract (); sim_brk_npc (0); @@ -8973,9 +8995,11 @@ lo = 0; /* initial bounds */ hi = sim_brk_ent - 1; do { p = (lo + hi) >> 1; /* probe */ - bp = sim_brk_tab + p; /* table addr */ - if (loc == bp->addr) /* match? */ + bp = sim_brk_tab[p]; /* table addr */ + if (loc == bp->addr) { /* match? */ + sim_brk_ins = p; return bp; + } else if (loc < bp->addr) /* go down? p is upper */ hi = p - 1; else lo = p + 1; /* go up? p is lower */ @@ -8986,37 +9010,56 @@ else sim_brk_ins = p + 1; /* after last sch */ return NULL; } +BRKTAB *sim_brk_fnd_ex (t_addr loc, uint32 btyp, t_bool any_typ) +{ +BRKTAB *bp = sim_brk_fnd (loc); + +while (bp) { + if (any_typ ? (bp->typ & btyp) : (bp->typ == btyp)) + return bp; + bp = bp->next; + } +return bp; +} + /* Insert a breakpoint */ -BRKTAB *sim_brk_new (t_addr loc) +BRKTAB *sim_brk_new (t_addr loc, uint32 btyp) { int32 i, t; -BRKTAB *bp, *newp; +BRKTAB *bp, **newp; if (sim_brk_ins < 0) return NULL; if (sim_brk_ent >= sim_brk_lnt) { /* out of space? */ t = sim_brk_lnt + SIM_BRK_INILNT; /* new size */ - newp = (BRKTAB *) calloc (t, sizeof (BRKTAB)); /* new table */ + newp = (BRKTAB **) calloc (t, sizeof (BRKTAB*)); /* new table */ if (newp == NULL) /* can't extend */ return NULL; - for (i = 0; i < sim_brk_lnt; i++) /* copy table */ - *(newp + i) = *(sim_brk_tab + i); + memcpy (newp, sim_brk_tab, sim_brk_lnt * sizeof (*sim_brk_tab));/* copy table */ + memset (newp + sim_brk_lnt, 0, SIM_BRK_INILNT * sizeof (*newp));/* zero new entries */ free (sim_brk_tab); /* free old table */ sim_brk_tab = newp; /* new base, lnt */ sim_brk_lnt = t; } -if (sim_brk_ins != sim_brk_ent) { /* move needed? */ - for (bp = sim_brk_tab + sim_brk_ent; - bp > sim_brk_tab + sim_brk_ins; bp--) - *bp = *(bp - 1); +if ((sim_brk_ins == sim_brk_ent) || + ((sim_brk_ins != sim_brk_ent) && + (sim_brk_tab[sim_brk_ins]->addr != loc))) { /* need to open a hole? */ + for (i = sim_brk_ent; i > sim_brk_ins; --i) + sim_brk_tab[i] = sim_brk_tab[i - 1]; + sim_brk_tab[sim_brk_ins] = NULL; } -bp = sim_brk_tab + sim_brk_ins; +bp = calloc (1, sizeof (*bp)); +bp->next = sim_brk_tab[sim_brk_ins]; +sim_brk_tab[sim_brk_ins] = bp; +if (bp->next == NULL) + sim_brk_ent += 1; bp->addr = loc; -bp->typ = 0; +bp->typ = btyp; bp->cnt = 0; bp->act = NULL; -sim_brk_ent = sim_brk_ent + 1; +for (i = 0; i < SIM_BKPT_N_SPC; i++) + bp->time_fired[i] = -1.0; return bp; } @@ -9035,12 +9078,17 @@ if (~sim_brk_types & sw) { } if ((sw & BRK_TYP_DYN_ALL) && act) /* can't specify an action with a dynamic breakpoint */ return SCPE_ARG; -bp = sim_brk_fnd (loc); /* present? */ +bp = sim_brk_fnd (loc); /* loc present? */ if (!bp) /* no, allocate */ - bp = sim_brk_new (loc); + bp = sim_brk_new (loc, sw); +else { + while (bp && (bp->typ != sw)) + bp = bp->next; + if (!bp) + bp = sim_brk_new (loc, sw); + } if (!bp) /* still no? mem err */ return SCPE_MEM; -bp->typ |= sw; /* set type */ bp->cnt = ncnt; /* set count */ if ((!(sw & BRK_TYP_DYN_ALL)) && /* Not Dynamic and */ (bp->act != NULL) && (act != NULL)) { /* replace old action? */ @@ -9054,7 +9102,7 @@ if ((act != NULL) && (*act != 0)) { /* new action? */ strncpy (newp, act, CBUFSIZE); /* copy action */ bp->act = newp; /* set pointer */ } -sim_brk_summ = sim_brk_summ | sw; +sim_brk_summ = sim_brk_summ | (sw & ~BRK_TYP_TEMP); return SCPE_OK; } @@ -9062,23 +9110,42 @@ return SCPE_OK; t_stat sim_brk_clr (t_addr loc, int32 sw) { -BRKTAB *bp = sim_brk_fnd (loc); +BRKTAB *bpl, *bp = sim_brk_fnd (loc); +int32 i; if (!bp) /* not there? ok */ return SCPE_OK; if (sw == 0) sw = SIM_BRK_ALLTYP; -bp->typ = bp->typ & ~sw; -if (bp->typ) /* clear all types? */ - return SCPE_OK; -if (bp->act != NULL) /* deallocate action */ - free (bp->act); -for ( ; bp < (sim_brk_tab + sim_brk_ent - 1); bp++) /* erase entry */ - *bp = *(bp + 1); -sim_brk_ent = sim_brk_ent - 1; /* decrement count */ + +while (bp) { + if (bp->typ == (bp->typ & sw)) { + free (bp->act); /* deallocate action */ + if (bp == sim_brk_tab[sim_brk_ins]) + bpl = sim_brk_tab[sim_brk_ins] = bp->next; + else + bpl->next = bp->next; + free (bp); + bp = bpl; + } + else { + bpl = bp; + bp = bp->next; + } + } +if (sim_brk_tab[sim_brk_ins] == NULL) { /* erased entry */ + sim_brk_ent = sim_brk_ent - 1; /* decrement count */ + for (i = sim_brk_ins; i < sim_brk_ent; i++) /* shuffle remaining entries */ + sim_brk_tab[i] = sim_brk_tab[i+1]; + } sim_brk_summ = 0; /* recalc summary */ -for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++) - sim_brk_summ = sim_brk_summ | bp->typ; +for (i = 0; i < sim_brk_ent; i++) { + bp = sim_brk_tab[i]; + while (bp) { + sim_brk_summ |= (bp->typ & ~BRK_TYP_TEMP); + bp = bp->next; + } + } return SCPE_OK; } @@ -9086,13 +9153,16 @@ return SCPE_OK; t_stat sim_brk_clrall (int32 sw) { -BRKTAB *bp; +int32 i; -if (sw == 0) sw = SIM_BRK_ALLTYP; -for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); ) { - if (bp->typ & sw) - sim_brk_clr (bp->addr, sw); - else bp++; +if (sw == 0) + sw = SIM_BRK_ALLTYP; +for (i = 0; i < sim_brk_ent;) { + t_addr loc = sim_brk_tab[i]->addr; + sim_brk_clr (loc, sw); + if ((i < sim_brk_ent) && + (loc == sim_brk_tab[i]->addr)) + ++i; } return SCPE_OK; } @@ -9101,7 +9171,7 @@ return SCPE_OK; t_stat sim_brk_show (FILE *st, t_addr loc, int32 sw) { -BRKTAB *bp = sim_brk_fnd (loc); +BRKTAB *bp = sim_brk_fnd_ex (loc, sw & (~SWMASK ('C')), FALSE); DEVICE *dptr; int32 i, any; @@ -9150,13 +9220,60 @@ return SCPE_OK; t_stat sim_brk_showall (FILE *st, int32 sw) { -BRKTAB *bp; +int32 bit, mask, types; +BRKTAB **bpt; if ((sw == 0) || (sw == SWMASK ('C'))) sw = SIM_BRK_ALLTYP | ((sw == SWMASK ('C')) ? SWMASK ('C') : 0); -for (bp = sim_brk_tab; bp < (sim_brk_tab + sim_brk_ent); bp++) { - if (bp->typ & sw) - sim_brk_show (st, bp->addr, sw); +for (types=bit=0; bit <= ('Z'-'A'); bit++) + if (sim_brk_types & (1 << bit)) + ++types; +if ((!(sw & SWMASK ('C'))) && sim_brk_types && (types > 1)) { + fprintf (st, "Supported Breakpoint Types:"); + for (bit=0; bit <= ('Z'-'A'); bit++) + if (sim_brk_types & (1 << bit)) + fprintf (st, " -%c", 'A' + bit); + fprintf (st, "\n"); + } +if (((sw & sim_brk_types) != sim_brk_types) && (types > 1)) { + mask = (sw & sim_brk_types); + fprintf (st, "Displaying Breakpoint Types:"); + for (bit=0; bit <= ('Z'-'A'); bit++) + if (mask & (1 << bit)) + fprintf (st, " -%c", 'A' + bit); + fprintf (st, "\n"); + } +for (bpt = sim_brk_tab; bpt < (sim_brk_tab + sim_brk_ent); bpt++) { + BRKTAB *prev = NULL; + BRKTAB *cur = *bpt; + BRKTAB *next; + /* First reverse the list */ + while (cur) { + next = cur->next; + cur->next = prev; + prev = cur; + cur = next; + } + /* save reversed list in the head pointer so lookups work */ + *bpt = prev; + /* Walk the reversed list and print it in the order it was defined in */ + cur = prev; + while (cur) { + if (cur->typ & sw) + sim_brk_show (st, cur->addr, cur->typ | ((sw & SWMASK ('C')) ? SWMASK ('C') : 0)); + cur = cur->next; + } + /* reversing the list again */ + cur = prev; + prev = NULL; + while (cur) { + next = cur->next; + cur->next = prev; + prev = cur; + cur = next; + } + /* restore original list */ + *bpt = prev; } return SCPE_OK; } @@ -9172,22 +9289,19 @@ uint32 res = 0; if (sim_brk_summ & BRK_TYP_DYN_ALL) btyp |= BRK_TYP_DYN_ALL; -if ((bp = sim_brk_fnd (loc)) && (btyp & bp->typ)) { /* in table, and type match? */ - if ((sim_brk_pend[spc] && (loc == sim_brk_ploc[spc])) || /* previous location? */ - (--bp->cnt > 0)) /* count > 0? */ +if ((bp = sim_brk_fnd_ex (loc, btyp, TRUE))) { /* in table, and type match? */ + if (bp->time_fired[spc] == sim_gtime()) /* already taken? */ + return 0; + bp->time_fired[spc] = sim_time; /* remember match time */ + if (--bp->cnt > 0) /* count > 0? */ return 0; bp->cnt = 0; /* reset count */ sim_brk_setact (bp->act); /* set up actions */ res = btyp & bp->typ; /* set return value */ if (bp->typ & BRK_TYP_TEMP) - sim_brk_clr (loc, btyp | BRK_TYP_TEMP); /* delete one-shot breakpoint */ - else { - sim_brk_ploc[spc] = loc; /* save location */ - sim_brk_pend[spc] = TRUE; /* don't do twice */ - } + sim_brk_clr (loc, bp->typ); /* delete one-shot breakpoint */ return res; } -sim_brk_pend[spc] = FALSE; return res; } @@ -9243,26 +9357,33 @@ else void sim_brk_npc (uint32 cnt) { -uint32 i; +uint32 spc; +BRKTAB **bpt, *bp; if ((cnt == 0) || (cnt > SIM_BKPT_N_SPC)) cnt = SIM_BKPT_N_SPC; -for (i = 0; i < cnt; i++) { - sim_brk_pend[i] = FALSE; - sim_brk_ploc[i] = 0; +for (bpt = sim_brk_tab; bpt < (sim_brk_tab + sim_brk_ent); bpt++) { + for (bp = *bpt; bp; bp = bp->next) { + for (spc = 0; spc < cnt; spc++) + bp->time_fired[spc] = -1.0; + } } -return; } /* Clear breakpoint space */ -void sim_brk_clrspc (uint32 spc) +void sim_brk_clrspc (uint32 spc, uint32 btyp) { +BRKTAB **bpt, *bp; + if (spc < SIM_BKPT_N_SPC) { - sim_brk_pend[spc] = FALSE; - sim_brk_ploc[spc] = 0; + for (bpt = sim_brk_tab; bpt < (sim_brk_tab + sim_brk_ent); bpt++) { + for (bp = *bpt; bp; bp = bp->next) { + if (bp->typ & btyp) + bp->time_fired[spc] = -1.0; + } + } } -return; } /* Expect package. This code provides a mechanism to stop and control simulator diff --git a/scp.h b/scp.h index 5bd9e930..5d8e5379 100644 --- a/scp.h +++ b/scp.h @@ -183,9 +183,8 @@ SHTAB *find_shtab (SHTAB *tab, const char *gbuf); t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr); BRKTAB *sim_brk_fnd (t_addr loc); uint32 sim_brk_test (t_addr bloc, uint32 btyp); -void sim_brk_clrspc (uint32 spc); +void sim_brk_clrspc (uint32 spc, uint32 btyp); void sim_brk_npc (uint32 cnt); -char *sim_brk_clract (void); void sim_brk_setact (const char *action); t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 after, uint32 delay); t_stat sim_show_send_input (FILE *st, const SEND *snd); @@ -273,8 +272,6 @@ extern volatile int32 stop_cpu; extern uint32 sim_brk_types; /* breakpoint info */ extern uint32 sim_brk_dflt; extern uint32 sim_brk_summ; -extern t_bool sim_brk_pend[SIM_BKPT_N_SPC]; -extern t_addr sim_brk_ploc[SIM_BKPT_N_SPC]; extern FILE *stdnul; extern t_bool sim_asynch_enabled; diff --git a/sim_defs.h b/sim_defs.h index d96aef86..5cc4b22a 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -714,6 +714,7 @@ struct SCHTAB { struct BRKTAB { t_addr addr; /* address */ uint32 typ; /* mask of types */ +#define BRK_TYP_USR_TYPES ((1 << ('Z'-'A'+1)) - 1)/* all types A-Z */ #define BRK_TYP_DYN_STEPOVER (SWMASK ('Z'+1)) #define BRK_TYP_DYN_USR (SWMASK ('Z'+2)) #define BRK_TYP_DYN_ALL (BRK_TYP_DYN_USR|BRK_TYP_DYN_STEPOVER) /* Mask of All Dynamic types */ @@ -721,6 +722,8 @@ struct BRKTAB { #define BRK_TYP_MAX (('Z'-'A')+3) /* Maximum breakpoint type */ int32 cnt; /* proceed count */ char *act; /* action string */ + double time_fired[SIM_BKPT_N_SPC]; /* instruction count when match occurred */ + BRKTAB *next; /* list with same address value */ }; /* Expect rule */