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

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

unix.superglobalmegacorp.com

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