Annotation of MiNT/src/xbios.c, revision 1.1.1.2

1.1       root        1: /*
                      2: 
                      3: Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
                      4: 
                      5: */
                      6: 
                      7: 
                      8: 
                      9: /*
                     10: 
                     11:  * XBIOS replacement routines
                     12: 
                     13:  */
                     14: 
                     15: 
                     16: 
                     17: #include "mint.h"
                     18: 
                     19: 
                     20: 
                     21: extern int tosvers;    /* from main.c */
                     22: 
                     23: 
                     24: 
                     25: #define XBIOS_MAX 0x80
                     26: 
                     27: 
                     28: 
                     29: Func xbios_tab[XBIOS_MAX];     /* initially all zeros */
                     30: 
                     31: short xbios_max = XBIOS_MAX;
                     32: 
                     33: 
                     34: 
                     35: /* NOTE: has_bconmap is initialized in main.c */
                     36: 
                     37: 
                     38: 
                     39: int has_bconmap;       /* flag: set if running under a version
                     40: 
                     41:                         * of TOS which supports Bconmap
                     42: 
                     43:                         */
                     44: 
                     45: 
                     46: 
                     47: /*
                     48: 
                     49:  * Supexec() presents a lot of problems for us: for example, the user
                     50: 
                     51:  * may be calling the kernel, or may be changing interrupt vectors
                     52: 
                     53:  * unexpectedly. So we play some dirty tricks here: the function
                     54: 
                     55:  * call is treated like a signal handler, and we take advantage
                     56: 
                     57:  * of the fact that no context switches will take place while
                     58: 
                     59:  * in supervisor mode. ASSUMPTION: the user will not choose to
                     60: 
                     61:  * switch back to user mode, or if s/he does it will be as part
                     62: 
                     63:  * of a longjmp().
                     64: 
                     65:  *
                     66: 
                     67:  * BUG: if the user function switches to user mode, then back to
                     68: 
                     69:  * supervisor mode and returns, then the returned value may be
                     70: 
                     71:  * inaccurate (this happens if two programs make Supexec calls
                     72: 
                     73:  * at the same time).
                     74: 
                     75:  */
                     76: 
                     77: 
                     78: 
1.1.1.2 ! root       79: static long ARGS_ON_STACK (*usrcall) P_((long,long,long,long,long));
1.1       root       80: 
                     81: static long usrret;
                     82: 
                     83: static long usrarg1, usrarg2, usrarg3, usrarg4, usrarg5;
                     84: 
                     85: 
                     86: 
1.1.1.2 ! root       87: static void ARGS_ON_STACK do_usrcall P_((void));
1.1       root       88: 
                     89: 
                     90: 
1.1.1.2 ! root       91: static void ARGS_ON_STACK
1.1       root       92: 
                     93: do_usrcall()
                     94: 
                     95: {
                     96: 
                     97:        usrret = (*usrcall)(usrarg1, usrarg2, usrarg3, usrarg4, usrarg5);
                     98: 
                     99: }
                    100: 
                    101: 
                    102: 
1.1.1.2 ! root      103: long ARGS_ON_STACK
1.1       root      104: 
                    105: supexec(funcptr, arg1, arg2, arg3, arg4, arg5)
                    106: 
                    107:        Func funcptr;
                    108: 
                    109:        long arg1, arg2, arg3, arg4, arg5;
                    110: 
                    111: {
                    112: 
                    113:        short savesr;
                    114: 
                    115:        CONTEXT *syscall = &curproc->ctxt[SYSCALL];
                    116: 
                    117: 
                    118: 
                    119: /* set things up so that "signal 0" will be handled by calling the user's
                    120: 
                    121:  * function.
                    122: 
                    123:  */
                    124: 
                    125: 
                    126: 
                    127:        usrcall = funcptr;
                    128: 
                    129:        usrarg1 = arg1;
                    130: 
                    131:        usrarg2 = arg2;
                    132: 
                    133:        usrarg3 = arg3;
                    134: 
                    135:        usrarg4 = arg4;
                    136: 
                    137:        usrarg5 = arg5;
                    138: 
                    139:        curproc->sighandle[0] = (long)do_usrcall;
                    140: 
                    141:        savesr = syscall->sr;   /* save old super/user mode flag */
                    142: 
                    143:        syscall->sr |= 0x2000;  /* set supervisor mode */
                    144: 
                    145:        handle_sig(0);          /* actually call out to the user function */
                    146: 
                    147:        syscall->sr = savesr;
                    148: 
                    149: 
                    150: 
                    151: /* do_usrcall saves the user's return value in usrret */
                    152: 
                    153:        return usrret;
                    154: 
                    155: }
                    156: 
                    157: 
                    158: 
                    159: 
                    160: 
                    161: /*
                    162: 
                    163:  * midiws: we have to replace this, because it's possible that the process'
                    164: 
                    165:  * view of what the MIDI port is has been changed by Fforce or Fmidipipe
                    166: 
                    167:  */
                    168: 
                    169: 
                    170: 
1.1.1.2 ! root      171: long ARGS_ON_STACK
1.1       root      172: 
                    173: midiws(cnt, buf)
                    174: 
                    175:        int cnt;
                    176: 
                    177:        const char *buf;
                    178: 
                    179: {
                    180: 
                    181:        FILEPTR *f;
                    182: 
                    183:        long towrite = cnt+1;
                    184: 
                    185: 
                    186: 
                    187:        f = curproc->handle[-5];        /* MIDI output handle */
                    188: 
                    189:        if (!f) return EIHNDL;
                    190: 
                    191: 
                    192: 
                    193:        if (is_terminal(f)) {
                    194: 
                    195:                while (cnt >= 0) {
                    196: 
                    197:                        tty_putchar(f, (long)*buf, RAW);
                    198: 
                    199:                        buf++; cnt--;
                    200: 
                    201:                }
                    202: 
                    203:                return towrite;
                    204: 
                    205:        }
                    206: 
                    207:        return (*f->dev->write)(f, buf, towrite);
                    208: 
                    209: }
                    210: 
                    211: 
                    212: 
                    213: /*
                    214: 
                    215:  * Modem control things: these are replaced because we handle
                    216: 
                    217:  * Bconmap ourselves
                    218: 
                    219:  */
                    220: 
                    221: 
                    222: 
                    223: /* mapin: utility routine, does a Bconmap and keeps track
                    224: 
                    225:  * so we call the kernel only when necessary; call this
                    226: 
                    227:  * only if has_bconmap is "true".
                    228: 
                    229:  * Returns: 0 on failure, 1 on success.
                    230: 
                    231:  */
                    232: 
                    233: int curbconmap;
                    234: 
                    235: 
                    236: 
                    237: int
                    238: 
                    239: mapin(dev)
                    240: 
                    241:        int dev;
                    242: 
                    243: {
                    244: 
1.1.1.2 ! root      245:        long r;
1.1       root      246: 
                    247: 
                    248: 
                    249:        if (dev == curbconmap)
                    250: 
                    251:                return 1;
                    252: 
                    253:        r = Bconmap(dev);
                    254: 
                    255:        if (r) {
                    256: 
                    257:                curbconmap = dev;
                    258: 
                    259:                return 1;
                    260: 
                    261:        }
                    262: 
                    263:        return 0;
                    264: 
                    265: }
                    266: 
                    267:        
                    268: 
1.1.1.2 ! root      269: long ARGS_ON_STACK
1.1       root      270: 
                    271: uiorec(dev)
                    272: 
                    273:        int dev;
                    274: 
                    275: {
                    276: 
1.1.1.2 ! root      277:        TRACE(("Iorec(%d)", dev));
1.1       root      278: 
                    279:        if (dev == 0 && has_bconmap)
                    280: 
                    281:                mapin(curproc->bconmap);
                    282: 
                    283:        return (long)Iorec(dev);
                    284: 
                    285: }
                    286: 
                    287: 
                    288: 
1.1.1.2 ! root      289: long ARGS_ON_STACK
1.1       root      290: 
                    291: rsconf(baud, flow, uc, rs, ts, sc)
                    292: 
                    293:        int baud, flow, uc, rs, ts, sc;
                    294: 
                    295: {
                    296: 
1.1.1.2 ! root      297:        static int oldbaud = -1;
1.1       root      298: 
1.1.1.2 ! root      299:        int ret_oldbaud = 0;
        !           300: 
        !           301:        long rsval;
        !           302: 
        !           303:        IOREC_T *ior;
        !           304: 
        !           305: 
        !           306: 
        !           307:        TRACE(("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
        !           308: 
        !           309:                uc, rs, ts, sc));
1.1       root      310: 
                    311: 
                    312: 
                    313:        if (has_bconmap)
                    314: 
                    315:                mapin(curproc->bconmap);
                    316: 
1.1.1.2 ! root      317:        else if (tosvers < 0x0104) {
        !           318: 
        !           319: /*
        !           320: 
        !           321:   If this is an old TOS, try to rearrange things to support
        !           322: 
        !           323:   the following Rsconf() features:
        !           324: 
        !           325:        1. Rsconf(-2, ...) does not return current baud (it crashes)
        !           326: 
        !           327:                -> keep track of old speed in static variable
        !           328: 
        !           329:        2. Rsconf(b, ...) sends ASCII DEL to the modem unless b == -1
        !           330: 
        !           331:                -> make speed parameter -1 if new speed matches old speed
        !           332: 
        !           333:        3. Rsconf() discards any buffered output
        !           334: 
        !           335:                -> use Iorec() to ensure all buffered data was sent before call
        !           336: 
        !           337: */
        !           338: 
        !           339:                if (baud == -2) {
        !           340: 
        !           341:                        ret_oldbaud = 1;
        !           342: 
        !           343:                        baud = -1;
        !           344: 
        !           345:                } else if (baud == oldbaud)
        !           346: 
        !           347:                        baud = -1;
        !           348: 
        !           349:                else if (baud > -1)
        !           350: 
        !           351:                        oldbaud = baud;
        !           352: 
        !           353:                ior = ((IOREC_T *) uiorec(0)) + 1; /* output record */
        !           354: 
        !           355:                while (ior->head != ior->tail) {
        !           356: 
        !           357:                        TRACE(("Rsconf() napping until transmit buf empty"));
        !           358: 
        !           359:                        nap(200);
        !           360: 
        !           361:                }
        !           362: 
        !           363:        }
        !           364: 
        !           365:        rsval = Rsconf(baud, flow, uc, rs, ts, sc);
        !           366: 
        !           367:        if (ret_oldbaud)
        !           368: 
        !           369:                rsval = (long) oldbaud;
        !           370: 
        !           371:        return rsval;
1.1       root      372: 
                    373: }
                    374: 
                    375: 
                    376: 
1.1.1.2 ! root      377: long ARGS_ON_STACK
1.1       root      378: 
                    379: bconmap(dev)
                    380: 
                    381:        int dev;
                    382: 
                    383: {
                    384: 
                    385:        int old = curproc->bconmap;
                    386: 
                    387: 
                    388: 
1.1.1.2 ! root      389:        TRACE(("Bconmap(%d)", dev));
1.1       root      390: 
                    391: 
                    392: 
                    393:        if (has_bconmap) {
                    394: 
                    395:                if (dev == -1) return old;
                    396: 
                    397:                if (dev == -2) return Bconmap(-2);
                    398: 
1.1.1.2 ! root      399:                if (dev == 0) return 0;  /* the user's just testing */
        !           400: 
1.1       root      401:                if (mapin(dev) == 0) {
                    402: 
1.1.1.2 ! root      403:                        DEBUG(("Bconmap: mapin(%d) failed", dev));
1.1       root      404: 
                    405:                        return 0;
                    406: 
                    407:                }
                    408: 
                    409:                if (set_auxhandle(curproc, dev) == 0) {
                    410: 
1.1.1.2 ! root      411:                        DEBUG(("Bconmap: Couldn't change AUX:"));
1.1       root      412: 
                    413:                        return 0;
                    414: 
                    415:                }
                    416: 
                    417:                curproc->bconmap = dev;
                    418: 
                    419:                return old;
                    420: 
                    421:        }
                    422: 
                    423:        return EINVFN;  /* no Bconmap available */
                    424: 
                    425: }
                    426: 
                    427: 
                    428: 
1.1.1.2 ! root      429: /*
        !           430: 
        !           431:  * cursconf(): this gets converted into an ioctl() call on
        !           432: 
        !           433:  * the appropriate device
        !           434: 
        !           435:  */
        !           436: 
        !           437: 
        !           438: 
        !           439: long ARGS_ON_STACK
        !           440: 
        !           441: cursconf(cmd, op)
        !           442: 
        !           443:        int cmd, op;
        !           444: 
        !           445: {
        !           446: 
        !           447:        FILEPTR *f;
        !           448: 
        !           449: 
        !           450: 
        !           451:        f = curproc->handle[-1];
        !           452: 
        !           453:        if (!f || !is_terminal(f))
        !           454: 
        !           455:                return EINVFN;
        !           456: 
        !           457:        return
        !           458: 
        !           459:          (*f->dev->ioctl)(f, TCURSOFF+cmd, &op);
        !           460: 
        !           461: }
        !           462: 
        !           463: 
        !           464: 
1.1       root      465: void
                    466: 
                    467: init_xbios()
                    468: 
                    469: {
                    470: 
1.1.1.2 ! root      471:        curbconmap = (has_bconmap) ? (int) Bconmap(-1) : 1;
1.1       root      472: 
                    473: 
                    474: 
                    475:        xbios_tab[0x0c] = midiws;
                    476: 
                    477:        xbios_tab[0x0e] = uiorec;
                    478: 
                    479:        xbios_tab[0x0f] = rsconf;
                    480: 
1.1.1.2 ! root      481:        xbios_tab[0x15] = cursconf;
        !           482: 
1.1       root      483:        xbios_tab[0x26] = supexec;
                    484: 
                    485:        xbios_tab[0x2c] = bconmap;
                    486: 
                    487: }
                    488: 

unix.superglobalmegacorp.com

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