1 // 2 // C interface to the UAE core 3 // 4 // by James Hammons 5 // (C) 2011 Underground Software 6 // 7 // Most of these functions are in place to help make it easy to replace the 8 // Musashi core with my bastardized UAE one. :-) 9 // 10 11 #ifndef __M68KINTERFACE_H__ 12 #define __M68KINTERFACE_H__ 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /* Registers used by m68k_get_reg() and m68k_set_reg() */ 19 typedef enum 20 { 21 /* Real registers */ 22 M68K_REG_D0, /* Data registers */ 23 M68K_REG_D1, 24 M68K_REG_D2, 25 M68K_REG_D3, 26 M68K_REG_D4, 27 M68K_REG_D5, 28 M68K_REG_D6, 29 M68K_REG_D7, 30 M68K_REG_A0, /* Address registers */ 31 M68K_REG_A1, 32 M68K_REG_A2, 33 M68K_REG_A3, 34 M68K_REG_A4, 35 M68K_REG_A5, 36 M68K_REG_A6, 37 M68K_REG_A7, 38 M68K_REG_PC, /* Program Counter */ 39 M68K_REG_SR, /* Status Register */ 40 M68K_REG_SP, /* The current Stack Pointer (located in A7) */ 41 M68K_REG_USP, /* User Stack Pointer */ 42 43 /* Assumed registers */ 44 /* These are cheat registers which emulate the 1-longword prefetch 45 * present in the 68000 and 68010. 46 */ 47 M68K_REG_PREF_ADDR, /* Last prefetch address */ 48 M68K_REG_PREF_DATA, /* Last prefetch data */ 49 50 /* Convenience registers */ 51 M68K_REG_PPC, /* Previous value in the program counter */ 52 M68K_REG_IR, /* Instruction register */ 53 } m68k_register_t; 54 55 /* Special interrupt acknowledge values. 56 * Use these as special returns from the interrupt acknowledge callback 57 * (specified later in this header). 58 */ 59 60 /* Causes an interrupt autovector (0x18 + interrupt level) to be taken. 61 * This happens in a real 68K if VPA or AVEC is asserted during an interrupt 62 * acknowledge cycle instead of DTACK. 63 */ 64 #define M68K_INT_ACK_AUTOVECTOR 0xFFFFFFFF 65 66 /* Causes the spurious interrupt vector (0x18) to be taken 67 * This happens in a real 68K if BERR is asserted during the interrupt 68 * acknowledge cycle (i.e. no devices responded to the acknowledge). 69 */ 70 #define M68K_INT_ACK_SPURIOUS 0xFFFFFFFE 71 72 void m68k_set_cpu_type(unsigned int); 73 void m68k_pulse_reset(void); 74 int m68k_execute(int num_cycles); 75 void m68k_set_irq(unsigned int int_level); 76 77 // Functions that MUST be implemented by the user: 78 79 // Read from anywhere 80 unsigned int m68k_read_memory_8(unsigned int address); 81 unsigned int m68k_read_memory_16(unsigned int address); 82 unsigned int m68k_read_memory_32(unsigned int address); 83 84 // Write to anywhere 85 void m68k_write_memory_8(unsigned int address, unsigned int value); 86 void m68k_write_memory_16(unsigned int address, unsigned int value); 87 void m68k_write_memory_32(unsigned int address, unsigned int value); 88 89 int irq_ack_handler(int); 90 91 // Convenience functions 92 93 // Uncomment this to have the emulated CPU call a hook function after every instruction 94 // NB: This must be implemented by the user! 95 #define M68K_HOOK_FUNCTION 96 #ifdef M68K_HOOK_FUNCTION 97 void M68KInstructionHook(void); 98 #endif 99 100 // Functions to allow debugging 101 void M68KDebugHalt(void); 102 void M68KDebugResume(void); 103 104 /* Peek at the internals of a CPU context. This can either be a context 105 * retrieved using m68k_get_context() or the currently running context. 106 * If context is NULL, the currently running CPU context will be used. 107 */ 108 unsigned int m68k_get_reg(void * context, m68k_register_t reg); 109 110 /* Poke values into the internals of the currently running CPU context */ 111 void m68k_set_reg(m68k_register_t reg, unsigned int value); 112 113 // Dummy functions, for now... 114 115 /* Check if an instruction is valid for the specified CPU type */ 116 unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type); 117 118 /* Disassemble 1 instruction using the epecified CPU type at pc. Stores 119 * disassembly in str_buff and returns the size of the instruction in bytes. 120 */ 121 unsigned int m68k_disassemble(char * str_buff, unsigned int pc, unsigned int cpu_type); 122 123 /* These functions let you read/write/modify the number of cycles left to run 124 * while m68k_execute() is running. 125 * These are useful if the 68k accesses a memory-mapped port on another device 126 * that requires immediate processing by another CPU. 127 */ 128 int m68k_cycles_run(void); // Number of cycles run so far 129 int m68k_cycles_remaining(void); // Number of cycles left 130 void m68k_modify_timeslice(int cycles); // Modify cycles left 131 void m68k_end_timeslice(void); // End timeslice now 132 133 #ifdef __cplusplus 134 } 135 #endif 136 137 #endif // __M68KINTERFACE_H__ 138