OSDN Git Service

[VM][General][Qt] Merge upstream 20160317.
[csp-qt/common_source_project-fm7.git] / source / src / vm / huc6280.cpp
1 /*
2         Skelton for retropc emulator
3
4         Origin : MESS 0.147
5         Author : Takeda.Toshiya
6         Date   : 2012.10.23-
7
8         [ HuC6280 ]
9 */
10
11 #include "huc6280.h"
12 #ifdef USE_DEBUGGER
13 #include "debugger.h"
14 #endif
15
16 /* ----------------------------------------------------------------------------
17         MAME h6280
18 ---------------------------------------------------------------------------- */
19
20 #define INLINE inline
21 #define PAIR pair_t
22 #define offs_t UINT16
23
24 /*****************************************************************************/
25 /* src/emu/devcpu.h */
26
27 // CPU interface functions
28 #define CPU_INIT_NAME(name)                     cpu_init_##name
29 #define CPU_INIT(name)                          void* CPU_INIT_NAME(name)()
30 #define CPU_INIT_CALL(name)                     CPU_INIT_NAME(name)()
31
32 #define CPU_RESET_NAME(name)                    cpu_reset_##name
33 #define CPU_RESET(name)                         void CPU_RESET_NAME(name)(h6280_Regs *cpustate)
34 #define CPU_RESET_CALL(name)                    CPU_RESET_NAME(name)(cpustate)
35
36 #define CPU_EXECUTE_NAME(name)                  cpu_execute_##name
37 #define CPU_EXECUTE(name)                       int CPU_EXECUTE_NAME(name)(h6280_Regs *cpustate)
38 #define CPU_EXECUTE_CALL(name)                  CPU_EXECUTE_NAME(name)(cpustate)
39
40 #define CPU_DISASSEMBLE_NAME(name)              cpu_disassemble_##name
41 #define CPU_DISASSEMBLE(name)                   int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
42 #define CPU_DISASSEMBLE_CALL(name)              CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, oprom)
43
44 #define READ8_HANDLER(name)                     UINT8 name(h6280_Regs *cpustate, offs_t offset)
45 #define WRITE8_HANDLER(name)                    void name(h6280_Regs *cpustate, offs_t offset, UINT8 data)
46
47 /*****************************************************************************/
48 /* src/emu/didisasm.h */
49
50 // Disassembler constants
51 const UINT32 DASMFLAG_SUPPORTED     = 0x80000000;   // are disassembly flags supported?
52 const UINT32 DASMFLAG_STEP_OUT      = 0x40000000;   // this instruction should be the end of a step out sequence
53 const UINT32 DASMFLAG_STEP_OVER     = 0x20000000;   // this instruction should be stepped over by setting a breakpoint afterwards
54 const UINT32 DASMFLAG_OVERINSTMASK  = 0x18000000;   // number of extra instructions to skip when stepping over
55 const UINT32 DASMFLAG_OVERINSTSHIFT = 27;           // bits to shift after masking to get the value
56 const UINT32 DASMFLAG_LENGTHMASK    = 0x0000ffff;   // the low 16-bits contain the actual length
57
58 /*****************************************************************************/
59 /* src/emu/diexec.h */
60
61 // I/O line states
62 enum line_state
63 {
64         CLEAR_LINE = 0,                         // clear (a fired or held) line
65         ASSERT_LINE,                            // assert an interrupt immediately
66         HOLD_LINE,                              // hold interrupt line until acknowledged
67         PULSE_LINE                              // pulse interrupt line instantaneously (only for NMI, RESET)
68 };
69
70 enum
71 {
72         INPUT_LINE_IRQ1 = 0,
73         INPUT_LINE_IRQ2 = 1,
74         INPUT_LINE_TIRQ = 2,
75         INPUT_LINE_NMI
76 };
77
78 #define logerror(...)
79
80 #include "mame/emu/cpu/h6280/h6280.c"
81 #ifdef USE_DEBUGGER
82 #include "mame/emu/cpu/h6280/6280dasm.c"
83 #endif
84
85 // main
86
87 void HUC6280::initialize()
88 {
89         opaque = CPU_INIT_CALL(h6280);
90         
91         h6280_Regs *cpustate = (h6280_Regs *)opaque;
92         cpustate->program = d_mem;
93         cpustate->io = d_io;
94 #ifdef USE_DEBUGGER
95         cpustate->emu = emu;
96         cpustate->debugger = d_debugger;
97         cpustate->program_stored = d_mem;
98         cpustate->io_stored = d_io;
99         
100         d_debugger->set_context_mem(d_mem);
101         d_debugger->set_context_io(d_io);
102 #endif
103 }
104
105 void HUC6280::release()
106 {
107         free(opaque);
108 }
109
110 void HUC6280::reset()
111 {
112         h6280_Regs *cpustate = (h6280_Regs *)opaque;
113         
114         CPU_RESET_CALL(h6280);
115         
116         cpustate->program = d_mem;
117         cpustate->io = d_io;
118 #ifdef USE_DEBUGGER
119         cpustate->emu = emu;
120         cpustate->debugger = d_debugger;
121         cpustate->program_stored = d_mem;
122         cpustate->io_stored = d_io;
123 #endif
124         icount = 0;
125         busreq = false;
126 }
127
128 int HUC6280::run(int clock)
129 {
130         h6280_Regs *cpustate = (h6280_Regs *)opaque;
131         
132         if(clock == -1) {
133                 if(busreq) {
134                         // don't run cpu!
135                         return 1;
136                 } else {
137                         // run only one opcode
138                         return CPU_EXECUTE_CALL(h6280);
139                 }
140         } else {
141                 icount += clock;
142                 int first_icount = icount;
143                 
144                 // run cpu while given clocks
145                 while(icount > 0 && !busreq) {
146                         icount -= CPU_EXECUTE_CALL(h6280);
147                 }
148                 // if busreq is raised, spin cpu while remained clock
149                 if(icount > 0 && busreq) {
150                         icount = 0;
151                 }
152                 return first_icount - icount;
153         }
154 }
155
156 void HUC6280::write_signal(int id, uint32_t data, uint32_t mask)
157 {
158         if(id == SIG_CPU_BUSREQ) {
159                 busreq = ((data & mask) != 0);
160         } else {
161                 h6280_Regs *cpustate = (h6280_Regs *)opaque;
162                 set_irq_line(cpustate, id, data);
163         }
164 }
165
166 uint32_t HUC6280::get_pc()
167 {
168         h6280_Regs *cpustate = (h6280_Regs *)opaque;
169         return cpustate->ppc.w.l;
170 }
171
172 uint32_t HUC6280::get_next_pc()
173 {
174         h6280_Regs *cpustate = (h6280_Regs *)opaque;
175         return cpustate->pc.w.l;
176 }
177
178 uint8_t HUC6280::irq_status_r(uint16_t offset)
179 {
180         h6280_Regs *cpustate = (h6280_Regs *)opaque;
181         return h6280_irq_status_r(cpustate, offset);
182 }
183
184 void HUC6280::irq_status_w(uint16_t offset, uint8_t data)
185 {
186         h6280_Regs *cpustate = (h6280_Regs *)opaque;
187         h6280_irq_status_w(cpustate, offset, data);
188 }
189
190 uint8_t HUC6280::timer_r(uint16_t offset)
191 {
192         h6280_Regs *cpustate = (h6280_Regs *)opaque;
193         return h6280_timer_r(cpustate, offset);
194 }
195
196 void HUC6280::timer_w(uint16_t offset, uint8_t data)
197 {
198         h6280_Regs *cpustate = (h6280_Regs *)opaque;
199         h6280_timer_w(cpustate, offset, data);
200 }
201
202 #ifdef USE_DEBUGGER
203 void HUC6280::write_debug_data8(uint32_t addr, uint32_t data)
204 {
205         int wait;
206         d_mem->write_data8w(addr, data, &wait);
207 }
208
209 uint32_t HUC6280::read_debug_data8(uint32_t addr)
210 {
211         int wait;
212         return d_mem->read_data8w(addr, &wait);
213 }
214
215 void HUC6280::write_debug_io8(uint32_t addr, uint32_t data)
216 {
217         int wait;
218         d_io->write_io8w(addr, data, &wait);
219 }
220
221 uint32_t HUC6280::read_debug_io8(uint32_t addr) {
222         int wait;
223         return d_io->read_io8w(addr, &wait);
224 }
225
226 bool HUC6280::write_debug_reg(const _TCHAR *reg, uint32_t data)
227 {
228         h6280_Regs *cpustate = (h6280_Regs *)opaque;
229         if(_tcsicmp(reg, _T("PC")) == 0) {
230                 cpustate->pc.w.l = data;
231         } if(_tcsicmp(reg, _T("SP")) == 0) {
232                 cpustate->sp.w.l = data;
233         } if(_tcsicmp(reg, _T("ZP")) == 0) {
234                 cpustate->zp.w.l = data;
235         } if(_tcsicmp(reg, _T("EA")) == 0) {
236                 cpustate->ea.w.l = data;
237         } if(_tcsicmp(reg, _T("A")) == 0) {
238                 cpustate->a = data;
239         } if(_tcsicmp(reg, _T("X")) == 0) {
240                 cpustate->x = data;
241         } if(_tcsicmp(reg, _T("Y")) == 0) {
242                 cpustate->y = data;
243         } if(_tcsicmp(reg, _T("P")) == 0) {
244                 cpustate->p = data;
245         } else {
246                 return false;
247         }
248         return true;
249 }
250
251 void HUC6280::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
252 {
253         h6280_Regs *cpustate = (h6280_Regs *)opaque;
254         my_stprintf_s(buffer, buffer_len,
255         _T("PC = %04X SP = %04X ZP = %04X EA = %04X A = %02X X = %02X Y = %02X P = %02X"),
256         cpustate->pc.w.l, cpustate->sp.w.l, cpustate->zp.w.l, cpustate->ea.w.l, cpustate->a, cpustate->x, cpustate->y, cpustate->p);
257 }
258
259 // disassembler
260
261 int HUC6280::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
262 {
263         uint8_t oprom[8];
264         uint8_t *opram = oprom;
265         
266         for(int i = 0; i < 8; i++) {
267                 int wait;
268                 oprom[i] = d_mem->read_data8w(pc + i, &wait);
269         }
270         return CPU_DISASSEMBLE_CALL(h6280) & DASMFLAG_LENGTHMASK;
271 }
272 #endif
273
274 #define STATE_VERSION   3
275
276 void HUC6280::save_state(FILEIO* state_fio)
277 {
278         state_fio->FputUint32(STATE_VERSION);
279         state_fio->FputInt32(this_device_id);
280         
281         state_fio->Fwrite(opaque, sizeof(h6280_Regs), 1);
282         state_fio->FputInt32(icount);
283         state_fio->FputBool(busreq);
284 }
285
286 bool HUC6280::load_state(FILEIO* state_fio)
287 {
288         if(state_fio->FgetUint32() != STATE_VERSION) {
289                 return false;
290         }
291         if(state_fio->FgetInt32() != this_device_id) {
292                 return false;
293         }
294         state_fio->Fread(opaque, sizeof(h6280_Regs), 1);
295         icount = state_fio->FgetInt32();
296         busreq = state_fio->FgetBool();
297
298         // post process   
299         h6280_Regs *cpustate = (h6280_Regs *)opaque;
300         cpustate->program = d_mem;
301         cpustate->io = d_io;
302 #ifdef USE_DEBUGGER
303         cpustate->emu = emu;
304         cpustate->debugger = d_debugger;
305         cpustate->program_stored = d_mem;
306         cpustate->io_stored = d_io;
307 #endif
308         return true;
309 }