Annotation of hatari/src/debug/natfeats.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Hatari - natfeats.c
                      3:  * 
                      4:  * Copyright (C) 2012 by Eero Tamminen
                      5:  *
                      6:  * This file is distributed under the GNU General Public License, version 2
                      7:  * or at your option any later version. Read the file gpl.txt for details.
                      8:  *
                      9:  * natfeats.c - Hatari Native features identification and call forwarding,
                     10:  * modeleted after similar code in Aranym (written by Petr Stehlik),
                     11:  * specified here:
                     12:  *     http://wiki.aranym.org/natfeats/proposal
                     13:  */
                     14: const char Natfeats_fileid[] = "Hatari natfeats.c : " __DATE__ " " __TIME__;
                     15: 
                     16: #include <stdio.h>
                     17: #include "main.h"
                     18: #include "version.h"
                     19: #include "configuration.h"
                     20: #include "stMemory.h"
                     21: #include "m68000.h"
                     22: #include "natfeats.h"
                     23: 
                     24: #define NF_DEBUG 1
                     25: #if NF_DEBUG
                     26: # define Dprintf(a) printf a
                     27: #else
                     28: # define Dprintf(a)
                     29: #endif
                     30: 
                     31: /* TODO:
                     32:  * - supervisor vs. user stack handling?
                     33:  * - clipboard and hostfs native features?
                     34:  */
                     35: 
                     36: 
                     37: static bool nf_name(Uint32 stack, Uint32 subid, Uint32 *retval)
                     38: {
                     39:        Uint32 ptr, len;
                     40:        const char *str;
                     41:        char *buf;
                     42: 
                     43:        ptr = STMemory_ReadLong(stack);
                     44:        len = STMemory_ReadLong(stack + SIZE_LONG);
                     45:        Dprintf(("NF name[%d](0x%x, %d)\n", subid, ptr, len));
                     46: 
                     47:        if (!STMemory_ValidArea(ptr, len)) {
                     48:                M68000_BusError(ptr, BUS_ERROR_WRITE);
                     49:                return false;
                     50:        }
                     51:        if (subid) {
                     52:                str = PROG_NAME;
                     53:        } else {
                     54:                str = "Hatari";
                     55:        }
                     56:        buf = (char *)STRAM_ADDR(ptr);
                     57:        *retval = snprintf(buf, len, "%s", str);
                     58:        return true;
                     59: }
                     60: 
                     61: static bool nf_version(Uint32 stack, Uint32 subid, Uint32 *retval)
                     62: {
                     63:        Dprintf(("NF version() -> 0x00010000\n"));
                     64:        *retval = 0x00010000;
                     65:        return true;
                     66: }
                     67: 
                     68: static bool nf_stderr(Uint32 stack, Uint32 subid, Uint32 *retval)
                     69: {
                     70:        const char *str;
                     71:        Uint32 ptr;
                     72: 
                     73:        ptr = STMemory_ReadLong(stack);
                     74:        //Dprintf(("NF stderr(0x%x)\n", ptr));
                     75: 
                     76:        if (!STMemory_ValidArea(ptr, 1)) {
                     77:                M68000_BusError(ptr, BUS_ERROR_READ);
                     78:                return false;
                     79:        }
                     80:        str = (const char *)STRAM_ADDR(ptr);
                     81:        *retval = fprintf(stderr, "%s", str);
                     82:        fflush(stderr);
                     83:        return true;
                     84: }
                     85: 
                     86: static bool nf_shutdown(Uint32 stack, Uint32 subid, Uint32 *retval)
                     87: {
                     88:        Dprintf(("NF shutdown()\n"));
                     89:        ConfigureParams.Log.bConfirmQuit = false;
                     90:        Main_RequestQuit();
                     91:        return true;
                     92: }
                     93: 
                     94: /* ---------------------------- */
                     95: 
                     96: #define FEATNAME_MAX 16
                     97: 
                     98: static const struct {
                     99:        const char *name;       /* feature name */
                    100:        bool super;             /* should be called only in supervisor mode */
                    101:        bool (*cb)(Uint32 stack, Uint32 subid, Uint32 *retval);
                    102: } features[] = {
                    103:        { "NF_NAME",     false, nf_name },
                    104:        { "NF_VERSION",  false, nf_version },
                    105:        { "NF_STDERR",   false, nf_stderr },
                    106:        { "NF_SHUTDOWN", true,  nf_shutdown }
                    107: };
                    108: 
                    109: /* macros from Aranym */
                    110: #define ID_SHIFT        20
                    111: #define IDX2MASTERID(idx)       (((idx)+1) << ID_SHIFT)
                    112: #define MASTERID2IDX(id)        (((id) >> ID_SHIFT)-1)
                    113: #define MASKOUTMASTERID(id)     ((id) & ((1L << ID_SHIFT)-1))
                    114: 
                    115: 
                    116: /**
                    117:  * Set retval to internal ID for requested Native Feature,
                    118:  * or zero if feature is unknown/unsupported.
                    119:  * 
                    120:  * Return true if caller is to proceed normally,
                    121:  * false if there was an exception.
                    122:  */
                    123: bool NatFeat_ID(Uint32 stack, Uint32 *retval)
                    124: {
                    125:        const char *name;
                    126:        Uint32 ptr;
                    127:        int i;
                    128: 
                    129:        ptr = STMemory_ReadLong(stack);
                    130:        if (!STMemory_ValidArea(ptr, FEATNAME_MAX)) {
                    131:                M68000_BusError(ptr, BUS_ERROR_READ);
                    132:                return false;
                    133:        }
                    134: 
                    135:        name = (const char *)STRAM_ADDR(ptr);
                    136:        Dprintf(("NF ID(0x%x)\n", ptr));
                    137:        Dprintf(("   \"%s\"\n", name));
                    138: 
                    139:        for (i = 0; i < ARRAYSIZE(features); i++) {
                    140:                if (strcmp(features[i].name, name) == 0) {
                    141:                        *retval = IDX2MASTERID(i);
                    142:                        return true;
                    143:                }
                    144:        }
                    145:        /* unknown feature */
                    146:        *retval = 0;
                    147:        return true;
                    148: }
                    149: 
                    150: /**
                    151:  * Do given Native Feature, if it is supported
                    152:  * and set 'retval' accordingly.
                    153:  * 
                    154:  * Return true if caller is to proceed normally,
                    155:  * false if there was an exception.
                    156:  */
                    157: bool NatFeat_Call(Uint32 stack, bool super, Uint32 *retval)
                    158: {
                    159:        Uint32 subid = STMemory_ReadLong(stack);
                    160:        unsigned int idx = MASTERID2IDX(subid);
                    161:        subid = MASKOUTMASTERID(subid);
                    162: 
                    163:        if (idx >= ARRAYSIZE(features)) {
                    164:                Dprintf(("ERROR: invalid NF ID %d requested\n", idx));
                    165:                return true; /* undefined */
                    166:        }
                    167:        if (features[idx].super && !super) {
                    168:                Dprintf(("ERROR: NF function %d called without supervisor mode\n", idx));
                    169:                Exception(8, 0, M68000_EXC_SRC_CPU);
                    170:                return false;
                    171:        }
                    172:        stack += SIZE_LONG;
                    173:        return features[idx].cb(stack, subid, retval);
                    174: }

unix.superglobalmegacorp.com

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