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

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: 
1.1.1.3 ! root       59:        if ( !STMemory_CheckAreaType ( ptr, len, ABFLAG_RAM | ABFLAG_ROM ) ) {
        !            60:                M68000_BusError(ptr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1       root       61:                return false;
                     62:        }
                     63:        if (subid) {
                     64:                str = PROG_NAME;
                     65:        } else {
                     66:                str = "Hatari";
                     67:        }
1.1.1.3 ! root       68:        buf = (char *)STMemory_STAddrToPointer ( ptr );
1.1       root       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: 
1.1.1.3 ! root       97:        if ( !STMemory_CheckAreaType ( ptr, 1, ABFLAG_RAM | ABFLAG_ROM ) ) {
        !            98:                M68000_BusError(ptr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1       root       99:                return false;
                    100:        }
1.1.1.3 ! root      101:        str = (const char *)STMemory_STAddrToPointer ( ptr );
1.1       root      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: 
1.1.1.3 ! root      178:        if ( !STMemory_CheckAreaType ( ptr, 1, ABFLAG_RAM | ABFLAG_ROM ) ) {
        !           179:                M68000_BusError(ptr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1.1.2   root      180:                return false;
                    181:        }
1.1.1.3 ! root      182:        buffer = (const char *)STMemory_STAddrToPointer ( ptr );
1.1.1.2   root      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);
1.1.1.3 ! root      232:        if ( !STMemory_CheckAreaType ( ptr, FEATNAME_MAX, ABFLAG_RAM | ABFLAG_ROM ) ) {
        !           233:                M68000_BusError(ptr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1       root      234:                return false;
                    235:        }
                    236: 
1.1.1.3 ! root      237:        name = (const char *)STMemory_STAddrToPointer ( 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.1.3 ! root      270: #ifndef WINUAE_FOR_HATARI
        !           271:                M68000_Exception(8, M68000_EXC_SRC_CPU);
        !           272: #else
        !           273:                M68000_Exception(8, M68000_EXC_SRC_CPU);
        !           274: #endif
1.1       root      275:                return false;
                    276:        }
                    277:        stack += SIZE_LONG;
                    278:        return features[idx].cb(stack, subid, retval);
                    279: }

unix.superglobalmegacorp.com

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