/* * cond_doit: whether do (mov or jmp) it? * args * PACK_CC: the current condition codes * cond: conditions (C_YES, C_LE, C_L, C_E, C_NE, C_GE, C_G) * * return * TRUE: do it * FALSE: not do it */ bool_t cond_doit(cc_t cc, cond_t cond) { bool_t doit = FALSE; switch(cond){ case C_YES: doit = TRUE; break; case C_LE: doit = ((GET_SF(cc) ^ GET_OF(cc)) | GET_ZF(cc)); break; case C_L: doit = (GET_SF(cc) ^ GET_OF(cc)); break; case C_E: doit = (GET_ZF(cc)); break; case C_NE: doit = (!GET_ZF(cc)); break; case C_GE: doit = !(GET_SF(cc) ^ GET_OF(cc)); break; case C_G: doit = !(GET_SF(cc) ^ GET_OF(cc)) & !GET_ZF(cc); break; } return doit; }
/* Branch logic */ bool_t take_branch(cc_t cc, jump_t bcond) { bool_t zf = GET_ZF(cc); bool_t sf = GET_SF(cc); bool_t of = GET_OF(cc); bool_t jump = FALSE; switch(bcond) { case J_YES: jump = TRUE; break; case J_LE: jump = (sf^of)|zf; break; case J_L: jump = sf^of; break; case J_E: jump = zf; break; case J_NE: jump = zf^1; break; case J_GE: jump = sf^of^1; break; case J_G: jump = (sf^of^1)&(zf^1); break; default: jump = FALSE; break; } return jump; }
/* Branch logic */ bool_t cond_holds(cc_t cc, cond_t bcond) { bool_t zf = GET_ZF(cc); bool_t sf = GET_SF(cc); bool_t of = GET_OF(cc); bool_t jump = FALSE; switch(bcond) { case C_YES: jump = TRUE; break; case C_LE: jump = (sf^of)|zf; break; case C_L: jump = sf^of; break; case C_E: jump = zf; break; case C_NE: jump = zf^1; break; case C_GE: jump = sf^of^1; break; case C_G: jump = (sf^of^1)&(zf^1); break; default: jump = FALSE; break; } return jump; }
/* Provide mechanism for simulator to update condition code display */ void show_cc(cc_t cc) { int code; sprintf(tcl_msg, "setCC %d %d %d", GET_ZF(cc), GET_SF(cc), GET_OF(cc)); code = Tcl_Eval(sim_interp, tcl_msg); if (code != TCL_OK) { fprintf(stderr, "Failed to display condition codes\n"); fprintf(stderr, "Error Message was '%s'\n", sim_interp->result); } }
/* * cond_doit: whether do (mov or jmp) it? * args * PACK_CC: the current condition codes * cond: conditions (C_YES, C_LE, C_L, C_E, C_NE, C_GE, C_G) * * return * TRUE: do it * FALSE: not do it */ bool_t cond_doit(cc_t cc, cond_t cond) { bool_t doit; bool_t ZF = GET_ZF(cc), SF = GET_SF(cc), OF = GET_OF(cc); switch (cond) { case C_YES: return TRUE; case C_LE: return (SF^OF)|ZF; case C_L: return SF^OF; case C_E: return ZF; case C_NE: return !ZF; case C_GE: return !(SF^OF); case C_G: return !(SF^OF)&!ZF; default: return FALSE; } }
/* * cond_doit: whether do (mov or jmp) it? * args * PACK_CC: the current condition codes * cond: conditions (C_YES, C_LE, C_L, C_E, C_NE, C_GE, C_G) * * return * TRUE: do it * FALSE: not do it */ bool_t cond_doit(cc_t cc, cond_t cond) { bool_t doit = FALSE; bool_t zero = GET_ZF(cc); bool_t sign = GET_SF(cc); bool_t ovf = GET_OF(cc); switch (cond) { case C_YES: doit = TRUE; break; case C_LE: if (((sign^ovf)|zero)&0x1) doit = TRUE; break; case C_L: if ((sign^ovf)&0x1) doit = TRUE; break; case C_E: if ((zero)&0x1) doit = TRUE; break; case C_NE: if ((!zero)&0x1) doit = TRUE; break; case C_GE: if ((~(sign^ovf))&0x1) doit = TRUE; break; case C_G: if (((~(sign^ovf))&(~zero))&0x1) doit = TRUE; break; default: break; } return doit; }
t_stat rp_go (int32 drv) { int32 dc, fnc, dtype, t; UNIT *uptr; fnc = GET_FNC (rpcs1[drv]); /* get function */ if (DEBUG_PRS (rp_dev)) fprintf (sim_deb, ">>RP%d STRT: fnc=%s, ds=%o, cyl=%o, da=%o, er=%o\n", drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]); uptr = rp_dev.units + drv; /* get unit */ rp_clr_as (AS_U0 << drv); /* clear attention */ dtype = GET_DTYPE (uptr->flags); /* get drive type */ dc = rpdc[drv]; /* assume seek, sch */ if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */ rp_set_er (ER1_ILF, drv); /* not allowed */ rp_update_ds (DS_ATA, drv); /* set attention */ return MBE_GOE; } switch (fnc) { /* case on function */ case FNC_DCLR: /* drive clear */ rper1[drv] = rper2[drv] = rper3[drv] = 0; /* clear errors */ rpec2[drv] = 0; /* clear EC2 */ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? */ rpmr[drv] = 0; /* clear maint */ else rpec1[drv] = 0; /* RP, clear EC1 */ case FNC_NOP: /* no operation */ case FNC_RELEASE: /* port release */ return SCPE_OK; case FNC_PRESET: /* read-in preset */ rpdc[drv] = 0; /* clear disk addr */ rpda[drv] = 0; rpof[drv] = 0; /* clear offset */ case FNC_PACK: /* pack acknowledge */ rpds[drv] = rpds[drv] | DS_VV; /* set volume valid */ return SCPE_OK; case FNC_OFFSET: /* offset mode */ case FNC_RETURN: if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rp_set_er (ER1_UNS, drv); /* unsafe */ break; } rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */ sim_activate (uptr, rp_swait); /* time operation */ return SCPE_OK; case FNC_UNLOAD: /* unload */ if (drv_tab[dtype].ctrl == RM_CTRL) { /* RM? */ rp_set_er (ER1_ILF, drv); /* not supported */ break; } rp_detach (uptr); /* detach unit */ return SCPE_OK; case FNC_RECAL: /* recalibrate */ dc = 0; /* seek to 0 */ case FNC_SEEK: /* seek */ case FNC_SEARCH: /* search */ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rp_set_er (ER1_UNS, drv); /* unsafe */ break; } if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */ (GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */ (GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */ rp_set_er (ER1_IAE, drv); break; } rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */ t = abs (dc - uptr->CYL); /* cyl diff */ if (t == 0) /* min time */ t = 1; sim_activate (uptr, rp_swait * t); /* schedule */ uptr->CYL = dc; /* save cylinder */ return SCPE_OK; case FNC_WRITEH: /* write headers */ case FNC_WRITE: /* write */ case FNC_WCHK: /* write check */ case FNC_READ: /* read */ case FNC_READH: /* read headers */ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rp_set_er (ER1_UNS, drv); /* unsafe */ break; } if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */ (GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */ (GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */ rp_set_er (ER1_IAE, drv); break; } rpds[drv] = rpds[drv] & ~DS_RDY; /* clear drive rdy */ sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr->CYL))); uptr->CYL = dc; /* save cylinder */ return SCPE_OK; default: /* all others */ rp_set_er (ER1_ILF, drv); /* not supported */ break; } rp_update_ds (DS_ATA, drv); /* set attn, req int */ return MBE_GOE; }