Annotation of 42BSD/games/compat/dofloat.c, revision 1.1

1.1     ! root        1: #
        !             2: static char sccsid[] = "       dofloat.c       4.1     82/05/12        ";
        !             3: /*
        !             4:  *     Simulate pdp11 floating point for compatability mode programs.
        !             5:  *     Quick and dirty with no big effort at speed since it takes so
        !             6:  *     much overhead to get here in the first place.
        !             7:  *     I make no claims on the completeness of this simulation.
        !             8:  *     Art Wetzel 3/16/80
        !             9:  */
        !            10: #ifndef NOFPSIM
        !            11: #ifdef DEBUG
        !            12: #include <stdio.h>
        !            13: #endif
        !            14: #include "defs.h"
        !            15: /* output codes */
        !            16: #define        NONE    0
        !            17: #define        SHORT   01
        !            18: #define        LONG    02
        !            19: #define        FLOAT   04
        !            20: #define        DOUBLE  010
        !            21: #define        OUTPUT  020
        !            22: /* parts of fps */
        !            23: #define        FD      0200
        !            24: #define        FL      0100
        !            25: #define        FN      010
        !            26: #define        FZ      04
        !            27: #define        FV      02
        !            28: #define        FC      01
        !            29: /* fis instructions */
        !            30: #define        FADD    075000
        !            31: #define        FSUB    075010
        !            32: #define        FMUL    075020
        !            33: #define        FDIV    075030
        !            34: /* fpu instructions */
        !            35: #define        ABSD    0170600
        !            36: #define        ABSF    0170600
        !            37: #define        ADDD    0172000
        !            38: #define        ADDF    0172000
        !            39: #define        CFCC    0170000
        !            40: #define        CLRD    0170400
        !            41: #define        CLRF    0170400
        !            42: #define        CMPD    0173400
        !            43: #define        CMPF    0173400
        !            44: #define        DIVD    0174400
        !            45: #define        DIVF    0174400
        !            46: #define        LDCFD   0177400
        !            47: #define        LDCFF   0177400
        !            48: #define        LDCLD   0177000
        !            49: #define        LDCLF   0177000
        !            50: #define        LDCIF   0177000
        !            51: #define        LDCID   0177000
        !            52: #define        LDEXP   0176400
        !            53: #define        LDD     0172400
        !            54: #define        LDF     0172400
        !            55: #define        LDFPS   0170100
        !            56: #define        MODD    0171400
        !            57: #define        MODF    0171400
        !            58: #define        MULD    0171000
        !            59: #define        MULF    0171000
        !            60: #define        NEGD    0170700
        !            61: #define        NEGF    0170700
        !            62: #define        SETF    0170001
        !            63: #define        SETD    0170011
        !            64: #define        SETI    0170002
        !            65: #define        SETL    0170012
        !            66: #define        STCDF   0176000
        !            67: #define        STCFD   0176000
        !            68: #define        STCDL   0175400
        !            69: #define        STCDI   0175400
        !            70: #define        STCFL   0175400
        !            71: #define        STCFI   0175400
        !            72: #define        STEXP   0175000
        !            73: #define        STD     0174000
        !            74: #define        STF     0174000
        !            75: #define        STFPS   0170200
        !            76: #define        STST    0170300
        !            77: #define        SUBD    0173000
        !            78: #define        SUBF    0173000
        !            79: #define        TSTD    0170500
        !            80: #define        TSTF    0170500
        !            81: union  alltypes        {
        !            82:        double  d;
        !            83:        float   f;
        !            84:        long    l;
        !            85:        short   s;
        !            86:        unsigned short p[4];
        !            87: };
        !            88: /* static storage for floating registers */
        !            89: static union   alltypes        fregs[6];
        !            90: static union   alltypes        srcdst;
        !            91: int    fps = FD|FL;
        !            92: int    dbl = 0;
        !            93: int    lng = 0;
        !            94: #endif
        !            95: dofloat(instr) unsigned int instr; {
        !            96: #ifdef NOFPSIM
        !            97:        return(-1);
        !            98: #else
        !            99:        register unsigned short *wptr;
        !           100:        register unsigned int opcode, ac, mode, fac, adjust, output, ccset;
        !           101:        unsigned short *locate();
        !           102:        /* indicate what condition codes will be changed by op - assume none */
        !           103:        ccset = 0;
        !           104:        /* type of memory output - assume none */
        !           105:        output = NONE;
        !           106:        /* default adjust to type */
        !           107:        if(dbl)
        !           108:                adjust = DOUBLE;
        !           109:        else
        !           110:                adjust = FLOAT;
        !           111:        /* chop up instruction to get relevent parts */
        !           112:        opcode = instr & 0177700;
        !           113:        fac = (instr>>6) & 03;
        !           114:        mode = (instr>>3) & 07;
        !           115:        ac = instr & 07;
        !           116:        /* if the instruction uses a src/dst construct ptr and fetch */
        !           117:        switch(opcode) {
        !           118:        case    FADD:
        !           119:        case    CFCC:
        !           120:                break;
        !           121:        default:
        !           122:                wptr = locate(mode, ac);
        !           123:                /* special case for mode 0 */
        !           124:                if(mode == 0) switch(opcode & 0177400) {
        !           125:                /* special instructions to use cpu regs */
        !           126:                case    LDEXP:
        !           127:                case    STEXP:
        !           128:                        wptr = &regs[ac];
        !           129:                        break;
        !           130:                case    STCDL:
        !           131:                        wptr = &regs[ac];
        !           132:                default:
        !           133:                        break;
        !           134:                }
        !           135:                if(dbl)
        !           136:                        srcdst.d = *(double *)wptr;
        !           137:                else
        !           138:                        srcdst.f = *(float *)wptr;
        !           139:                /* immediate fetches are 16 bits */
        !           140:                if(ac == 7 && (mode == 2)) {
        !           141:                        srcdst.p[1] = 0;
        !           142:                        srcdst.p[2] = 0;
        !           143:                        srcdst.p[3] = 0;
        !           144:                }
        !           145:                break;
        !           146:        }
        !           147: #ifdef DEBUG
        !           148: fprintf(stderr,"pc %o sp %o instr %o srcdst %o mode %o reg %o fac %o\n", pc-1,regs[6],instr,srcdst.s,mode,ac,fac);
        !           149: #endif
        !           150:        switch(opcode) {
        !           151:        case    FADD:
        !           152:                /* catches all fis instructions */
        !           153:                /* last 3 bits are stack pointer register */
        !           154:                ac = instr & 07;
        !           155:                /* get pointer to stack words */
        !           156:                wptr = (unsigned short *)regs[ac];
        !           157:                /* getch floating value from stack */
        !           158:                srcdst.f = *(float *)wptr;
        !           159:                /* shorten stack */
        !           160:                wptr += 2;
        !           161:                /* do appropriate operation */
        !           162:                switch(instr & 0177770) {
        !           163:                case    FADD:
        !           164:                        srcdst.f += *(float *)wptr;
        !           165:                        break;
        !           166:                case    FSUB:
        !           167:                        srcdst.f = *(float *)wptr - srcdst.f;
        !           168:                        break;
        !           169:                case    FMUL:
        !           170:                        srcdst.f *= *(float *)wptr;
        !           171:                        break;
        !           172:                case    FDIV:
        !           173:                        srcdst.f = *(float *)wptr / srcdst.f;
        !           174:                        break;
        !           175:                default:
        !           176:                        return(-1);
        !           177:                }
        !           178:                /* copy out result */
        !           179:                *(float *)wptr = srcdst.f;
        !           180:                /* set up condition codes */
        !           181:                psl &= ~017;
        !           182:                if(srcdst.f == 0.) psl |= FZ;
        !           183:                if(srcdst.f < 0.) psl |= FN;
        !           184:                /* adjust register to reflect stack change */
        !           185:                regs[ac] = (unsigned short)(int)wptr;
        !           186:                return(0);
        !           187:        case    CFCC:
        !           188:                switch(instr) {
        !           189:                case    SETF:
        !           190:                        dbl = 0;
        !           191:                        break;
        !           192:                case    SETD:
        !           193:                        dbl = 1;
        !           194:                        break;
        !           195:                case    SETI:
        !           196:                        lng = 0;
        !           197:                        break;
        !           198:                case    SETL:
        !           199:                        lng = 1;
        !           200:                        break;
        !           201:                case    CFCC:
        !           202:                        psl &= ~017;
        !           203:                        psl |= (fps & 017);
        !           204: #ifdef DEBUG
        !           205: fprintf(stderr,"CFCC %o\n",psl);
        !           206: #endif
        !           207:                        break;
        !           208:                default:
        !           209:                        return(-1);
        !           210:                }
        !           211:                return(0);
        !           212:        case    ABSD:
        !           213:                if(srcdst.d < 0.0 ) srcdst.d = -srcdst.d;
        !           214:                ccset = FZ;
        !           215:                if(dbl) 
        !           216:                        output = DOUBLE;
        !           217:                else
        !           218:                        output = FLOAT;
        !           219:                break;
        !           220:        case    CLRD:
        !           221:                srcdst.d =0.0;
        !           222:                ccset = FZ;
        !           223:                if(dbl)
        !           224:                        output = DOUBLE;
        !           225:                else
        !           226:                        output = FLOAT;
        !           227:                break;
        !           228:        case    LDFPS:
        !           229:                adjust = SHORT;
        !           230:                fps = srcdst.s;
        !           231:                if(fps & FD)
        !           232:                        dbl = 1;
        !           233:                else
        !           234:                        dbl = 0;
        !           235:                if(fps & FL )
        !           236:                        lng = 1;
        !           237:                else
        !           238:                        lng = 0;
        !           239:                break;
        !           240:        case    NEGD:
        !           241:                srcdst.d = -srcdst.d;
        !           242:                ccset = FZ|FN;
        !           243:                if(dbl)
        !           244:                        output = DOUBLE;
        !           245:                else
        !           246:                        output = FLOAT;
        !           247:                break;
        !           248:        case    STFPS:
        !           249:                srcdst.s = fps;
        !           250:                adjust = output = SHORT;
        !           251:                break;
        !           252:        case    STST:
        !           253:                return(0);
        !           254:                break;
        !           255:        case    TSTD:
        !           256:                ccset = FZ|FN;
        !           257:                break;
        !           258:        default:
        !           259:                opcode = instr & 0177400;
        !           260:                switch(opcode) {
        !           261:                case    STD:
        !           262:                        srcdst.d = fregs[fac].d;
        !           263: #ifdef DEBUG
        !           264: fprintf(stderr,"STD %o\n",srcdst.s);
        !           265: #endif
        !           266:                        if(dbl)
        !           267:                                output = DOUBLE;
        !           268:                        else
        !           269:                                output = FLOAT;
        !           270:                        break;
        !           271:                case    LDD:
        !           272: #ifdef DEBUG
        !           273: fprintf(stderr,"LDD %o\n",srcdst.s);
        !           274: #endif
        !           275:                        fregs[fac].d = srcdst.d;
        !           276:                        ccset = FZ|FN;
        !           277:                        break;
        !           278:                case    ADDD:
        !           279:                        fregs[fac].d += srcdst.d;
        !           280:                        ccset = FZ|FN;
        !           281:                        break;
        !           282:                case    SUBD:
        !           283:                        fregs[fac].d -= srcdst.d;
        !           284:                        ccset = FZ|FN;
        !           285:                        break;
        !           286:                case    MULD:
        !           287:                        fregs[fac].d *= srcdst.d;
        !           288:                        ccset = FZ|FN;
        !           289:                        break;
        !           290:                case    DIVD:
        !           291: #ifdef DEBUG
        !           292: fprintf(stderr,"DIVD %f by %f gives ",fregs[fac].d,srcdst.d);
        !           293: #endif
        !           294:                        fregs[fac].d /= srcdst.d;
        !           295: #ifdef DEBUG
        !           296: fprintf(stderr,"-> %f\n",fregs[fac].d);
        !           297: #endif
        !           298:                        ccset = FZ|FN;
        !           299:                        break;
        !           300:                case    STCDF:
        !           301:                        adjust = output = FLOAT;
        !           302:                        ccset = FZ|FN;
        !           303:                        break;
        !           304:                case    LDCFD:
        !           305:                        adjust = FLOAT;
        !           306:                        ccset = FZ|FN;
        !           307:                        break;
        !           308:                case    LDCLD:
        !           309:                        if(lng) {
        !           310:                                adjust = LONG;
        !           311:                                srcdst.d = srcdst.l;
        !           312:                        } else {
        !           313:                                adjust = SHORT;
        !           314:                                srcdst.d = srcdst.s;
        !           315:                        }
        !           316:                        ccset = FZ|FN;
        !           317:                        break;
        !           318:                case    CMPD:
        !           319:                        srcdst.d -= fregs[fac].d;
        !           320:                        ccset = FZ|FN;
        !           321:                        break;
        !           322:                case    LDEXP:
        !           323:                        srcdst.d = 0.0;
        !           324:                        srcdst.s = *wptr;
        !           325:                        srcdst.s <<= 7;
        !           326:                        srcdst.s += 0200;
        !           327:                        adjust = SHORT;
        !           328:                        ccset = FZ|FN;
        !           329: #ifdef DEBUG
        !           330: fprintf(stderr,"LDEXP %o gives %o\n",*wptr,srcdst.s);
        !           331: #endif
        !           332:                        break;
        !           333:                case    MODD:
        !           334:                        srcdst.d *= fregs[fac].d;
        !           335:                        fregs[fac].d = (double)(long)srcdst.d;
        !           336:                        if(~fac & 1) fregs[fac + 1].d = fregs[fac].d;
        !           337:                        srcdst.d -= fregs[fac].d;
        !           338:                        ccset = FN|FZ;
        !           339:                        fregs[fac].d = srcdst.d;
        !           340: #ifdef DEBUG
        !           341: fprintf(stderr,"MODD %o %o\n",fregs[fac].s,fregs[fac+1].s);
        !           342: #endif
        !           343:                        break;
        !           344:                case    STCDL:
        !           345:                        if(lng)
        !           346:                                adjust = output = LONG;
        !           347:                        else
        !           348:                                adjust = output = SHORT;
        !           349:                        if(mode == 0) output = SHORT;
        !           350:                        srcdst.l = fregs[fac].d;
        !           351: #ifdef DEBUG
        !           352: fprintf(stderr,"STCDL %o\n",srcdst.l);
        !           353: #endif
        !           354:                        ccset = FZ|FN;
        !           355:                        break;
        !           356:                case    STEXP:
        !           357: #ifdef DEBUG
        !           358: fprintf(stderr,"STEXP of %o gives ",srcdst.s);
        !           359: #endif
        !           360:                        srcdst.s &= 077600;
        !           361:                        srcdst.s >>= 7;
        !           362:                        srcdst.s -= 0200;
        !           363:                        adjust = output = SHORT;
        !           364:                        ccset = FZ|FN;
        !           365: #ifdef DEBUG
        !           366: fprintf(stderr,"%o\n",srcdst.s);
        !           367: #endif
        !           368:                        break;
        !           369:                default:
        !           370:                        return(-1);
        !           371:                }
        !           372:        }
        !           373:        if(ccset & FZ) {
        !           374:                fps &= ~FZ;
        !           375:                if(srcdst.d == 0.0) fps |= FZ;
        !           376:                if(!dbl && srcdst.f == 0.0) fps |= FZ;
        !           377:        }
        !           378:        if(ccset & FN) {
        !           379:                fps &= ~FN;
        !           380:                if(srcdst.f < 0.0) fps |= FN;
        !           381:        }
        !           382:        switch(instr & 0177400) {
        !           383:        case    STCDL:
        !           384:        case    STEXP:
        !           385:                psl &= ~017;
        !           386:                psl |= (fps & 017);
        !           387:                break;
        !           388:        default:
        !           389:                break;
        !           390:        }
        !           391:        switch(output) {
        !           392:        case    NONE:
        !           393:                break;
        !           394:        case    SHORT:
        !           395:                *((short *)wptr) = srcdst.s;
        !           396:                srcdst.d = 0.0;
        !           397:                break;
        !           398:        case    LONG:
        !           399:                if(mode == 4) wptr--;
        !           400:                *((long *)wptr) = longrev(srcdst.l);
        !           401:                break;
        !           402:        case    FLOAT:
        !           403:                if(mode == 4) wptr--;
        !           404:                *((float *)wptr) = srcdst.f;
        !           405:                break;
        !           406:        case    DOUBLE:
        !           407:                if(mode == 4) wptr -= 3;
        !           408:                *((double *)wptr) = srcdst.d;
        !           409:                break;
        !           410:        }
        !           411:        switch(mode) {
        !           412:        case    0:
        !           413:        case    1:
        !           414:                break;
        !           415:        case    2:
        !           416:                switch(adjust) {
        !           417:                case    SHORT:
        !           418:                        regs[ac] += 2;
        !           419:                        break;
        !           420:                case    LONG:
        !           421:                case    FLOAT:
        !           422:                        regs[ac] += 4;
        !           423:                        break;
        !           424:                case    DOUBLE:
        !           425:                        regs[ac] += 8;
        !           426:                        break;
        !           427:                case    NONE:
        !           428:                        break;
        !           429:                }
        !           430:                if(ac == 7) pc++;
        !           431:                break;
        !           432:        case    3:
        !           433:                regs[ac] += 2;
        !           434:                if(ac == 7) pc++;
        !           435:                break;
        !           436:        case    4:
        !           437:                switch(adjust) {
        !           438:                case    SHORT:
        !           439:                        regs[ac] -= 2;
        !           440:                        break;
        !           441:                case    LONG:
        !           442:                case    FLOAT:
        !           443:                        regs[ac] -= 4;
        !           444:                        break;
        !           445:                case    DOUBLE:
        !           446:                        regs[ac] -= 8;
        !           447:                        break;
        !           448:                case    NONE:
        !           449:                        break;
        !           450:                }
        !           451:                break;
        !           452:        case    5:
        !           453:                regs[ac] -= 2;
        !           454:                break;
        !           455:        case    6:
        !           456:        case    7:
        !           457:                pc++;
        !           458:                break;
        !           459:        }
        !           460:        return(0);
        !           461: #endif
        !           462: }
        !           463: #ifndef NOFPSIM
        !           464: unsigned short *locate(mode, ac) {
        !           465:        register unsigned short *wptr;
        !           466:        switch(mode) {
        !           467:        case    0:
        !           468:                /* mode 0 normally implies fregs */
        !           469:                wptr = (unsigned short *)&fregs[ac];
        !           470:                break;
        !           471:        case    1:
        !           472:                break;
        !           473:        case    2:
        !           474:                wptr = (unsigned short *)(int)regs[ac];
        !           475:                break;
        !           476:        case    3:
        !           477:                wptr = (unsigned short *)regs[ac];
        !           478:                wptr = (unsigned short *)*wptr;
        !           479:                break;
        !           480:        case    4:
        !           481:                wptr = (unsigned short *)regs[ac];
        !           482:                wptr--;
        !           483:                break;
        !           484:        case    5:
        !           485:                wptr = (unsigned short *)regs[ac];
        !           486:                wptr--;
        !           487:                wptr = (unsigned short *)*wptr;
        !           488:                break;
        !           489:        case    6:
        !           490:                wptr = (unsigned short *)((regs[ac] + *pc) & 0177776);
        !           491:                if(ac == 7) wptr++;
        !           492:                break;
        !           493:        case    7:
        !           494:                wptr = (unsigned short *)((regs[ac] + *pc) & 0177776);
        !           495:                if(ac == 7) wptr++;
        !           496:                wptr = (unsigned short *)*wptr;
        !           497:                break;
        !           498:        }
        !           499:        return(wptr);
        !           500: }
        !           501: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.