ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp
(Generate patch)

Comparing SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp (file contents):
Revision 1.45 by gbeauche, 2004-06-22T14:18:35Z vs.
Revision 1.52 by gbeauche, 2004-11-13T14:09:16Z

# Line 43 | Line 43
43   #include <stdio.h>
44   #include <stdlib.h>
45  
46 + #ifdef USE_SDL_VIDEO
47 + #include <SDL_events.h>
48 + #endif
49 +
50   #if ENABLE_MON
51   #include "mon.h"
52   #include "mon_disass.h"
# Line 101 | Line 105 | const uint32 POWERPC_EXEC_RETURN = POWER
105   // Interrupts in native mode?
106   #define INTERRUPTS_IN_NATIVE_MODE 1
107  
104 // Enable native EMUL_OPs to be run without a mode switch
105 #define ENABLE_NATIVE_EMUL_OP 1
106
108   // Pointer to Kernel Data
109 < static KernelData * const kernel_data = (KernelData *)KERNEL_DATA_BASE;
109 > static KernelData * kernel_data;
110  
111   // SIGSEGV handler
112 < static sigsegv_return_t sigsegv_handler(sigsegv_address_t, sigsegv_address_t);
112 > sigsegv_return_t sigsegv_handler(sigsegv_address_t, sigsegv_address_t);
113  
114   #if PPC_ENABLE_JIT && PPC_REENTRANT_JIT
115   // Special trampolines for EmulOp and NativeOp
# Line 138 | Line 139 | class sheepshaver_cpu
139          void init_decoder();
140          void execute_sheep(uint32 opcode);
141  
141        // Filter out EMUL_OP routines that only call native code
142        bool filter_execute_emul_op(uint32 emul_op);
143
144        // "Native" EMUL_OP routines
145        void execute_emul_op_microseconds();
146        void execute_emul_op_idle_time_1();
147        void execute_emul_op_idle_time_2();
148
142          // CPU context to preserve on interrupt
143          class interrupt_context {
144                  uint32 gpr[32];
# Line 270 | Line 263 | typedef bit_field< 19, 19 > FN_field;
263   typedef bit_field< 20, 25 > NATIVE_OP_field;
264   typedef bit_field< 26, 31 > EMUL_OP_field;
265  
273 // "Native" EMUL_OP routines
274 #define GPR_A(REG) gpr(16 + (REG))
275 #define GPR_D(REG) gpr( 8 + (REG))
276
277 void sheepshaver_cpu::execute_emul_op_microseconds()
278 {
279        Microseconds(GPR_A(0), GPR_D(0));
280 }
281
282 void sheepshaver_cpu::execute_emul_op_idle_time_1()
283 {
284        // Sleep if no events pending
285        if (ReadMacInt32(0x14c) == 0)
286                Delay_usec(16667);
287        GPR_A(0) = ReadMacInt32(0x2b6);
288 }
289
290 void sheepshaver_cpu::execute_emul_op_idle_time_2()
291 {
292        // Sleep if no events pending
293        if (ReadMacInt32(0x14c) == 0)
294                Delay_usec(16667);
295        GPR_D(0) = (uint32)-2;
296 }
297
298 // Filter out EMUL_OP routines that only call native code
299 bool sheepshaver_cpu::filter_execute_emul_op(uint32 emul_op)
300 {
301        switch (emul_op) {
302        case OP_MICROSECONDS:
303                execute_emul_op_microseconds();
304                return true;
305        case OP_IDLE_TIME:
306                execute_emul_op_idle_time_1();
307                return true;
308        case OP_IDLE_TIME_2:
309                execute_emul_op_idle_time_2();
310                return true;
311        }
312        return false;
313 }
314
266   // Execute EMUL_OP routine
267   void sheepshaver_cpu::execute_emul_op(uint32 emul_op)
268   {
318 #if ENABLE_NATIVE_EMUL_OP
319        // First, filter out EMUL_OPs that can be executed without a mode switch
320        if (filter_execute_emul_op(emul_op))
321                return;
322 #endif
323
269          M68kRegisters r68;
270          WriteMacInt32(XLM_68K_R25, gpr(25));
271          WriteMacInt32(XLM_RUN_MODE, MODE_EMUL_OP);
# Line 446 | Line 391 | int sheepshaver_cpu::compile1(codegen_co
391                          status = COMPILE_CODE_OK;
392                          break;
393   #endif
449                case NATIVE_DISABLE_INTERRUPT:
450                        dg.gen_invoke(DisableInterrupt);
451                        status = COMPILE_CODE_OK;
452                        break;
453                case NATIVE_ENABLE_INTERRUPT:
454                        dg.gen_invoke(EnableInterrupt);
455                        status = COMPILE_CODE_OK;
456                        break;
394                  case NATIVE_BITBLT:
395                          dg.gen_load_T0_GPR(3);
396                          dg.gen_invoke_T0((void (*)(uint32))NQD_bitblt);
# Line 510 | Line 447 | int sheepshaver_cpu::compile1(codegen_co
447  
448          default: {      // EMUL_OP
449                  uint32 emul_op = EMUL_OP_field::extract(opcode) - 3;
513 #if ENABLE_NATIVE_EMUL_OP
514                typedef void (*emul_op_func_t)(dyngen_cpu_base);
515                emul_op_func_t emul_op_func = 0;
516                switch (emul_op) {
517                case OP_MICROSECONDS:
518                        emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_microseconds).ptr();
519                        break;
520                case OP_IDLE_TIME:
521                        emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_idle_time_1).ptr();
522                        break;
523                case OP_IDLE_TIME_2:
524                        emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_idle_time_2).ptr();
525                        break;
526                }
527                if (emul_op_func) {
528                        dg.gen_invoke_CPU(emul_op_func);
529                        cg_context.done_compile = false;
530                        status = COMPILE_CODE_OK;
531                        break;
532                }
533 #endif
450   #if PPC_REENTRANT_JIT
451                  // Try to execute EmulOp trampoline
452                  dg.gen_set_PC_im(cg_context.pc + 4);
# Line 884 | Line 800 | static void dump_log(void)
800   *  Initialize CPU emulation
801   */
802  
803 < static sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction)
803 > sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction)
804   {
805   #if ENABLE_VOSF
806          // Handle screen fault
# Line 896 | Line 812 | static sigsegv_return_t sigsegv_handler(
812          const uintptr addr = (uintptr)fault_address;
813   #if HAVE_SIGSEGV_SKIP_INSTRUCTION
814          // Ignore writes to ROM
815 <        if ((addr - ROM_BASE) < ROM_SIZE)
815 >        if ((addr - (uintptr)ROMBaseHost) < ROM_SIZE)
816                  return SIGSEGV_RETURN_SKIP_INSTRUCTION;
817  
818          // Get program counter of target CPU
# Line 956 | Line 872 | static sigsegv_return_t sigsegv_handler(
872  
873   void init_emul_ppc(void)
874   {
875 +        // Get pointer to KernelData in host address space
876 +        kernel_data = (KernelData *)Mac2HostAddr(KERNEL_DATA_BASE);
877 +
878          // Initialize main CPU emulator
879          ppc_cpu = new sheepshaver_cpu();
880          ppc_cpu->set_register(powerpc_registers::GPR(3), any_register((uint32)ROM_BASE + 0x30d000));
881          ppc_cpu->set_register(powerpc_registers::GPR(4), any_register(KernelDataAddr + 0x1000));
882          WriteMacInt32(XLM_RUN_MODE, MODE_68K);
883  
965        // Install the handler for SIGSEGV
966        sigsegv_install_handler(sigsegv_handler);
967
884   #if ENABLE_MON
885          // Install "regs" command in cxmon
886          mon_add_command("regs", dump_registers, "regs                     Dump PowerPC registers\n");
# Line 1067 | Line 983 | void TriggerInterrupt(void)
983  
984   void sheepshaver_cpu::handle_interrupt(void)
985   {
986 + #ifdef USE_SDL_VIDEO
987 +        // We must fill in the events queue in the same thread that did call SDL_SetVideoMode()
988 +        SDL_PumpEvents();
989 + #endif
990 +
991          // Do nothing if interrupts are disabled
992 <        if (*(int32 *)XLM_IRQ_NEST > 0)
992 >        if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0)
993                  return;
994  
995          // Current interrupt nest level
# Line 1132 | Line 1053 | void sheepshaver_cpu::handle_interrupt(v
1053                                  0x4e, 0xd0,                                             // jmp          (a0)
1054                                  M68K_RTS >> 8, M68K_RTS & 0xff  // @1
1055                          };
1056 <                        Execute68k((uint32)proc, &r);
1056 >                        Execute68k(Host2MacAddr((uint8 *)proc), &r);
1057                          WriteMacInt32(XLM_68K_R25, old_r25);            // Restore interrupt level
1058   #else
1059                          // Only update cursor
# Line 1181 | Line 1102 | void sheepshaver_cpu::execute_native_op(
1102                  VideoVBL();
1103                  break;
1104          case NATIVE_VIDEO_DO_DRIVER_IO:
1105 <                gpr(3) = (int32)(int16)VideoDoDriverIO((void *)gpr(3), (void *)gpr(4),
1185 <                                                                                           (void *)gpr(5), gpr(6), gpr(7));
1105 >                gpr(3) = (int32)(int16)VideoDoDriverIO(gpr(3), gpr(4), gpr(5), gpr(6), gpr(7));
1106                  break;
1107   #ifdef WORDS_BIGENDIAN
1108          case NATIVE_ETHER_IRQ:
# Line 1266 | Line 1186 | void sheepshaver_cpu::execute_native_op(
1186                  get_resource_callbacks[selector - NATIVE_GET_RESOURCE]();
1187                  break;
1188          }
1269        case NATIVE_DISABLE_INTERRUPT:
1270                DisableInterrupt();
1271                break;
1272        case NATIVE_ENABLE_INTERRUPT:
1273                EnableInterrupt();
1274                break;
1189          case NATIVE_MAKE_EXECUTABLE:
1190 <                MakeExecutable(0, (void *)gpr(4), gpr(5));
1190 >                MakeExecutable(0, gpr(4), gpr(5));
1191                  break;
1192          case NATIVE_CHECK_LOAD_INVOC:
1193                  check_load_invoc(gpr(3), gpr(4), gpr(5));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines