1 /* 2 * TilEm II 3 * 4 * Copyright (c) 2011 Benjamin Moody 5 * 6 * This program is free software: you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation, either version 3 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 /* IMPORTANT: The following functions may ONLY be used within 21 tilem_em_main() or a task function, and must be called while 22 holding the emulator lock. */ 23 24 #define TILEM_EM_ALWAYS_FF 0xffffffff 25 26 /* Run one iteration of the emulator. LINKMODE is the link port 27 emulation mode. EVENTS is a mask of events we are interested in; 28 emulation will stop early if any of these events occur, or possibly 29 for other reasons (e.g., a breakpoint being hit.) 30 31 FF_EVENTS is a mask of events we want to fast-forward through 32 (i.e., not apply speed limiting even if enabled.) If FF_EVENTS is 33 set to the constant ALWAYS_FF, speed limiting is completely 34 disabled. 35 36 If KEEP_AWAKE is FALSE and the calculator CPU is turned off, this 37 function may block until another thread wakes it up; in that case, 38 no timer events will be triggered, and the elapsed time cannot be 39 measured in any meaningful way. If KEEP_AWAKE is TRUE, the 40 emulator continues running even when the CPU is turned off. 41 42 TIMEOUT is the length of time (microseconds) to run the emulator. 43 If ELAPSED is non-null, *ELAPSED will be set to the actual number 44 of microseconds elapsed. 45 46 The return value is a mask indicating which of the requested events 47 occurred. */ 48 dword tilem_em_run(TilemCalcEmulator *emu, int linkmode, 49 dword events, dword ff_events, gboolean keep_awake, 50 int timeout, int *elapsed); 51 52 /* Main loop */ 53 gpointer tilem_em_main(gpointer data); 54 55 /* Run the calculator for a short time. */ 56 void tilem_em_delay(TilemCalcEmulator *emu, int timeout, gboolean ff); 57 58 /* Send a byte to the calculator. */ 59 int tilem_em_send_byte(TilemCalcEmulator *emu, unsigned value, 60 int timeout, gboolean ff); 61 62 /* Receive a byte from the calculator. */ 63 int tilem_em_get_byte(TilemCalcEmulator *emu, int timeout, gboolean ff); 64 65 /* Wake up calculator if currently turned off. */ 66 void tilem_em_wake_up(TilemCalcEmulator *emu, gboolean ff); 67 68 /* Set progress window title. Set TITLE to NULL to disable progress 69 window. */ 70 void tilem_em_set_progress_title(TilemCalcEmulator *emu, const char *title); 71 72 /* Set current progress information. FRAC is the estimated fraction 73 of the task completed; STATUS is a text description of the current 74 operation. */ 75 void tilem_em_set_progress(TilemCalcEmulator *emu, gdouble frac, 76 const char *status); 77 78 /* Lock emulator. */ 79 #define tilem_em_lock(emu) \ 80 g_mutex_lock(emu->calc_mutex) 81 82 /* Unlock temporarily if another thread is waiting. */ 83 #define tilem_em_check_yield(emu) \ 84 do { \ 85 if (g_atomic_int_get(&emu->calc_lock_waiting)) \ 86 g_cond_wait(emu->calc_wakeup_cond, emu->calc_mutex); \ 87 } while (0) 88 89 /* Unlock emulator. */ 90 #define tilem_em_unlock(emu) \ 91 do { \ 92 tilem_em_check_yield(emu); \ 93 g_mutex_unlock(emu->calc_mutex); \ 94 } while (0) 95 96