| 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 | |
| 101 | int M68KGetCurrentOpcodeFamily(void); |
| 102 | |
| 103 | |
| 104 | // Functions to allow debugging |
| 105 | int M68KDebugHalt(void); |
| 106 | void M68KDebugResume(void); |
| 107 | int M68KDebugHaltStatus(void); |
| 108 | |
| 109 | /* Peek at the internals of a CPU context. This can either be a context |
| 110 | * retrieved using m68k_get_context() or the currently running context. |
| 111 | * If context is NULL, the currently running CPU context will be used. |
| 112 | */ |
| 113 | unsigned int m68k_get_reg(void * context, m68k_register_t reg); |
| 114 | |
| 115 | /* Poke values into the internals of the currently running CPU context */ |
| 116 | void m68k_set_reg(m68k_register_t reg, unsigned int value); |
| 117 | |
| 118 | // Dummy functions, for now... |
| 119 | |
| 120 | /* Check if an instruction is valid for the specified CPU type */ |
| 121 | unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type); |
| 122 | |
| 123 | /* Disassemble 1 instruction using the epecified CPU type at pc. Stores |
| 124 | * disassembly in str_buff and returns the size of the instruction in bytes. |
| 125 | */ |
| 126 | unsigned int m68k_disassemble(char * str_buff, unsigned int pc, unsigned int cpu_type, unsigned int OpCodes); |
| 127 | |
| 128 | /* These functions let you read/write/modify the number of cycles left to run |
| 129 | * while m68k_execute() is running. |
| 130 | * These are useful if the 68k accesses a memory-mapped port on another device |
| 131 | * that requires immediate processing by another CPU. |
| 132 | */ |
| 133 | int m68k_cycles_run(void); // Number of cycles run so far |
| 134 | int m68k_cycles_remaining(void); // Number of cycles left |
| 135 | void m68k_modify_timeslice(int cycles); // Modify cycles left |
| 136 | void m68k_end_timeslice(void); // End timeslice now |
| 137 | |
| 138 | // Breakpoints functions |
| 139 | extern void m68k_brk_init(void); |
| 140 | extern void m68k_brk_hitcounts_reset(void); |
| 141 | extern unsigned int m68k_brk_add(void *PtrInfo); |
| 142 | extern void m68k_brk_del(unsigned int NumBrk); |
| 143 | extern void m68k_brk_disable(void); |
| 144 | extern void m68k_brk_reset(void); |
| 145 | extern void m68k_brk_close(void); |
| 146 | extern unsigned int m68k_brk_check(unsigned int adr); |
| 147 | |
| 148 | #ifdef __cplusplus |
| 149 | } |
| 150 | #endif |
| 151 | |
| 152 | #endif // __M68KINTERFACE_H__ |