Commit | Line | Data |
---|---|---|
cf76e892 JPM |
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 | void 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 | #ifdef __cplusplus | |
139 | } | |
140 | #endif | |
141 | ||
142 | #endif // __M68KINTERFACE_H__ |