/** * Set retval to internal ID for requested Native Feature, * or zero if feature is unknown/unsupported. * * Return true if caller is to proceed normally, * false if there was an exception. */ bool NatFeat_ID(Uint32 stack, Uint32 *retval) { const char *name; Uint32 ptr; int i; ptr = STMemory_ReadLong(stack); if ( !STMemory_CheckAreaType ( ptr, FEATNAME_MAX, ABFLAG_RAM | ABFLAG_ROM ) ) { M68000_BusError(ptr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA); return false; } name = (const char *)STMemory_STAddrToPointer ( ptr ); LOG_TRACE(TRACE_NATFEATS, "NF ID(0x%x \"%s\")\n", ptr, name); for (i = 0; i < ARRAYSIZE(features); i++) { if (strcmp(features[i].name, name) == 0) { *retval = IDX2MASTERID(i); return true; } } /* unknown feature */ *retval = 0; return true; }
/** * Copy given memory area safely to Atari RAM. * If the memory area isn't fully within RAM, only the valid parts are written. * Useful for all kinds of IO operations. * * addr - destination Atari RAM address * src - source Hatari memory address * len - number of bytes to copy * name - name / description if this memory copy for error messages * * Return true if whole copy was safe / valid. */ bool STMemory_SafeCopy(Uint32 addr, Uint8 *src, unsigned int len, const char *name) { Uint32 end; if ( STMemory_CheckAreaType ( addr, len, ABFLAG_RAM ) ) { memcpy(&STRam[addr], src, len); return true; } Log_Printf(LOG_WARN, "Invalid '%s' RAM range 0x%x+%i!\n", name, addr, len); for (end = addr + len; addr < end; addr++, src++) { if ( STMemory_CheckAreaType ( addr, 1, ABFLAG_RAM ) ) STRam[addr] = *src; } return false; }
/** * NF_STDERR - print string to stderr * Stack arguments are: * - pointer to buffer containing the string */ static bool nf_stderr(Uint32 stack, Uint32 subid, Uint32 *retval) { const char *str; Uint32 ptr; ptr = STMemory_ReadLong(stack); LOG_TRACE(TRACE_NATFEATS, "NF_STDERR(0x%x)\n", ptr); if ( !STMemory_CheckAreaType ( ptr, 1, ABFLAG_RAM | ABFLAG_ROM ) ) { M68000_BusError(ptr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA); return false; } str = (const char *)STMemory_STAddrToPointer ( ptr ); *retval = fprintf(stderr, "%s", str); fflush(stderr); return true; }
/** * NF_COMMAND - execute Hatari (cli / debugger) command * Stack arguments are: * - pointer to command string */ static bool nf_command(Uint32 stack, Uint32 subid, Uint32 *retval) { const char *buffer; Uint32 ptr; ptr = STMemory_ReadLong(stack); if ( !STMemory_CheckAreaType ( ptr, 1, ABFLAG_RAM | ABFLAG_ROM ) ) { M68000_BusError(ptr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA); return false; } buffer = (const char *)STMemory_STAddrToPointer ( ptr ); LOG_TRACE(TRACE_NATFEATS, "NF_COMMAND(0x%x \"%s\")\n", ptr, buffer); Control_ProcessBuffer(buffer); return true; }
/** * NF_NAME - emulator name * Stack arguments are: * - pointer to buffer for emulator name, and * - uint32_t for its size * If subid is set, emulator name includes also version information */ static bool nf_name(Uint32 stack, Uint32 subid, Uint32 *retval) { Uint32 ptr, len; const char *str; char *buf; ptr = STMemory_ReadLong(stack); len = STMemory_ReadLong(stack + SIZE_LONG); LOG_TRACE(TRACE_NATFEATS, "NF_NAME[%d](0x%x, %d)\n", subid, ptr, len); if ( !STMemory_CheckAreaType ( ptr, len, ABFLAG_RAM | ABFLAG_ROM ) ) { M68000_BusError(ptr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA); return false; } if (subid) { str = PROG_NAME; } else { str = "Hatari"; } buf = (char *)STMemory_STAddrToPointer ( ptr ); *retval = snprintf(buf, len, "%s", str); return true; }