static struct videomode * edid_search_mode(struct edid_info *edid, const struct videomode *mode) { int refresh, i; refresh = DIVIDE(DIVIDE(mode->dot_clock * 1000, mode->htotal), mode->vtotal); for (i = 0; i < edid->edid_nmodes; i++) { if (mode->hdisplay == edid->edid_modes[i].hdisplay && mode->vdisplay == edid->edid_modes[i].vdisplay && refresh == DIVIDE(DIVIDE( edid->edid_modes[i].dot_clock * 1000, edid->edid_modes[i].htotal), edid->edid_modes[i].vtotal)) { return &edid->edid_modes[i]; } } return NULL; }
void calculate( void ) { int j; N4 = N + 4; for (j = 0; j < 10*5; ++j) { memdiv5[j][0] = j/5; memdiv5[j][1] = 10*(j - memdiv5[j][0]*5); } for (j = 0; j < 10*25; ++j) { memdiv25[j][0] = j/25; memdiv25[j][1] = 10*(j - memdiv25[j][0]*25); } for (j = 0; j < 10*239; ++j) { memdiv239[j][0] = j/239; memdiv239[j][1] = 10*(j - memdiv239[j][0]*239); } SET( a, 0 ); SET( b, 0 ); for( j = 2 * N4 + 1; j >= 3; j -= 2 ) { SET( c, 1 ); DIVIDE( c, j ); SUBTRACT( a, c, a ); DIVIDE25( a ); SUBTRACT( b, c, b ); DIVIDE239( b ); DIVIDE239( b ); progress(); } SET( c, 1 ); SUBTRACT( a, c, a ); DIVIDE5( a ); SUBTRACT( b, c, b ); DIVIDE239( b ); MULTIPLY( a, 4 ); SUBTRACT( a, a, b ); MULTIPLY( a, 4 ); progress(); }
void vacfunc(real_T *dx, real_T *xms, SimStruct *S) { real_T mvs[NM], x[NS]; #ifdef DEBUG debug("vacfunc entered.\n"); #endif // #ifdef DEBUG // debug("Time:%f (in minutes: %f) entered.\n",GETTIME(S), GETTIME(S)*60); // #endif GETXMV(XMV,S); GETIDV(IDV,S); VAModel(dx, x, mvs, xms, STS(S), XMV, GETTIME(S)*60, 0, IDV); #if defined(CONTINUOUS_STATES) MULTIPLY(dx, NS, 60); #elif defined(DISCRETE_STATES) DIVIDE(dx, NS, 180); #endif #ifdef DEBUG debug("vacfunc left.\n"); #endif }
void calculate( void ) { int j; N4 = N + 4; SET( a, 0 ); SET( b, 0 ); for( j = 2 * N4 + 1; j >= 3; j -= 2 ) { SET( c, 1 ); DIVIDE( c, j ); SUBTRACT( a, c, a ); DIVIDE25(a);//DIVIDE( a, 25 ); SUBTRACT( b, c, b ); DIVIDE239(b);//DIVIDE( b, 239 ); DIVIDE239(b);//DIVIDE( b, 239 ); progress(); } SET( c, 1 ); SUBTRACT( a, c, a ); DIVIDE5(a); //DIVIDE( a, 5 ); SUBTRACT( b, c, b ); DIVIDE239(b);//DIVIDE( b, 239 ); MULTIPLY( a, 4 ); SUBTRACT( a, a, b ); MULTIPLY( a, 4 ); progress(); }
/* Process 4OP Integer instructions */ bool eval_4OP_Int(struct lilith* vm, struct Instruction* c) { #ifdef DEBUG char Name[20] = "ILLEGAL_4OP"; #endif switch(c->raw_XOP) { case 0x00: /* ADD.CI */ { #ifdef DEBUG strncpy(Name, "ADD.CI", 19); #elif TRACE record_trace("ADD.CI"); #endif ADD_CI(vm, c); break; } case 0x01: /* ADD.CO */ { #ifdef DEBUG strncpy(Name, "ADD.CO", 19); #elif TRACE record_trace("ADD.CO"); #endif ADD_CO(vm, c); break; } case 0x02: /* ADD.CIO */ { #ifdef DEBUG strncpy(Name, "ADD.CIO", 19); #elif TRACE record_trace("ADD.CIO"); #endif ADD_CIO(vm, c); break; } case 0x03: /* ADDU.CI */ { #ifdef DEBUG strncpy(Name, "ADDU.CI", 19); #elif TRACE record_trace("ADDU.CI"); #endif ADDU_CI(vm, c); break; } case 0x04: /* ADDU.CO */ { #ifdef DEBUG strncpy(Name, "ADDU.CO", 19); #elif TRACE record_trace("ADDU.CO"); #endif ADDU_CO(vm, c); break; } case 0x05: /* ADDU.CIO */ { #ifdef DEBUG strncpy(Name, "ADDU.CIO", 19); #elif TRACE record_trace("ADDU.CIO"); #endif ADDU_CIO(vm, c); break; } case 0x06: /* SUB.BI */ { #ifdef DEBUG strncpy(Name, "SUB.BI", 19); #elif TRACE record_trace("SUB.BI"); #endif SUB_BI(vm, c); break; } case 0x07: /* SUB.BO */ { #ifdef DEBUG strncpy(Name, "SUB.BO", 19); #elif TRACE record_trace("SUB.BO"); #endif SUB_BO(vm, c); break; } case 0x08: /* SUB.BIO */ { #ifdef DEBUG strncpy(Name, "SUB.BIO", 19); #elif TRACE record_trace("SUB.BIO"); #endif SUB_BIO(vm, c); break; } case 0x09: /* SUBU.BI */ { #ifdef DEBUG strncpy(Name, "SUBU.BI", 19); #elif TRACE record_trace("SUBU.BI"); #endif SUBU_BI(vm, c); break; } case 0x0A: /* SUBU.BO */ { #ifdef DEBUG strncpy(Name, "SUBU.BO", 19); #elif TRACE record_trace("SUBU.BO"); #endif SUBU_BO(vm, c); break; } case 0x0B: /* SUBU.BIO */ { #ifdef DEBUG strncpy(Name, "SUBU.BIO", 19); #elif TRACE record_trace("SUBU.BIO"); #endif SUBU_BIO(vm, c); break; } case 0x0C: /* MULTIPLY */ { #ifdef DEBUG strncpy(Name, "MULTIPLY", 19); #elif TRACE record_trace("MULTIPLY"); #endif MULTIPLY(vm, c); break; } case 0x0D: /* MULTIPLYU */ { #ifdef DEBUG strncpy(Name, "MULTIPLYU", 19); #elif TRACE record_trace("MULTIPLYU"); #endif MULTIPLYU(vm, c); break; } case 0x0E: /* DIVIDE */ { #ifdef DEBUG strncpy(Name, "DIVIDE", 19); #elif TRACE record_trace("DIVIDE"); #endif DIVIDE(vm, c); break; } case 0x0F: /* DIVIDEU */ { #ifdef DEBUG strncpy(Name, "DIVIDEU", 19); #elif TRACE record_trace("DIVIDEU"); #endif DIVIDEU(vm, c); break; } case 0x10: /* MUX */ { #ifdef DEBUG strncpy(Name, "MUX", 19); #elif TRACE record_trace("MUX"); #endif MUX(vm, c); break; } case 0x11: /* NMUX */ { #ifdef DEBUG strncpy(Name, "NMUX", 19); #elif TRACE record_trace("NMUX"); #endif NMUX(vm, c); break; } case 0x12: /* SORT */ { #ifdef DEBUG strncpy(Name, "SORT", 19); #elif TRACE record_trace("SORT"); #endif SORT(vm, c); break; } case 0x13: /* SORTU */ { #ifdef DEBUG strncpy(Name, "SORTU", 19); #elif TRACE record_trace("SORTU"); #endif SORTU(vm, c); break; } default: { illegal_instruction(vm, c); break; } } #ifdef DEBUG fprintf(stdout, "# %s reg%u reg%u reg%u reg%u\n", Name, c->reg0, c->reg1, c->reg2, c->reg3); #endif return false; }
void mpz_bin_ui (mpz_ptr r, mpz_srcptr n, unsigned long int k) { mpz_t ni; mp_limb_t i; mpz_t nacc; mp_limb_t kacc; mp_size_t negate; if (mpz_sgn (n) < 0) { /* bin(n,k) = (-1)^k * bin(-n+k-1,k), and set ni = -n+k-1 - k = -n-1 */ mpz_init (ni); mpz_neg (ni, n); mpz_sub_ui (ni, ni, 1L); negate = (k & 1); /* (-1)^k */ } else { /* bin(n,k) == 0 if k>n (no test for this under the n<0 case, since -n+k-1 >= k there) */ if (mpz_cmp_ui (n, k) < 0) { mpz_set_ui (r, 0L); return; } /* set ni = n-k */ mpz_init (ni); mpz_sub_ui (ni, n, k); negate = 0; } /* Now wanting bin(ni+k,k), with ni positive, and "negate" is the sign (0 for positive, 1 for negative). */ mpz_set_ui (r, 1L); /* Rewrite bin(n,k) as bin(n,n-k) if that is smaller. In this case it's whether ni+k-k < k meaning ni<k, and if so change to denominator ni+k-k = ni, and new ni of ni+k-ni = k. */ if (mpz_cmp_ui (ni, k) < 0) { unsigned long tmp; tmp = k; k = mpz_get_ui (ni); mpz_set_ui (ni, tmp); } kacc = 1; mpz_init_set_ui (nacc, 1L); for (i = 1; i <= k; i++) { mp_limb_t k1, k0; #if 0 mp_limb_t nacclow; int c; nacclow = PTR(nacc)[0]; for (c = 0; (((kacc | nacclow) & 1) == 0); c++) { kacc >>= 1; nacclow >>= 1; } mpz_div_2exp (nacc, nacc, c); #endif mpz_add_ui (ni, ni, 1L); mpz_mul (nacc, nacc, ni); umul_ppmm (k1, k0, kacc, i << GMP_NAIL_BITS); k0 >>= GMP_NAIL_BITS; if (k1 != 0) { /* Accumulator overflow. Perform bignum step. */ mpz_mul (r, r, nacc); mpz_set_ui (nacc, 1L); DIVIDE (); kacc = i; } else { /* Save new products in accumulators to keep accumulating. */ kacc = k0; } } mpz_mul (r, r, nacc); DIVIDE (); SIZ(r) = (SIZ(r) ^ -negate) + negate; mpz_clear (nacc); mpz_clear (ni); }
void sort_modes(struct videomode *modes, struct videomode **preferred, int nmodes) { int aspect, refresh, hbest, vbest, abest, atemp, rbest, rtemp; int i, j; struct videomode *mtemp = NULL; if (nmodes < 2) return; if (*preferred != NULL) { /* Put the preferred mode first in the list */ aspect = (*preferred)->hdisplay * 100 / (*preferred)->vdisplay; refresh = DIVIDE(DIVIDE((*preferred)->dot_clock * 1000, (*preferred)->htotal), (*preferred)->vtotal); if (*preferred != modes) { swap_modes(*preferred, modes); *preferred = modes; } } else { /* * Find the largest horizontal and vertical mode and put that * first in the list. Preferred refresh rate is taken from * the first mode of this size. */ hbest = 0; vbest = 0; for (i = 0; i < nmodes; i++) { if (modes[i].hdisplay > hbest) { hbest = modes[i].hdisplay; vbest = modes[i].vdisplay; mtemp = &modes[i]; } else if (modes[i].hdisplay == hbest && modes[i].vdisplay > vbest) { vbest = modes[i].vdisplay; mtemp = &modes[i]; } } aspect = mtemp->hdisplay * 100 / mtemp->vdisplay; refresh = DIVIDE(DIVIDE(mtemp->dot_clock * 1000, mtemp->htotal), mtemp->vtotal); if (mtemp != modes) swap_modes(mtemp, modes); } /* Sort other modes by refresh rate, aspect ratio, then resolution */ for (j = 1; j < nmodes - 1; j++) { rbest = 1000; abest = 1000; hbest = 0; vbest = 0; for (i = j; i < nmodes; i++) { rtemp = abs(refresh - DIVIDE(DIVIDE(modes[i].dot_clock * 1000, modes[i].htotal), modes[i].vtotal)); atemp = (modes[i].hdisplay * 100 / modes[i].vdisplay); if (rtemp < rbest) { rbest = rtemp; mtemp = &modes[i]; } if (rtemp == rbest) { /* Treat "close" aspect ratios as identical */ if (abs(abest - atemp) > (abest / 8) && abs(aspect - atemp) < abs(aspect - abest)) { abest = atemp; mtemp = &modes[i]; } if (atemp == abest || abs(abest - atemp) <= (abest / 8)) { if (modes[i].hdisplay > hbest) { hbest = modes[i].hdisplay; mtemp = &modes[i]; } if (modes[i].hdisplay == hbest && modes[i].vdisplay > vbest) { vbest = modes[i].vdisplay; mtemp = &modes[i]; } } } } if (mtemp != &modes[j]) swap_modes(mtemp, &modes[j]); } }
void awin_tcon1_set_videomode(int unit, const struct videomode *mode) { struct awin_tcon_softc *sc; device_t dev; uint32_t val; dev = device_find_by_driver_unit("awintcon", unit); if (dev == NULL) { printf("TCON%d: no driver found\n", unit); return; } sc = device_private(dev); KASSERT((sc->sc_output_type == OUTPUT_HDMI) || (sc->sc_output_type == OUTPUT_VGA)); awin_debe_set_videomode(device_unit(sc->sc_dev), mode); if (mode) { const u_int interlace_p = !!(mode->flags & VID_INTERLACE); const u_int phsync_p = !!(mode->flags & VID_PHSYNC); const u_int pvsync_p = !!(mode->flags & VID_PVSYNC); const u_int hspw = mode->hsync_end - mode->hsync_start; const u_int hbp = mode->htotal - mode->hsync_start; const u_int vspw = mode->vsync_end - mode->vsync_start; const u_int vbp = mode->vtotal - mode->vsync_start; const u_int vblank_len = ((mode->vtotal << interlace_p) >> 1) - mode->vdisplay - 2; const u_int start_delay = vblank_len >= 32 ? 30 : vblank_len - 2; val = TCON_READ(sc, AWIN_TCON_GCTL_REG); val |= AWIN_TCON_GCTL_IO_MAP_SEL; TCON_WRITE(sc, AWIN_TCON_GCTL_REG, val); /* enable */ val = AWIN_TCONx_CTL_EN; if (interlace_p) val |= AWIN_TCONx_CTL_INTERLACE_EN; val |= __SHIFTIN(start_delay, AWIN_TCONx_CTL_START_DELAY); #ifdef AWIN_TCON1_BLUEDATA val |= __SHIFTIN(AWIN_TCONx_CTL_SRC_SEL_BLUEDATA, AWIN_TCONx_CTL_SRC_SEL); #else /* * the DE selector selects the primary DEBE for this tcon: * 0 selects debe0 for tcon0 and debe1 for tcon1 */ val |= __SHIFTIN(AWIN_TCONx_CTL_SRC_SEL_DE0, AWIN_TCONx_CTL_SRC_SEL); #endif TCON_WRITE(sc, AWIN_TCON1_CTL_REG, val); /* Source width/height */ TCON_WRITE(sc, AWIN_TCON1_BASIC0_REG, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); /* Scaler width/height */ TCON_WRITE(sc, AWIN_TCON1_BASIC1_REG, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); /* Output width/height */ TCON_WRITE(sc, AWIN_TCON1_BASIC2_REG, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); /* Horizontal total + back porch */ TCON_WRITE(sc, AWIN_TCON1_BASIC3_REG, ((mode->htotal - 1) << 16) | (hbp - 1)); /* Vertical total + back porch */ u_int vtotal = mode->vtotal * 2; if (interlace_p) { u_int framerate = DIVIDE(DIVIDE(mode->dot_clock * 1000, mode->htotal), mode->vtotal); u_int clk = mode->htotal * (mode->vtotal * 2 + 1) * framerate; if ((clk / 2) == mode->dot_clock * 1000) vtotal += 1; } TCON_WRITE(sc, AWIN_TCON1_BASIC4_REG, (vtotal << 16) | (vbp - 1)); /* Sync */ TCON_WRITE(sc, AWIN_TCON1_BASIC5_REG, ((hspw - 1) << 16) | (vspw - 1)); /* Polarity */ val = AWIN_TCON_IO_POL_IO2_INV; if (phsync_p) val |= AWIN_TCON_IO_POL_PHSYNC; if (pvsync_p) val |= AWIN_TCON_IO_POL_PVSYNC; TCON_WRITE(sc, AWIN_TCON1_IO_POL_REG, val); TCON_WRITE(sc, AWIN_TCON_GINT1_REG, __SHIFTIN(start_delay + 2, AWIN_TCON_GINT1_TCON1_LINENO)); /* Setup LCDx CH1 PLL */ awin_tcon_set_pll(sc, mode->dot_clock, 1); } else {
void edid_print(struct edid_info *edid) { int i; if (edid == NULL) return; printf("Vendor: [%s] %s\n", edid->edid_vendor, edid->edid_vendorname); printf("Product: [%04X] %s\n", edid->edid_product, edid->edid_productname); printf("Serial number: %s\n", edid->edid_serial); printf("Manufactured %d Week %d\n", edid->edid_year, edid->edid_week); printf("EDID Version %d.%d\n", edid->edid_version, edid->edid_revision); printf("EDID Comment: %s\n", edid->edid_comment); printf("Video Input: %x\n", edid->edid_video_input); if (edid->edid_video_input & EDID_VIDEO_INPUT_DIGITAL) { printf("\tDigital"); if (edid->edid_video_input & EDID_VIDEO_INPUT_DFP1_COMPAT) printf(" (DFP 1.x compatible)"); printf("\n"); } else { printf("\tAnalog\n"); switch (EDID_VIDEO_INPUT_LEVEL(edid->edid_video_input)) { case 0: printf("\t-0.7, 0.3V\n"); break; case 1: printf("\t-0.714, 0.286V\n"); break; case 2: printf("\t-1.0, 0.4V\n"); break; case 3: printf("\t-0.7, 0.0V\n"); break; } if (edid->edid_video_input & EDID_VIDEO_INPUT_BLANK_TO_BLACK) printf("\tBlank-to-black setup\n"); if (edid->edid_video_input & EDID_VIDEO_INPUT_SEPARATE_SYNCS) printf("\tSeperate syncs\n"); if (edid->edid_video_input & EDID_VIDEO_INPUT_COMPOSITE_SYNC) printf("\tComposite sync\n"); if (edid->edid_video_input & EDID_VIDEO_INPUT_SYNC_ON_GRN) printf("\tSync on green\n"); if (edid->edid_video_input & EDID_VIDEO_INPUT_SERRATION) printf("\tSerration vsync\n"); } printf("Gamma: %d.%02d\n", edid->edid_gamma / 100, edid->edid_gamma % 100); printf("Max Size: %d cm x %d cm\n", edid->edid_max_hsize, edid->edid_max_vsize); printf("Features: %x\n", edid->edid_features); if (edid->edid_features & EDID_FEATURES_STANDBY) printf("\tDPMS standby\n"); if (edid->edid_features & EDID_FEATURES_SUSPEND) printf("\tDPMS suspend\n"); if (edid->edid_features & EDID_FEATURES_ACTIVE_OFF) printf("\tDPMS active-off\n"); switch (EDID_FEATURES_DISP_TYPE(edid->edid_features)) { case EDID_FEATURES_DISP_TYPE_MONO: printf("\tMonochrome\n"); break; case EDID_FEATURES_DISP_TYPE_RGB: printf("\tRGB\n"); break; case EDID_FEATURES_DISP_TYPE_NON_RGB: printf("\tMulticolor\n"); break; case EDID_FEATURES_DISP_TYPE_UNDEFINED: printf("\tUndefined monitor type\n"); break; } if (edid->edid_features & EDID_FEATURES_STD_COLOR) printf("\tStandard color space\n"); if (edid->edid_features & EDID_FEATURES_PREFERRED_TIMING) printf("\tPreferred timing\n"); if (edid->edid_features & EDID_FEATURES_DEFAULT_GTF) printf("\tDefault GTF supported\n"); printf("Chroma Info:\n"); printf("\tRed X: 0.%03d\n", edid->edid_chroma.ec_redx); printf("\tRed Y: 0.%03d\n", edid->edid_chroma.ec_redy); printf("\tGrn X: 0.%03d\n", edid->edid_chroma.ec_greenx); printf("\tGrn Y: 0.%03d\n", edid->edid_chroma.ec_greeny); printf("\tBlu X: 0.%03d\n", edid->edid_chroma.ec_bluex); printf("\tBlu Y: 0.%03d\n", edid->edid_chroma.ec_bluey); printf("\tWht X: 0.%03d\n", edid->edid_chroma.ec_whitex); printf("\tWht Y: 0.%03d\n", edid->edid_chroma.ec_whitey); if (edid->edid_have_range) { printf("Range:\n"); printf("\tHorizontal: %d - %d kHz\n", edid->edid_range.er_min_hfreq, edid->edid_range.er_max_hfreq); printf("\tVertical: %d - %d Hz\n", edid->edid_range.er_min_vfreq, edid->edid_range.er_max_vfreq); printf("\tMax Dot Clock: %d MHz\n", edid->edid_range.er_max_clock); if (edid->edid_range.er_have_gtf2) { printf("\tGTF2 hfreq: %d\n", edid->edid_range.er_gtf2_hfreq); printf("\tGTF2 C: %d\n", edid->edid_range.er_gtf2_c); printf("\tGTF2 M: %d\n", edid->edid_range.er_gtf2_m); printf("\tGTF2 J: %d\n", edid->edid_range.er_gtf2_j); printf("\tGTF2 K: %d\n", edid->edid_range.er_gtf2_k); } } printf("Video modes:\n"); for (i = 0; i < edid->edid_nmodes; i++) { printf("\t%dx%d @ %dHz", edid->edid_modes[i].hdisplay, edid->edid_modes[i].vdisplay, DIVIDE(DIVIDE(edid->edid_modes[i].dot_clock * 1000, edid->edid_modes[i].htotal), edid->edid_modes[i].vtotal)); printf(" (%d %d %d %d %d %d %d", edid->edid_modes[i].dot_clock, edid->edid_modes[i].hsync_start, edid->edid_modes[i].hsync_end, edid->edid_modes[i].htotal, edid->edid_modes[i].vsync_start, edid->edid_modes[i].vsync_end, edid->edid_modes[i].vtotal); printf(" %s%sH %s%sV)\n", edid->edid_modes[i].flags & VID_PHSYNC ? "+" : "", edid->edid_modes[i].flags & VID_NHSYNC ? "-" : "", edid->edid_modes[i].flags & VID_PVSYNC ? "+" : "", edid->edid_modes[i].flags & VID_NVSYNC ? "-" : ""); } if (edid->edid_preferred_mode) printf("Preferred mode: %dx%d @ %dHz\n", edid->edid_preferred_mode->hdisplay, edid->edid_preferred_mode->vdisplay, DIVIDE(DIVIDE(edid->edid_preferred_mode->dot_clock * 1000, edid->edid_preferred_mode->htotal), edid->edid_preferred_mode->vtotal)); }
X_X_PROTO(F_ENTRY_NAME, packed_result, packed_argument) { WORD fp_class; UX_SIGN_TYPE sign; UX_EXPONENT_TYPE exponent; UX_FRACTION_DIGIT_TYPE f_hi; UX_FLOAT unpacked_argument, unpacked_result, tmp; EXCEPTION_INFO_DECL DECLARE_X_FLOAT(packed_result) INIT_EXCEPTION_INFO; fp_class = UNPACK( PASS_ARG_X_FLOAT(packed_argument), & unpacked_argument, ASINH_CLASS_TO_ACTION_MAP, PASS_RET_X_FLOAT(packed_result) OPT_EXCEPTION_INFO); if (0 >= fp_class) RETURN_X_FLOAT(packed_result); /* Get |x| */ sign = G_UX_SIGN(&unpacked_argument); P_UX_SIGN(&unpacked_argument, 0); /* Compute sqrt(x^2+1) */ SQUARE(&unpacked_argument, &tmp); ADDSUB(&tmp, UX_ONE, ADD, &tmp); NORMALIZE(&tmp); UX_SQRT(&tmp, &tmp); /* Check for small arguments */ exponent = G_UX_EXPONENT(&unpacked_argument); f_hi = G_UX_MSD(&unpacked_argument); if ((exponent < -1) || ((exponent == -1) && (f_hi <= SQRT_2_OV_4))) { /* Argument is small, evaluate directly */ ADDSUB(&tmp, UX_ONE, ADD, &tmp); DIVIDE(&unpacked_argument, &tmp, FULL_PRECISION, &tmp); UX_LOG_POLY(&tmp, &unpacked_result); } else { /* Argument is not small, use log function */ ADDSUB(&tmp, &unpacked_argument, ADD, &tmp); NORMALIZE(&tmp); UX_LOG( &tmp, UX_LN2, &unpacked_result); } /* Set sign of result and pack */ P_UX_SIGN(&unpacked_result, sign); PACK( &unpacked_result, PASS_RET_X_FLOAT(packed_result), NOT_USED, NOT_USED OPT_EXCEPTION_INFO); RETURN_X_FLOAT(packed_result); }
X_X_PROTO(F_ENTRY_NAME, packed_result, packed_argument) { WORD fp_class, underflow_error; UX_SIGN_TYPE sign; UX_EXPONENT_TYPE exponent; UX_FRACTION_DIGIT_TYPE f_hi; UX_FLOAT * unpacked_argument, * unpacked_result, tmp[3]; EXCEPTION_INFO_DECL DECLARE_X_FLOAT(packed_result) unpacked_argument = &tmp[2]; unpacked_result = &tmp[0]; INIT_EXCEPTION_INFO; fp_class = UNPACK( PASS_ARG_X_FLOAT(packed_argument), unpacked_argument, ATANH_CLASS_TO_ACTION_MAP, PASS_RET_X_FLOAT(packed_result) OPT_EXCEPTION_INFO); if (0 > fp_class) RETURN_X_FLOAT(packed_result); /* Get |x| */ sign = G_UX_SIGN(unpacked_argument); P_UX_SIGN(unpacked_argument, 0); /* Check for |arg| >= 1 */ exponent = G_UX_EXPONENT(unpacked_argument); f_hi = G_UX_MSD(unpacked_argument); if (exponent >= 1) { /* |x| >= 1, split out |x| == 1 and |x| > 1 */ P_UX_MSD(unpacked_result, UX_MSB); if ((exponent > 1) || !UX_FRACTION_IS_ONE_HALF(unpacked_argument)) /* |x| > 1, return error by forcing overflow */ P_UX_EXPONENT(unpacked_result, UX_OVERFLOW_EXPONENT); else { /* |x| = 1, return error by forcing "underflow" */ P_UX_EXPONENT(unpacked_result, UX_UNDERFLOW_EXPONENT); underflow_error = (sign) ? ATANH_OF_NEG_ONE : ATANH_OF_ONE; } } /* Check for x small */ else if ((exponent < -2) || ((exponent == -2) && (f_hi <= SQRT_2_M1_SQR))) { /* Argument is small, evaluate directly */ UX_LOG_POLY( unpacked_argument, unpacked_result); } else { /* Argument is not small, use log function */ ADDSUB(unpacked_argument, UX_ONE, ADD_SUB, unpacked_result); DIVIDE(unpacked_result + 1, unpacked_result, FULL_PRECISION, unpacked_result); NORMALIZE(unpacked_result); UX_LOG(unpacked_result, UX_LN2, unpacked_result); } /* Set sign of result, multiply by 1/2 and pack */ P_UX_SIGN(unpacked_result, sign); UX_DECR_EXPONENT(unpacked_result, 1); PACK( unpacked_result, PASS_RET_X_FLOAT(packed_result), underflow_error, ATANH_ABS_ARG_GT_ONE OPT_EXCEPTION_INFO); RETURN_X_FLOAT(packed_result); }
X_X_PROTO(F_ENTRY_NAME, packed_result, packed_argument) { WORD fp_class; UX_SIGN_TYPE sign; UX_EXPONENT_TYPE exponent; UX_FRACTION_DIGIT_TYPE f_hi; UX_FLOAT *unpacked_argument, *unpacked_result, tmp[3]; EXCEPTION_INFO_DECL DECLARE_X_FLOAT(packed_result) unpacked_argument = &tmp[2]; unpacked_result = &tmp[0]; INIT_EXCEPTION_INFO; fp_class = UNPACK( PASS_ARG_X_FLOAT(packed_argument), unpacked_argument, ACOSH_CLASS_TO_ACTION_MAP, PASS_RET_X_FLOAT(packed_result) OPT_EXCEPTION_INFO); if (0 > fp_class) RETURN_X_FLOAT(packed_result); /* Only positive arguments get here */ exponent = G_UX_EXPONENT(unpacked_argument); f_hi = G_UX_MSD(unpacked_argument); /* Compute x - 1 and x + 1 */ ADDSUB(unpacked_argument, UX_ONE, ADD_SUB, unpacked_result); /* Check for arguments less than one */ if (G_UX_SIGN(&unpacked_result[1])) { /* Arg was less than 1, force "overflow" */ P_UX_EXPONENT(unpacked_result, UX_OVERFLOW_EXPONENT); goto pack_it; } /* Check for small arguments */ else if ((exponent == 1) && (f_hi <= THREE_SQRT_2_OV_4)) { /* Argument is small, evaluate directly */ DIVIDE(unpacked_result + 1, unpacked_result, FULL_PRECISION, unpacked_result); UX_SQRT(unpacked_result, unpacked_result + 1); UX_LOG_POLY(unpacked_result + 1, unpacked_result); } else { /* Argument is not small, use log function */ MULTIPLY(unpacked_result + 1, unpacked_result, unpacked_result); NORMALIZE(unpacked_result); UX_SQRT(unpacked_result, unpacked_result); ADDSUB(unpacked_result, unpacked_argument, ADD, unpacked_result); UX_LOG(unpacked_result, UX_LN2, unpacked_result); } pack_it: PACK( unpacked_result, PASS_RET_X_FLOAT(packed_result), NOT_USED, ACOSH_ARG_LT_ONE OPT_EXCEPTION_INFO); RETURN_X_FLOAT(packed_result); }
void vesagtf_mode_params(unsigned h_pixels, unsigned v_lines, unsigned freq, struct vesagtf_params *params, int flags, struct videomode *vmp) { unsigned v_field_rqd; unsigned top_margin; unsigned bottom_margin; unsigned interlace; uint64_t h_period_est; unsigned vsync_plus_bp; unsigned v_back_porch __unused; unsigned total_v_lines; uint64_t v_field_est; uint64_t h_period; unsigned v_field_rate; unsigned v_frame_rate __unused; unsigned left_margin; unsigned right_margin; unsigned total_active_pixels; uint64_t ideal_duty_cycle; unsigned h_blank; unsigned total_pixels; unsigned pixel_freq; unsigned h_sync; unsigned h_front_porch; unsigned v_odd_front_porch_lines; #ifdef GTFDEBUG unsigned h_freq; #endif /* 1. In order to give correct results, the number of horizontal * pixels requested is first processed to ensure that it is divisible * by the character size, by rounding it to the nearest character * cell boundary: * * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND]) */ h_pixels = DIVIDE(h_pixels, CELL_GRAN) * CELL_GRAN; print_value(1, "[H PIXELS RND]", h_pixels); /* 2. If interlace is requested, the number of vertical lines assumed * by the calculation must be halved, as the computation calculates * the number of vertical lines per field. In either case, the * number of lines is rounded to the nearest integer. * * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0), * ROUND([V LINES],0)) */ v_lines = (flags & VESAGTF_FLAG_ILACE) ? DIVIDE(v_lines, 2) : v_lines; print_value(2, "[V LINES RND]", v_lines); /* 3. Find the frame rate required: * * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2, * [I/P FREQ RQD]) */ v_field_rqd = (flags & VESAGTF_FLAG_ILACE) ? (freq * 2) : (freq); print_value(3, "[V FIELD RATE RQD]", v_field_rqd); /* 4. Find number of lines in Top margin: * 5. Find number of lines in Bottom margin: * * [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y", * ROUND(([MARGIN%]/100*[V LINES RND]),0), * 0) * * Ditto for bottom margin. Note that instead of %, we use PPT, which * is parts per thousand. This helps us with integer math. */ top_margin = bottom_margin = (flags & VESAGTF_FLAG_MARGINS) ? DIVIDE(v_lines * params->margin_ppt, 1000) : 0; print_value(4, "[TOP MARGIN (LINES)]", top_margin); print_value(5, "[BOT MARGIN (LINES)]", bottom_margin); /* 6. If interlace is required, then set variable [INTERLACE]=0.5: * * [INTERLACE]=(IF([INT RQD?]="y",0.5,0)) * * To make this integer friendly, we use some special hacks in step * 7 below. Please read those comments to understand why I am using * a whole number of 1.0 instead of 0.5 here. */ interlace = (flags & VESAGTF_FLAG_ILACE) ? 1 : 0; print_value(6, "[2*INTERLACE]", interlace); /* 7. Estimate the Horizontal period * * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) / * ([V LINES RND] + (2*[TOP MARGIN (LINES)]) + * [MIN PORCH RND]+[INTERLACE]) * 1000000 * * To make it integer friendly, we pre-multiply the 1000000 to get to * usec. This gives us: * * [H PERIOD EST] = ((1000000/[V FIELD RATE RQD]) - [MIN VSYNC+BP]) / * ([V LINES RND] + (2 * [TOP MARGIN (LINES)]) + * [MIN PORCH RND]+[INTERLACE]) * * The other problem is that the interlace value is wrong. To get * the interlace to a whole number, we multiply both the numerator and * divisor by 2, so we can use a value of either 1 or 0 for the interlace * factor. * * This gives us: * * [H PERIOD EST] = ((2*((1000000/[V FIELD RATE RQD]) - [MIN VSYNC+BP])) / * (2*([V LINES RND] + (2*[TOP MARGIN (LINES)]) + * [MIN PORCH RND]) + [2*INTERLACE])) * * Finally we multiply by another 1000, to get value in picosec. * Why picosec? To minimize rounding errors. Gotta love integer * math and error propagation. */ h_period_est = DIVIDE(((DIVIDE(2000000000000ULL, v_field_rqd)) - (2000000 * params->min_vsbp)), ((2 * (v_lines + (2 * top_margin) + params->min_porch)) + interlace)); print_value(7, "[H PERIOD EST (ps)]", h_period_est); /* 8. Find the number of lines in V sync + back porch: * * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0) * * But recall that h_period_est is in psec. So multiply by 1000000. */ vsync_plus_bp = DIVIDE(params->min_vsbp * 1000000, h_period_est); print_value(8, "[V SYNC+BP]", vsync_plus_bp); /* 9. Find the number of lines in V back porch alone: * * [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND] * * XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]? */ v_back_porch = vsync_plus_bp - params->vsync_rqd; print_value(9, "[V BACK PORCH]", v_back_porch); /* 10. Find the total number of lines in Vertical field period: * * [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] + * [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] + * [MIN PORCH RND] */ total_v_lines = v_lines + top_margin + bottom_margin + vsync_plus_bp + interlace + params->min_porch; print_value(10, "[TOTAL V LINES]", total_v_lines); /* 11. Estimate the Vertical field frequency: * * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000 * * Again, we want to pre multiply by 10^9 to convert for nsec, thereby * making it usable in integer math. * * So we get: * * [V FIELD RATE EST] = 1000000000 / [H PERIOD EST] / [TOTAL V LINES] * * This is all scaled to get the result in uHz. Again, we're trying to * minimize error propagation. */ v_field_est = DIVIDE(DIVIDE(1000000000000000ULL, h_period_est), total_v_lines); print_value(11, "[V FIELD RATE EST(uHz)]", v_field_est); /* 12. Find the actual horizontal period: * * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST]) */ h_period = DIVIDE(h_period_est * v_field_est, v_field_rqd * 1000); print_value(12, "[H PERIOD(ps)]", h_period); /* 13. Find the actual Vertical field frequency: * * [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000 * * And again, we convert to nsec ahead of time, giving us: * * [V FIELD RATE] = 1000000 / [H PERIOD] / [TOTAL V LINES] * * And another rescaling back to mHz. Gotta love it. */ v_field_rate = DIVIDE(1000000000000ULL, h_period * total_v_lines); print_value(13, "[V FIELD RATE]", v_field_rate); /* 14. Find the Vertical frame frequency: * * [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE])) * * N.B. that the result here is in mHz. */ v_frame_rate = (flags & VESAGTF_FLAG_ILACE) ? v_field_rate / 2 : v_field_rate; print_value(14, "[V FRAME RATE]", v_frame_rate); /* 15. Find number of pixels in left margin: * 16. Find number of pixels in right margin: * * [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / * [CELL GRAN RND]),0)) * [CELL GRAN RND], * 0)) * * Again, we deal with margin percentages as PPT (parts per thousand). * And the calculations for left and right are the same. */ left_margin = right_margin = (flags & VESAGTF_FLAG_MARGINS) ? DIVIDE(DIVIDE(h_pixels * params->margin_ppt, 1000), CELL_GRAN) * CELL_GRAN : 0; print_value(15, "[LEFT MARGIN (PIXELS)]", left_margin); print_value(16, "[RIGHT MARGIN (PIXELS)]", right_margin); /* 17. Find total number of active pixels in image and left and right * margins: * * [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] + * [RIGHT MARGIN (PIXELS)] */ total_active_pixels = h_pixels + left_margin + right_margin; print_value(17, "[TOTAL ACTIVE PIXELS]", total_active_pixels); /* 18. Find the ideal blanking duty cycle from the blanking duty cycle * equation: * * [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000) * * However, we have modified values for [C'] as [256*C'] and * [M'] as [256*M']. Again the idea here is to get good scaling. * We use 256 as the factor to make the math fast. * * Note that this means that we have to scale it appropriately in * later calculations. * * The ending result is that our ideal_duty_cycle is 256000x larger * than the duty cycle used by VESA. But again, this reduces error * propagation. */ ideal_duty_cycle = ((C_PRIME256(params) * 1000) - (M_PRIME256(params) * h_period / 1000000)); print_value(18, "[IDEAL DUTY CYCLE]", ideal_duty_cycle); /* 19. Find the number of pixels in the blanking time to the nearest * double character cell: * * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] * * [IDEAL DUTY CYCLE] / * (100-[IDEAL DUTY CYCLE]) / * (2*[CELL GRAN RND])), 0)) * * (2*[CELL GRAN RND]) * * Of course, we adjust to make this rounding work in integer math. */ h_blank = DIVIDE(DIVIDE(total_active_pixels * ideal_duty_cycle, (256000 * 100ULL) - ideal_duty_cycle), 2 * CELL_GRAN) * (2 * CELL_GRAN); print_value(19, "[H BLANK (PIXELS)]", h_blank); /* 20. Find total number of pixels: * * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)] */ total_pixels = total_active_pixels + h_blank; print_value(20, "[TOTAL PIXELS]", total_pixels); /* 21. Find pixel clock frequency: * * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD] * * We calculate this in Hz rather than MHz, to get a value that * is usable with integer math. Recall that the [H PERIOD] is in * nsec. */ pixel_freq = DIVIDE(total_pixels * 1000000, DIVIDE(h_period, 1000)); print_value(21, "[PIXEL FREQ]", pixel_freq); /* 22. Find horizontal frequency: * * [H FREQ] = 1000 / [H PERIOD] * * I've ifdef'd this out, because we don't need it for any of * our calculations. * We calculate this in Hz rather than kHz, to avoid rounding * errors. Recall that the [H PERIOD] is in usec. */ #ifdef GTFDEBUG h_freq = 1000000000 / h_period; print_value(22, "[H FREQ]", h_freq); #endif /* Stage 1 computations are now complete; I should really pass the results to another function and do the Stage 2 computations, but I only need a few more values so I'll just append the computations here for now */ /* 17. Find the number of pixels in the horizontal sync period: * * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] / * [CELL GRAN RND]),0))*[CELL GRAN RND] * * Rewriting for integer math: * * [H SYNC (PIXELS)]=(ROUND((H SYNC%] * [TOTAL PIXELS] / 100 / * [CELL GRAN RND),0))*[CELL GRAN RND] */ h_sync = DIVIDE(((params->hsync_pct * total_pixels) / 100), CELL_GRAN) * CELL_GRAN; print_value(17, "[H SYNC (PIXELS)]", h_sync); /* 18. Find the number of pixels in the horizontal front porch period: * * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)] * * Note that h_blank is always an even number of characters (i.e. * h_blank % (CELL_GRAN * 2) == 0) */ h_front_porch = (h_blank / 2) - h_sync; print_value(18, "[H FRONT PORCH (PIXELS)]", h_front_porch); /* 36. Find the number of lines in the odd front porch period: * * [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE]) * * Adjusting for the fact that the interlace is scaled: * * [V ODD FRONT PORCH(LINES)]=(([MIN PORCH RND] * 2) + [2*INTERLACE]) / 2 */ v_odd_front_porch_lines = ((2 * params->min_porch) + interlace) / 2; print_value(36, "[V ODD FRONT PORCH(LINES)]", v_odd_front_porch_lines); /* finally, pack the results in the mode struct */ vmp->hsync_start = h_pixels + h_front_porch; vmp->hsync_end = vmp->hsync_start + h_sync; vmp->htotal = total_pixels; vmp->hdisplay = h_pixels; vmp->vsync_start = v_lines + v_odd_front_porch_lines; vmp->vsync_end = vmp->vsync_start + params->vsync_rqd; vmp->vtotal = total_v_lines; vmp->vdisplay = v_lines; vmp->dot_clock = pixel_freq; }