Annotation of 42BSD/games/compat/dofloat.c, revision 1.1.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.