Annotation of 40BSD/games/compat/dofloat.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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