예제 #1
0
        /* compute all values */
        public static void compute_res_net_all(out std.vector <rgb_t> rgb, ListBytesPointer prom, res_net_decode_info rdi, res_net_info di)  //std::vector<rgb_t> &rgb, const u8 *prom, const res_net_decode_info &rdi, const res_net_info &di);
        {
            u8  r;
            u8  g;
            u8  b;
            int i;
            int j;
            int k;

            rgb = new std.vector <rgb_t>();
            rgb.resize(rdi.end - rdi.start + 1);
            for (i = rdi.start; i <= rdi.end; i++)
            {
                u8 [] t = new u8[3] {
                    0, 0, 0
                };
                int s;
                for (j = 0; j < rdi.numcomp; j++)
                {
                    for (k = 0; k < 3; k++)
                    {
                        s = rdi.shift[3 * j + k];
                        if (s > 0)
                        {
                            t[k] = (u8)(t[k] | ((prom[i + rdi.offset[3 * j + k]] >> s) & rdi.mask[3 * j + k]));
                        }
                        else
                        {
                            t[k] = (u8)(t[k] | ((prom[i + rdi.offset[3 * j + k]] << (0 - s)) & rdi.mask[3 * j + k]));
                        }
                    }
                }

                r = (u8)compute_res_net(t[0], RES_NET_CHAN_RED, di);
                g = (u8)compute_res_net(t[1], RES_NET_CHAN_GREEN, di);
                b = (u8)compute_res_net(t[2], RES_NET_CHAN_BLUE, di);
                rgb[i - rdi.start] = new rgb_t(r, g, b);
            }
        }
예제 #2
0
        /* return a single value for one channel */
        public static int compute_res_net(int inputs, int channel, res_net_info di)
        {
            double rTotal = 0.0;
            double v      = 0;
            int    i;

            double vBias   = di.rgb[channel].vBias;
            double vOH     = di.vOH;
            double vOL     = di.vOL;
            double minout  = di.rgb[channel].minout;
            double cut     = di.rgb[channel].cut;
            double vcc     = di.vcc;
            double ttlHRes = 0;
            double rGnd    = di.rgb[channel].rGnd;
            u8     OpenCol = di.OpenCol;

            /* Global options */

            switch (di.options & RES_NET_AMP_MASK)
            {
            case RES_NET_AMP_USE_GLOBAL:
                /* just ignore */
                break;

            case RES_NET_AMP_NONE:
                minout = 0.0;
                cut    = 0.0;
                break;

            case RES_NET_AMP_DARLINGTON:
                minout = 0.9;
                cut    = 0.0;
                break;

            case RES_NET_AMP_EMITTER:
                minout = 0.0;
                cut    = 0.7;
                break;

            case RES_NET_AMP_CUSTOM:
                /* Fall through */
                break;

            default:
                global_object.fatalerror("compute_res_net: Unknown amplifier type\n");
                break;
            }

            switch (di.options & RES_NET_VCC_MASK)
            {
            case RES_NET_VCC_5V:
                vcc = 5.0;
                break;

            case RES_NET_VCC_CUSTOM:
                /* Fall through */
                break;

            default:
                global_object.fatalerror("compute_res_net: Unknown vcc type\n");
                break;
            }

            switch (di.options & RES_NET_VBIAS_MASK)
            {
            case RES_NET_VBIAS_USE_GLOBAL:
                /* just ignore */
                break;

            case RES_NET_VBIAS_5V:
                vBias = 5.0;
                break;

            case RES_NET_VBIAS_TTL:
                vBias = TTL_VOH;
                break;

            case RES_NET_VBIAS_CUSTOM:
                /* Fall through */
                break;

            default:
                global_object.fatalerror("compute_res_net: Unknown vcc type\n");
                break;
            }

            switch (di.options & RES_NET_VIN_MASK)
            {
            case RES_NET_VIN_OPEN_COL:
                OpenCol = 1;
                vOL     = TTL_VOL;
                break;

            case RES_NET_VIN_VCC:
                vOL     = 0.0;
                vOH     = vcc;
                OpenCol = 0;
                break;

            case RES_NET_VIN_TTL_OUT:
                vOL = TTL_VOL;
                vOH = TTL_VOH;

                /* rough estimation from 82s129 (7052) datasheet and from various sources
                 * 1.4k / 30
                 */
                ttlHRes = 50;
                OpenCol = 0;
                break;

            case RES_NET_VIN_CUSTOM:
                /* Fall through */
                break;

            default:
                global_object.fatalerror("compute_res_net: Unknown vin type\n");
                break;
            }

            /* Per channel options */

            switch (di.rgb[channel].options & RES_NET_AMP_MASK)
            {
            case RES_NET_AMP_USE_GLOBAL:
                /* use global defaults */
                break;

            case RES_NET_AMP_NONE:
                minout = 0.0;
                cut    = 0.0;
                break;

            case RES_NET_AMP_DARLINGTON:
                minout = 0.7;
                cut    = 0.0;
                break;

            case RES_NET_AMP_EMITTER:
                minout = 0.0;
                cut    = 0.7;
                break;

            case RES_NET_AMP_CUSTOM:
                /* Fall through */
                break;

            default:
                global_object.fatalerror("compute_res_net: Unknown amplifier type\n");
                break;
            }

            switch (di.rgb[channel].options & RES_NET_VBIAS_MASK)
            {
            case RES_NET_VBIAS_USE_GLOBAL:
                /* use global defaults */
                break;

            case RES_NET_VBIAS_5V:
                vBias = 5.0;
                break;

            case RES_NET_VBIAS_TTL:
                vBias = TTL_VOH;
                break;

            case RES_NET_VBIAS_CUSTOM:
                /* Fall through */
                break;

            default:
                global_object.fatalerror("compute_res_net: Unknown vcc type\n");
                break;
            }

            /* Input impedances */

            switch (di.options & RES_NET_MONITOR_MASK)
            {
            case RES_NET_MONITOR_INVERT:
            case RES_NET_MONITOR_SANYO_EZV20:
                /* Nothing */
                break;

            case RES_NET_MONITOR_ELECTROHOME_G07:
                if (rGnd != 0.0)
                {
                    rGnd = rGnd * 5600 / (rGnd + 5600);
                }
                else
                {
                    rGnd = 5600;
                }
                break;
            }

            /* compute here - pass a / low inputs */

            for (i = 0; i < di.rgb[channel].num; i++)
            {
                int level = ((inputs >> i) & 1);
                if (di.rgb[channel].R[i] != 0.0 && level == 0)
                {
                    // There is no difference in the calculation of the "low" input
                    // (transistor conducting to ground) between TTL output and
                    // open collector output. This is documented explicitly in the
                    // code below (no difference if / else.
                    if (OpenCol != 0)
                    {
                        rTotal += 1.0 / di.rgb[channel].R[i];
                        v      += vOL / di.rgb[channel].R[i];
                    }
                    else
                    {
                        rTotal += 1.0 / di.rgb[channel].R[i];
                        v      += vOL / di.rgb[channel].R[i];
                    }
                }
            }

            /* Mix in rbias and rgnd */
            if (di.rgb[channel].rBias != 0.0)
            {
                rTotal += 1.0 / di.rgb[channel].rBias;
                v      += vBias / di.rgb[channel].rBias;
            }
            if (rGnd != 0.0)
            {
                rTotal += 1.0 / rGnd;
            }

            /* if the resulting voltage after application of all low inputs is
             * greater than vOH, treat high inputs as open collector/high impedance
             * There will be now current into/from the TTL gate
             */

            if ((di.options & RES_NET_VIN_MASK) == RES_NET_VIN_TTL_OUT)
            {
                if (v / rTotal > vOH)
                {
                    OpenCol = 1;
                }
            }

            /* Second pass - high inputs */

            for (i = 0; i < di.rgb[channel].num; i++)
            {
                int level = ((inputs >> i) & 1);
                if (di.rgb[channel].R[i] != 0.0 && level != 0)
                {
                    if (OpenCol != 0)
                    {
                        rTotal += 0;
                        v      += 0;
                    }
                    else
                    {
                        rTotal += 1.0 / (di.rgb[channel].R[i] + ttlHRes);
                        v      += vOH / (di.rgb[channel].R[i] + ttlHRes);
                    }
                }
            }

            rTotal = 1.0 / rTotal;
            v     *= rTotal;
            v      = Math.Max(minout, v - cut);

            switch (di.options & RES_NET_MONITOR_MASK)
            {
            case RES_NET_MONITOR_INVERT:
                v = vcc - v;
                break;

            case RES_NET_MONITOR_SANYO_EZV20:
                v = vcc - v;
                v = Math.Max((double)0, v - 0.7);
                v = Math.Min(v, vcc - 2 * 0.7);
                v = v / (vcc - 1.4);
                v = v * vcc;
                break;

            case RES_NET_MONITOR_ELECTROHOME_G07:
                /* Nothing */
                break;
            }

            return((int)(v * 255 / vcc + 0.4));
        }