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

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

unix.superglobalmegacorp.com

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