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

1.1       root        1: /*
                      2:  * Hatari - natfeats.c
                      3:  * 
1.1.1.2 ! root        4:  * Copyright (C) 2012-2014 by Eero Tamminen
1.1       root        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,
1.1.1.2 ! root       10:  * modeled after similar code in Aranym (written by Petr Stehlik),
1.1       root       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"
1.1.1.2 ! root       23: #include "control.h"
        !            24: #include "log.h"
1.1       root       25: 
1.1.1.2 ! root       26: 
        !            27: /* whether to allow XBIOS(255) style
        !            28:  * Hatari command line parsing with "command" NF
        !            29:  */
        !            30: #define NF_COMMAND 0
1.1       root       31: 
                     32: /* TODO:
                     33:  * - supervisor vs. user stack handling?
                     34:  * - clipboard and hostfs native features?
                     35:  */
                     36: 
                     37: 
1.1.1.2 ! root       38: /* ----------------------------------
        !            39:  * Native Features shared with Aranym
        !            40:  */
        !            41: 
        !            42: /**
        !            43:  * NF_NAME - emulator name
        !            44:  * Stack arguments are:
        !            45:  * - pointer to buffer for emulator name, and
        !            46:  * - uint32_t for its size
        !            47:  * If subid is set, emulator name includes also version information
        !            48:  */
1.1       root       49: static bool nf_name(Uint32 stack, Uint32 subid, Uint32 *retval)
                     50: {
                     51:        Uint32 ptr, len;
                     52:        const char *str;
                     53:        char *buf;
                     54: 
                     55:        ptr = STMemory_ReadLong(stack);
                     56:        len = STMemory_ReadLong(stack + SIZE_LONG);
1.1.1.2 ! root       57:        LOG_TRACE(TRACE_NATFEATS, "NF_NAME[%d](0x%x, %d)\n", subid, ptr, len);
1.1       root       58: 
                     59:        if (!STMemory_ValidArea(ptr, len)) {
                     60:                M68000_BusError(ptr, BUS_ERROR_WRITE);
                     61:                return false;
                     62:        }
                     63:        if (subid) {
                     64:                str = PROG_NAME;
                     65:        } else {
                     66:                str = "Hatari";
                     67:        }
                     68:        buf = (char *)STRAM_ADDR(ptr);
                     69:        *retval = snprintf(buf, len, "%s", str);
                     70:        return true;
                     71: }
                     72: 
1.1.1.2 ! root       73: /**
        !            74:  * NF_VERSION - NativeFeatures version
        !            75:  * returns version number
        !            76:  */
1.1       root       77: static bool nf_version(Uint32 stack, Uint32 subid, Uint32 *retval)
                     78: {
1.1.1.2 ! root       79:        LOG_TRACE(TRACE_NATFEATS, "NF_VERSION() -> 0x00010000\n");
1.1       root       80:        *retval = 0x00010000;
                     81:        return true;
                     82: }
                     83: 
1.1.1.2 ! root       84: /**
        !            85:  * NF_STDERR - print string to stderr
        !            86:  * Stack arguments are:
        !            87:  * - pointer to buffer containing the string
        !            88:  */
1.1       root       89: static bool nf_stderr(Uint32 stack, Uint32 subid, Uint32 *retval)
                     90: {
                     91:        const char *str;
                     92:        Uint32 ptr;
                     93: 
                     94:        ptr = STMemory_ReadLong(stack);
1.1.1.2 ! root       95:        LOG_TRACE(TRACE_NATFEATS, "NF_STDERR(0x%x)\n", ptr);
1.1       root       96: 
                     97:        if (!STMemory_ValidArea(ptr, 1)) {
                     98:                M68000_BusError(ptr, BUS_ERROR_READ);
                     99:                return false;
                    100:        }
                    101:        str = (const char *)STRAM_ADDR(ptr);
                    102:        *retval = fprintf(stderr, "%s", str);
                    103:        fflush(stderr);
                    104:        return true;
                    105: }
                    106: 
1.1.1.2 ! root      107: /**
        !           108:  * NF_SHUTDOWN - exit emulator normally
        !           109:  * Needs to be called from supervisor mode
        !           110:  */
1.1       root      111: static bool nf_shutdown(Uint32 stack, Uint32 subid, Uint32 *retval)
                    112: {
1.1.1.2 ! root      113:        LOG_TRACE(TRACE_NATFEATS, "NF_SHUTDOWN()\n");
1.1       root      114:        ConfigureParams.Log.bConfirmQuit = false;
1.1.1.2 ! root      115:        Main_RequestQuit(0);
1.1       root      116:        return true;
                    117: }
                    118: 
1.1.1.2 ! root      119: /* ----------------------------------
        !           120:  * Native Features specific to Hatari
        !           121:  */
        !           122: 
        !           123: /**
        !           124:  * NF_EXIT - exit emulator with given exit code
        !           125:  * Stack arguments are:
        !           126:  * - emulator's int32_t exit value
        !           127:  */
        !           128: static bool nf_exit(Uint32 stack, Uint32 subid, Uint32 *retval)
        !           129: {
        !           130:        Sint32 exitval;
        !           131: 
        !           132:        ConfigureParams.Log.bConfirmQuit = false;
        !           133:        exitval = STMemory_ReadLong(stack);
        !           134:        LOG_TRACE(TRACE_NATFEATS, "NF_EXIT(%d)\n", exitval);
        !           135:        Main_RequestQuit(exitval);
        !           136:        return true;
        !           137: }
        !           138: 
        !           139: /**
        !           140:  * NF_DEBUGGER - invoke debugger
        !           141:  */
        !           142: static bool nf_debugger(Uint32 stack, Uint32 subid, Uint32 *retval)
        !           143: {
        !           144:        LOG_TRACE(TRACE_NATFEATS, "NF_DEBUGGER()\n");
        !           145:        M68000_SetSpecial(SPCFLAG_DEBUGGER);
        !           146:        return true;
        !           147: }
        !           148: 
        !           149: /**
        !           150:  * NF_FASTFORWARD - set fast forward state
        !           151:  * Stack arguments are:
        !           152:  * - state 0: off, >=1: on
        !           153:  */
        !           154: static bool nf_fastforward(Uint32 stack, Uint32 subid, Uint32 *retval)
        !           155: {
        !           156:        Uint32 val;
        !           157: 
        !           158:        val = STMemory_ReadLong(stack);
        !           159:        *retval = ConfigureParams.System.bFastForward;
        !           160:        LOG_TRACE(TRACE_NATFEATS, "NF_FASTFORWARD(%d -> %d)\n", *retval, val);
        !           161:        ConfigureParams.System.bFastForward = ( val ? true : false );
        !           162:        return true;
        !           163: }
        !           164: 
        !           165: #if NF_COMMAND
        !           166: /**
        !           167:  * NF_COMMAND - execute Hatari (cli / debugger) command
        !           168:  * Stack arguments are:
        !           169:  * - pointer to command string
        !           170:  */
        !           171: static bool nf_command(Uint32 stack, Uint32 subid, Uint32 *retval)
        !           172: {
        !           173:        const char *buffer;
        !           174:        Uint32 ptr;
        !           175: 
        !           176:        ptr = STMemory_ReadLong(stack);
        !           177: 
        !           178:        if (!STMemory_ValidArea(ptr, 1)) {
        !           179:                M68000_BusError(ptr, BUS_ERROR_READ);
        !           180:                return false;
        !           181:        }
        !           182:        buffer = (const char *)STRAM_ADDR(ptr);
        !           183:        LOG_TRACE(TRACE_NATFEATS, "NF_COMMAND(0x%x \"%s\")\n", ptr, buffer);
        !           184: 
        !           185:        Control_ProcessBuffer(buffer);
        !           186:        return true;
        !           187: }
        !           188: #endif
        !           189: 
1.1       root      190: /* ---------------------------- */
                    191: 
                    192: #define FEATNAME_MAX 16
                    193: 
                    194: static const struct {
                    195:        const char *name;       /* feature name */
                    196:        bool super;             /* should be called only in supervisor mode */
                    197:        bool (*cb)(Uint32 stack, Uint32 subid, Uint32 *retval);
                    198: } features[] = {
1.1.1.2 ! root      199: #if NF_COMMAND
        !           200:        { "NF_COMMAND",  false, nf_command },
        !           201: #endif
1.1       root      202:        { "NF_NAME",     false, nf_name },
                    203:        { "NF_VERSION",  false, nf_version },
                    204:        { "NF_STDERR",   false, nf_stderr },
1.1.1.2 ! root      205:        { "NF_SHUTDOWN", true,  nf_shutdown },
        !           206:        { "NF_EXIT",     false, nf_exit },
        !           207:        { "NF_DEBUGGER", false, nf_debugger },
        !           208:        { "NF_FASTFORWARD", false,  nf_fastforward }
1.1       root      209: };
                    210: 
                    211: /* macros from Aranym */
                    212: #define ID_SHIFT        20
                    213: #define IDX2MASTERID(idx)       (((idx)+1) << ID_SHIFT)
                    214: #define MASTERID2IDX(id)        (((id) >> ID_SHIFT)-1)
                    215: #define MASKOUTMASTERID(id)     ((id) & ((1L << ID_SHIFT)-1))
                    216: 
                    217: 
                    218: /**
                    219:  * Set retval to internal ID for requested Native Feature,
                    220:  * or zero if feature is unknown/unsupported.
                    221:  * 
                    222:  * Return true if caller is to proceed normally,
                    223:  * false if there was an exception.
                    224:  */
                    225: bool NatFeat_ID(Uint32 stack, Uint32 *retval)
                    226: {
                    227:        const char *name;
                    228:        Uint32 ptr;
                    229:        int i;
                    230: 
                    231:        ptr = STMemory_ReadLong(stack);
                    232:        if (!STMemory_ValidArea(ptr, FEATNAME_MAX)) {
                    233:                M68000_BusError(ptr, BUS_ERROR_READ);
                    234:                return false;
                    235:        }
                    236: 
                    237:        name = (const char *)STRAM_ADDR(ptr);
1.1.1.2 ! root      238:        LOG_TRACE(TRACE_NATFEATS, "NF ID(0x%x \"%s\")\n", ptr, name);
1.1       root      239: 
                    240:        for (i = 0; i < ARRAYSIZE(features); i++) {
                    241:                if (strcmp(features[i].name, name) == 0) {
                    242:                        *retval = IDX2MASTERID(i);
                    243:                        return true;
                    244:                }
                    245:        }
                    246:        /* unknown feature */
                    247:        *retval = 0;
                    248:        return true;
                    249: }
                    250: 
                    251: /**
                    252:  * Do given Native Feature, if it is supported
                    253:  * and set 'retval' accordingly.
                    254:  * 
                    255:  * Return true if caller is to proceed normally,
                    256:  * false if there was an exception.
                    257:  */
                    258: bool NatFeat_Call(Uint32 stack, bool super, Uint32 *retval)
                    259: {
                    260:        Uint32 subid = STMemory_ReadLong(stack);
                    261:        unsigned int idx = MASTERID2IDX(subid);
                    262:        subid = MASKOUTMASTERID(subid);
                    263: 
                    264:        if (idx >= ARRAYSIZE(features)) {
1.1.1.2 ! root      265:                LOG_TRACE(TRACE_NATFEATS, "ERROR: invalid NF ID %d requested\n", idx);
1.1       root      266:                return true; /* undefined */
                    267:        }
                    268:        if (features[idx].super && !super) {
1.1.1.2 ! root      269:                LOG_TRACE(TRACE_NATFEATS, "ERROR: NF function %d called without supervisor mode\n", idx);
1.1       root      270:                Exception(8, 0, M68000_EXC_SRC_CPU);
                    271:                return false;
                    272:        }
                    273:        stack += SIZE_LONG;
                    274:        return features[idx].cb(stack, subid, retval);
                    275: }

unix.superglobalmegacorp.com

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