void ATrap::SetNewDReg (int regNum, uint32 value) { m68k_dreg (fNewRegisters, regNum) = value; }
static uae_u32 hardfile_beginio (void) { uae_u32 tmp1, tmp2, dataptr, offset; uae_u32 retval = m68k_dreg(regs, 0); int unit; struct hardfiledata *hfd; tmp1 = m68k_areg(regs, 1); unit = get_long (tmp1 + 24); #undef DEBUGME #ifdef DEBUGME printf ("hardfile: unit = %d\n", unit); printf ("hardfile: tmp1 = %08lx\n", (unsigned long)tmp1); printf ("hardfile: cmd = %d\n", (int)get_word(tmp1+28)); #endif hfd = get_hardfile_data (unit); put_byte (tmp1+8, NT_MESSAGE); put_byte (tmp1+31, 0); /* no error yet */ tmp2 = get_word (tmp1+28); /* io_Command */ /* put_byte (tmp1 + 30, get_byte (tmp1 + 30) & ~1);*/ switch (tmp2) { case CMD_READ: gui_data.hdled = HDLED_READ; dataptr = get_long (tmp1 + 40); if (dataptr & 1) goto bad_command; offset = get_long (tmp1 + 44); if (offset & 511) goto bad_command; tmp2 = get_long (tmp1 + 36); /* io_Length */ if (tmp2 & 511) goto bad_command; if (tmp2 + offset > (uae_u32)hfd->size) goto bad_command; put_long (tmp1 + 32, tmp2); /* set io_Actual */ #ifdef __SYMBIAN32__ lseek (fileno(hfd->fd), offset, SEEK_SET); #else fseek (hfd->fd, offset, SEEK_SET); #endif while (tmp2) { int i; char buffer[512]; #ifdef __SYMBIAN32__ /* See the comment in CMD_WRITE */ read (fileno(hfd->fd), buffer, 512); #else fread (buffer, 1, 512, hfd->fd); #endif for (i = 0; i < 512; i++, dataptr++) put_byte(dataptr, buffer[i]); tmp2 -= 512; } break; case CMD_WRITE: case 11: /* Format */ gui_data.hdled = HDLED_WRITE; dataptr = get_long (tmp1 + 40); if (dataptr & 1) goto bad_command; offset = get_long (tmp1 + 44); if (offset & 511) goto bad_command; tmp2 = get_long (tmp1 + 36); /* io_Length */ if (tmp2 & 511) goto bad_command; if (tmp2 + offset > (uae_u32)hfd->size) goto bad_command; put_long (tmp1 + 32, tmp2); /* set io_Actual */ #ifdef __SYMBIAN32__ lseek (fileno(hfd->fd), offset, SEEK_SET); #else fseek (hfd->fd, offset, SEEK_SET); #endif while (tmp2) { char buffer[512]; int i; for (i=0; i < 512; i++, dataptr++) buffer[i] = get_byte(dataptr); #ifdef __SYMBIAN32__ /* For some reason, fwrite() *appends* data at the end of the HDF file, * instead of writing it at fseek() offset, even though fopen() was called * with "r+b" parameter, and not "a+"! * write() works correctly. */ write (fileno(hfd->fd), buffer, 512); #else fwrite (buffer, 1, 512, hfd->fd); #endif tmp2 -= 512; } break; bad_command: break; case 18: /* GetDriveType */ printf ("Shouldn't happen\n"); put_long (tmp1 + 32, 1); /* not exactly a 3.5" drive, but... */ break; case 19: /* GetNumTracks */ printf ("Shouldn't happen 2\n"); put_long (tmp1 + 32, 0); break; /* Some commands that just do nothing and return zero */ case CMD_UPDATE: case CMD_CLEAR: case 9: /* Motor */ case 10: /* Seek */ case 12: /* Remove */ case 13: /* ChangeNum */ case 14: /* ChangeStatus */ case 15: /* ProtStatus */ case 20: /* AddChangeInt */ case 21: /* RemChangeInt */ put_long (tmp1+32, 0); /* io_Actual */ retval = 0; break; default: /* Command not understood. */ put_byte (tmp1+31, (uae_u8)-3); /* io_Error */ retval = 0; break; } #if 0 if ((get_byte (tmp1+30) & 1) == 0) { /* Not IOF_QUICK -- need to ReplyMsg */ m68k_areg(regs, 1) = tmp1; CallLib (get_long(4), -378); } #endif return retval; }
void uae_FreeMem (TrapContext *context, uaecptr memory, uae_u32 size) { m68k_dreg (&context->regs, 0) = size; m68k_areg (&context->regs, 1) = memory; CallLib (context, get_long (4), -0xD2); /* FreeMem */ }
uaecptr uae_AllocMem (TrapContext *context, uae_u32 size, uae_u32 flags) { m68k_dreg (&context->regs, 0) = size; m68k_dreg (&context->regs, 1) = flags; return CallLib (context, get_long (4), -198); /* AllocMem */ }
/************************************************************* Display the enforcer hit *************************************************************/ static void enforcer_display_hit (const char *addressmode, uae_u32 pc, uaecptr addr) { uae_u32 a7; uae_u32 sysbase; uae_u32 this_task; uae_u32 task_name; const char *native_task_name; int i, j; static char buf[256], instrcode[256]; static char lines[INSTRUCTIONLINES/2][256]; static uaecptr bestpc_array[INSTRUCTIONLINES/2][5]; static int bestpc_idxs[INSTRUCTIONLINES/2]; char *enforcer_buf_ptr = enforcer_buf; uaecptr bestpc, pospc, nextpc, temppc; if (enforcer_hit) return; /* our function itself generated a hit ;), avoid endless loop */ enforcer_hit = 1; if (!(sysbase = get_long (4))) return; if (!(this_task = get_long (sysbase + 276))) return; task_name = get_long (this_task + 10); /* ln_Name */ native_task_name = (char *) amiga2native (task_name, 100); strcpy (enforcer_buf_ptr, "Enforcer Hit! Bad program\n"); enforcer_buf_ptr += strlen (enforcer_buf_ptr); sprintf (buf, "Illegal %s: %08lx", addressmode, addr); sprintf (enforcer_buf_ptr,"%-48sPC: %0lx\n", buf, pc); enforcer_buf_ptr += strlen (enforcer_buf_ptr); /* Data registers */ sprintf (enforcer_buf_ptr, "Data: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", m68k_dreg (®s, 0), m68k_dreg (®s, 1), m68k_dreg (®s, 2), m68k_dreg (®s, 3), m68k_dreg (®s, 4), m68k_dreg (®s, 5), m68k_dreg (®s, 6), m68k_dreg (®s, 7)); enforcer_buf_ptr += strlen (enforcer_buf_ptr); /* Address registers */ sprintf (enforcer_buf_ptr, "Addr: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", m68k_areg (®s, 0), m68k_areg (®s, 1), m68k_areg (®s, 2), m68k_areg (®s, 3), m68k_areg (®s, 4), m68k_areg (®s, 5), m68k_areg (®s, 6), m68k_areg (®s, 7)); enforcer_buf_ptr += strlen(enforcer_buf_ptr); /* Stack */ a7 = m68k_areg (®s, 7); for (i = 0; i < 8 * STACKLINES; i++) { a7 -= 4; if (!(i % 8)) { strcpy (enforcer_buf_ptr,"Stck:"); enforcer_buf_ptr += strlen (enforcer_buf_ptr); } sprintf (enforcer_buf_ptr," %08lx", get_long (a7)); enforcer_buf_ptr += strlen (enforcer_buf_ptr); if (i%8 == 7) *enforcer_buf_ptr++ = '\n'; } /* Segtracker output */ a7 = m68k_areg (®s, 7); if (get_long (a7-4) != pc) { if (enforcer_decode_hunk_and_offset (buf, pc)) { strcpy (enforcer_buf_ptr, buf); enforcer_buf_ptr += strlen (enforcer_buf_ptr); } } for (i = 0; i < 8 * STACKLINES; i++) { a7 -= 4; if (enforcer_decode_hunk_and_offset (buf, get_long (a7))) { int l = strlen (buf); if (ENFORCER_BUF_SIZE - (enforcer_buf_ptr - enforcer_buf) > l + 256) { strcpy(enforcer_buf_ptr, buf); enforcer_buf_ptr += l; } } } /* Decode the instructions around the pc where the enforcer hit was caused. * * At first, the area before the pc, this not always done correctly because * it's done backwards */ temppc = pc; memset (bestpc_array, 0, sizeof (bestpc_array)); for (i = 0; i < INSTRUCTIONLINES / 2; i++) bestpc_idxs[i] = -1; for (i = 0; i < INSTRUCTIONLINES / 2; i++) { pospc = temppc; bestpc = 0; if (bestpc_idxs[i] == -1) { for (j = 0; j < 5; j++) { pospc -= 2; sm68k_disasm (buf, NULL, pospc, &nextpc); if (nextpc == temppc) { bestpc_idxs[i] = j; bestpc_array[i][j] = bestpc = pospc; } } } else { bestpc = bestpc_array[i][bestpc_idxs[i]]; } if (!bestpc) { /* there was no best pc found, so it is high probable that * a former used best pc was wrong. * * We trace back and use the former best pc instead */ int former_idx; int leave = 0; do { if (!i) { leave = 1; break; } i--; former_idx = bestpc_idxs[i]; bestpc_idxs[i] = -1; bestpc_array[i][former_idx] = 0; for (j = former_idx - 1; j >= 0; j--) { if (bestpc_array[i][j]) { bestpc_idxs[i] = j; break; } } } while (bestpc_idxs[i] == -1); if (leave) break; if (i) temppc = bestpc_array[i-1][bestpc_idxs[i-1]]; else temppc = pc; i--; /* will be increased in after continue */ continue; } sm68k_disasm (buf, instrcode, bestpc, NULL); sprintf (lines[i], "%08lx : %-20s %s\n", bestpc, instrcode, buf); temppc = bestpc; } i--; for (; i>=0; i--) { strcpy (enforcer_buf_ptr,lines[i]); enforcer_buf_ptr += strlen (enforcer_buf_ptr); } /* Now the instruction after the pc including the pc */ temppc = pc; for (i=0; i < (INSTRUCTIONLINES+1) / 2; i++) { sm68k_disasm (buf, instrcode, temppc, &nextpc); sprintf (enforcer_buf_ptr, "%08lx : %s %-20s %s\n", temppc, (i == 0 ? "*" : " "), instrcode, buf); enforcer_buf_ptr += strlen (enforcer_buf_ptr); temppc = nextpc; } if (!native_task_name) native_task_name = "Unknown"; sprintf (enforcer_buf_ptr, "Name: \"%s\"\n\n", native_task_name); enforcer_buf_ptr += strlen (enforcer_buf_ptr); console_out (enforcer_buf); write_log (enforcer_buf); enforcer_hit = 0; flashscreen = 30; }
uae_u32 uaenative_call_function (TrapContext *context, int flags) { if (!currprefs.native_code) { return UNI_ERROR_NOT_ENABLED; } struct uni uni; uni.function = m68k_areg (regs, 0); if (flags & UNI_FLAG_COMPAT) { uni.library = 0; #ifdef AHI uni.uaevar_compat = uaenative_get_uaevar(); #else uni.uaevar_compat = NULL; #endif } else if (flags & UNI_FLAG_NAMED_FUNCTION) { uni.library = m68k_dreg (regs, 0); } else { uni.library = 0; } struct library_data *library_data; if (uni.library) { // library handle given, function is pointer to function name const char *function = (const char *) get_real_address (uni.function); library_data = get_library_data_from_handle (uni.library); if (library_data == NULL) { write_log (_T("uni: get_function - invalid library (%d)\n"), uni.library); return UNI_ERROR_INVALID_LIBRARY; } uni.native_function = dl_symbol (library_data->dl_handle, function); if (uni.native_function == NULL) { write_log (_T("uni: get_function - function (%s) not found ") _T("in library %d (%p)\n"), function, uni.library, library_data->dl_handle); return UNI_ERROR_FUNCTION_NOT_FOUND; } } else { // library handle not given, function argument is function handle int index = uni.function - (uae_u32) 0x80000000; if (index >= 0 && index <= g_max_handle) { uni.native_function = g_handles[index].function; library_data = g_handles[index].library; } else { uni.native_function = NULL; } if (uni.native_function == NULL) { // printf ("UNI_ERROR_INVALID_FUNCTION\n"); return UNI_ERROR_INVALID_FUNCTION; } } if (context == NULL) { // we have no context and cannot call into m68k space flags &= ~UNI_FLAG_ASYNCHRONOUS; } uni.d1 = m68k_dreg (regs, 1); uni.d2 = m68k_dreg (regs, 2); uni.d3 = m68k_dreg (regs, 3); uni.d4 = m68k_dreg (regs, 4); uni.d5 = m68k_dreg (regs, 5); uni.d6 = m68k_dreg (regs, 6); uni.d7 = m68k_dreg (regs, 7); uni.a1 = m68k_areg (regs, 1); uni.a2 = m68k_areg (regs, 2); uni.a3 = m68k_areg (regs, 3); uni.a4 = m68k_areg (regs, 4); uni.a5 = m68k_areg (regs, 5); uni.a7 = m68k_areg (regs, 7); uni.flags = flags; uni.error = 0; if (flags & UNI_FLAG_ASYNCHRONOUS) { uaecptr sysbase = get_long (4); uni.task = get_long (sysbase + 276); // ThisTask // make sure signal bit is cleared m68k_dreg (regs, 0) = 0; m68k_dreg (regs, 1) = 1 << SIGBIT; CallLib (context, sysbase, -0x132); // SetSignal // start thread if necessary if (!library_data->thread_id) { uae_sem_init (&library_data->full_count, 0, 0); // we don't have a queue as such, the thread only processes // one item at a time with a "queue size" of 1 uae_sem_init (&library_data->empty_count, 0, 1); uae_start_thread (_T("uaenative"), uaenative_thread, library_data, &library_data->thread_id); } // signal async thread to process new function call uae_sem_wait(&library_data->empty_count); library_data->uni = &uni; uae_sem_post(&library_data->full_count); // wait for signal m68k_dreg (regs, 0) = 1 << SIGBIT; CallLib (context, sysbase, -0x13e); // Wait write_log (_T("uni: -- Got async result --\n")); } else { // synchronous mode, just call the function here and now do_call_function(&uni); } return uni.result; }