• R/O
  • HTTP
  • SSH
  • HTTPS

common_source_project-fm7: Commit

Common Source Code Project for Qt (a.k.a for FM-7).


Commit MetaInfo

Revisiona5a0c738a91ade3818e9b54206e06e68c095c730 (tree)
Zeit2017-12-07 17:25:36
AutorK.Ohta <whatisthis.sowhat@gmai...>
CommiterK.Ohta

Log Message

[VM][MC6809] More accurate emulation around HALT/BUSREQ and INT.
[VM][MC6809] You should'nt use bus_halt, use bus_ba (bus available) and bus_bs (bus status).
[VM][MC6809] Split interrupt sequence, to indicate bs bus as interrupt or sync_in.

Ändern Zusammenfassung

Diff

--- a/source/src/vm/mc6809.cpp
+++ b/source/src/vm/mc6809.cpp
@@ -97,6 +97,39 @@ void MC6809::run_one_opecode()
9797 }
9898 }
9999
100+void MC6809::debugger_hook()
101+{
102+ if(__USE_DEBUGGER) {
103+ bool now_debugging = d_debugger->now_debugging;
104+ if(now_debugging) {
105+ d_debugger->check_break_points(PC);
106+ if(d_debugger->now_suspended) {
107+ osd->mute_sound();
108+ d_debugger->now_waiting = true;
109+ while(d_debugger->now_debugging && d_debugger->now_suspended) {
110+ osd->sleep(10);
111+ }
112+ d_debugger->now_waiting = false;
113+ }
114+ if(d_debugger->now_debugging) {
115+ d_mem = d_debugger;
116+ } else {
117+ now_debugging = false;
118+ }
119+
120+ d_debugger->add_cpu_trace(PC);
121+ int first_icount = icount;
122+ //pPPC = pPC;
123+ if(now_debugging) {
124+ if(!d_debugger->now_going) {
125+ d_debugger->now_suspended = true;
126+ }
127+ d_mem = d_mem_stored;
128+ }
129+ }
130+ }
131+}
132+
100133
101134 // from MAME 0.160
102135
--- a/source/src/vm/mc6809.h
+++ b/source/src/vm/mc6809.h
@@ -20,6 +20,22 @@
2020 #include "device.h"
2121 #include "mc6809_consts.h"
2222
23+enum {
24+ MC6809_PHASE_RUN = 0,
25+ MC6809_PHASE_DEAD_CYCLE,
26+ MC6809_PHASE_IRQ_PUSH_STACK,
27+ MC6809_PHASE_IRQ_FETCH_VECTOR,
28+ MC6809_PHASE_FIRQ_PUSH_STACK,
29+ MC6809_PHASE_FIRQ_FETCH_VECTOR,
30+ MC6809_PHASE_NMI_PUSH_STACK,
31+ MC6809_PHASE_NMI_FETCH_VECTOR,
32+
33+ MC6809_PHASE_REQ_HALT,
34+ MC6809_PHASE_DO_HALT,
35+};
36+
37+#define SIG_CPU_HALTREQ 0x8000 + SIG_CPU_BUSREQ
38+
2339 class VM;
2440 class EMU;
2541 class DEBUGGER;
@@ -33,9 +49,9 @@ protected:
3349 DEVICE *d_mem_stored;
3450 int dasm_ptr;
3551
36- outputs_t outputs_bus_halt; // For sync
37-
3852 outputs_t outputs_bus_clr; // If clr() insn used, write "1" or "2".
53+ outputs_t outputs_bus_ba; // Bus available.
54+ outputs_t outputs_bus_bs; // Bus status.
3955 bool clr_used;
4056
4157 // registers
@@ -49,6 +65,12 @@ protected:
4965 pair_t ea; /* effective address */
5066
5167 uint32_t int_state;
68+ /* In Motorola's datasheet, status has some valiants. 20171207 K.O */
69+
70+ uint8_t run_phase;
71+ uint8_t old_run_phase;
72+ bool req_halt_on;
73+ bool req_halt_off;
5274 bool busreq;
5375
5476 uint64_t total_icount;
@@ -57,9 +79,12 @@ protected:
5779 int icount;
5880 int extra_icount;
5981 void WM16(uint32_t Addr, pair_t *p);
60- void cpu_irq(void);
61- void cpu_firq(void);
62- void cpu_nmi(void);
82+ void cpu_irq_push(void);
83+ void cpu_firq_push(void);
84+ void cpu_nmi_push(void);
85+ void cpu_irq_fetch_vector_address(void);
86+ void cpu_firq_fetch_vector_address(void);
87+ void cpu_nmi_fetch_vector_address(void);
6388 // Tables
6489 /* increment */
6590 const uint8_t flags8i[256] = {
@@ -498,6 +523,7 @@ protected:
498523 void tst_ix();
499524
500525 bool __USE_DEBUGGER;
526+
501527 public:
502528 MC6809_BASE(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
503529 {
@@ -505,7 +531,8 @@ public:
505531 total_icount = prev_total_icount = 0;
506532 __USE_DEBUGGER = false;
507533 initialize_output_signals(&outputs_bus_clr);
508- initialize_output_signals(&outputs_bus_halt);
534+ initialize_output_signals(&outputs_bus_ba);
535+ initialize_output_signals(&outputs_bus_bs);
509536 set_device_name(_T("MC6809 MPU"));
510537 }
511538 ~MC6809_BASE() {}
@@ -574,7 +601,7 @@ public:
574601 void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
575602 virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
576603 virtual uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram);
577-
604+ virtual void debugger_hook(void);
578605 // common functions
579606 void reset();
580607 virtual void initialize();
@@ -637,14 +664,18 @@ public:
637664 {
638665 d_mem = device;
639666 }
640- void set_context_bus_halt(DEVICE* device, int id, uint32_t mask)
641- {
642- register_output_signal(&outputs_bus_halt, device, id, mask);
643- }
644667 void set_context_bus_clr(DEVICE* device, int id, uint32_t mask)
645668 {
646669 register_output_signal(&outputs_bus_clr, device, id, mask);
647670 }
671+ void set_context_bus_ba(DEVICE* device, int id, uint32_t mask)
672+ {
673+ register_output_signal(&outputs_bus_ba, device, id, mask);
674+ }
675+ void set_context_bus_bs(DEVICE* device, int id, uint32_t mask)
676+ {
677+ register_output_signal(&outputs_bus_bs, device, id, mask);
678+ }
648679
649680 void set_context_debugger(DEBUGGER* device)
650681 {
@@ -665,6 +696,7 @@ class MC6809 : public MC6809_BASE
665696 void run_one_opecode();
666697 uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram);
667698 int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
699+ void debugger_hook(void);
668700 };
669701 #endif
670702
--- a/source/src/vm/mc6809_base.cpp
+++ b/source/src/vm/mc6809_base.cpp
@@ -161,9 +161,20 @@ void MC6809_BASE::reset()
161161 //#if defined(_FM7) || defined(_FM8) || defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
162162 clr_used = false;
163163 write_signals(&outputs_bus_clr, 0x00000000);
164+ if((req_halt_on) && !(req_halt_off)) {
165+ int_state |= MC6809_HALT_BIT;
166+ } else {
167+ req_halt_on = req_halt_off = false;
168+ }
169+ if((int_state & MC6809_HALT_BIT) != 0) {
170+ write_signals(&outputs_bus_ba, 0xffffffff);
171+ write_signals(&outputs_bus_bs, 0xffffffff);
172+ } else {
173+ write_signals(&outputs_bus_ba, 0x00000000);
174+ write_signals(&outputs_bus_bs, 0x00000000);
175+ }
176+ run_phase = old_run_phase = MC6809_PHASE_RUN;
164177 //#endif
165- write_signals(&outputs_bus_halt, ((int_state & MC6809_HALT_BIT) != 0) ? 0xffffffff : 0x00000000);
166-
167178 CC |= CC_II; /* IRQ disabled */
168179 CC |= CC_IF; /* FIRQ disabled */
169180
@@ -178,6 +189,8 @@ void MC6809_BASE::initialize()
178189 busreq = false;
179190 icount = 0;
180191 extra_icount = 0;
192+ run_phase = old_run_phase = MC6809_PHASE_RUN;
193+ req_halt_on = req_halt_off = false;
181194 __USE_DEBUGGER = osd->check_feature(_T("USE_DEBUGGER"));
182195
183196 }
@@ -208,12 +221,21 @@ void MC6809_BASE::write_signal(int id, uint32_t data, uint32_t mask)
208221 } else {
209222 int_state &= ~MC6809_HALT_BIT;
210223 }
224+ } else if(id == SIG_CPU_HALTREQ) {
225+ if(data & mask) {
226+ req_halt_on = true;
227+ //int_state |= MC6809_HALT_BIT;
228+ } else {
229+ if(req_halt_on) {
230+ req_halt_off = true;
231+ }
232+ //int_state &= ~MC6809_HALT_BIT;
233+ }
211234 }
212235 }
213236
214-void MC6809_BASE::cpu_nmi(void)
237+void MC6809_BASE::cpu_nmi_push(void)
215238 {
216- //pair_t rpc = pPC;
217239 if ((int_state & MC6809_CWAI_IN) == 0) {
218240 CC |= CC_E;
219241 PUSHWORD(pPC);
@@ -226,15 +248,29 @@ void MC6809_BASE::cpu_nmi(void)
226248 PUSHBYTE(CC);
227249 }
228250 CC = CC | CC_II | CC_IF; // 0x50
251+ return;
252+}
253+
254+void MC6809_BASE::cpu_nmi_fetch_vector_address(void)
255+{
229256 pPC = RM16_PAIR(0xfffc);
230257 // printf("NMI occured PC=0x%04x VECTOR=%04x SP=%04x \n",rpc.w.l,pPC.w.l,S);
231258 int_state |= MC6809_CWAI_OUT;
232259 int_state &= ~(MC6809_NMI_BIT | MC6809_SYNC_IN | MC6809_SYNC_OUT | MC6809_CWAI_IN); // $FF1E
260+ return;
233261 }
234262
235263
236-// Refine from cpu_x86.asm of V3.52a.
237-void MC6809_BASE::cpu_firq(void)
264+
265+void MC6809_BASE::cpu_firq_fetch_vector_address(void)
266+{
267+ pPC = RM16_PAIR(0xfff6);
268+ int_state |= MC6809_CWAI_OUT;
269+ int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT | MC6809_CWAI_IN);
270+ return;
271+}
272+
273+void MC6809_BASE::cpu_firq_push(void)
238274 {
239275 //pair_t rpc = pPC;
240276 if ((int_state & MC6809_CWAI_IN) == 0) {
@@ -244,16 +280,11 @@ void MC6809_BASE::cpu_firq(void)
244280 PUSHBYTE(CC);
245281 }
246282 CC = CC | CC_IF | CC_II;
247- pPC = RM16_PAIR(0xfff6);
248- int_state |= MC6809_CWAI_OUT;
249- int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT | MC6809_CWAI_IN);
283+
250284 // printf("Firq occured PC=0x%04x VECTOR=%04x SP=%04x \n",rpc.w.l,pPC.w.l,S);
251285 }
252-
253-// Refine from cpu_x86.asm of V3.52a.
254-void MC6809_BASE::cpu_irq(void)
286+void MC6809_BASE::cpu_irq_push(void)
255287 {
256- //pair_t rpc = pPC;
257288 if ((int_state & MC6809_CWAI_IN) == 0) {
258289 CC |= CC_E;
259290 PUSHWORD(pPC);
@@ -266,53 +297,58 @@ void MC6809_BASE::cpu_irq(void)
266297 PUSHBYTE(CC);
267298 }
268299 CC |= CC_II;
300+}
301+void MC6809_BASE::cpu_irq_fetch_vector_address(void)
302+{
303+ //pair_t rpc = pPC;
269304 pPC = RM16_PAIR(0xfff8);
270305 int_state |= MC6809_CWAI_OUT;
271306 int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT | MC6809_CWAI_IN);
272-
273-// printf("IRQ occured PC=0x%04x VECTOR=%04x SP=%04x \n",rpc.w.l,pPC.w.l,S);
274307 }
275308
276309 int MC6809_BASE::run(int clock)
277310 {
278311 int cycle = 0;
279312 int first_icount;
313+ int tmpcycle;
280314 if (clock >= 0) {
281315 icount += clock;
282316 }
283317 first_icount = icount;
284318
319+ if((req_halt_on) && !(req_halt_off)) {
320+ int_state |= MC6809_HALT_BIT;
321+ } else if(req_halt_on && req_halt_off) { // HALT OFF
322+ //if(!busreq) {
323+ int_state &= ~MC6809_HALT_BIT;
324+ req_halt_on = req_halt_off = false;
325+ //}
326+ }
327+
285328 if ((int_state & MC6809_HALT_BIT) != 0) { // 0x80
286-#if 0
287- if(clock < 0) {
288- int passed_icount;
289- passed_icount = max(1, extra_icount);
290- extra_icount = 0;
291- busreq = true;
292- total_icount += first_icount - passed_icount;
293- return first_icount - passed_icount;
294- } else {
295- //icount = 0;
296- icount -= extra_icount;
297- extra_icount = 0;
298- busreq = true;
299- total_icount += first_icount - icount;
300- return first_icount - icount;
301- }
302-#else
303329 icount = 0;
304330 icount -= extra_icount;
305331 extra_icount = 0;
306- if(!busreq) write_signals(&outputs_bus_halt, 0xffffffff); // Moved form before.Thanks to Ryu Takegami.
332+ if(!busreq) {
333+ write_signals(&outputs_bus_ba, 0xffffffff);
334+ write_signals(&outputs_bus_bs, 0xffffffff);
335+ }
307336 busreq = true;
337+ debugger_hook();
308338
309339 total_icount += first_icount - icount;
310340
311341 return first_icount - icount;
312-#endif
313342 }
314- if(busreq) write_signals(&outputs_bus_halt, 0x00000000);
315- busreq = false;
343+ if(busreq) {
344+ if((int_state & MC6809_SYNC_IN) != 0) {
345+ write_signals(&outputs_bus_ba, 0xffffffff);
346+ } else {
347+ write_signals(&outputs_bus_ba, 0x00000000);
348+ }
349+ write_signals(&outputs_bus_bs, 0x00000000);
350+ busreq = false;
351+ }
316352 if((int_state & MC6809_INSN_HALT) != 0) { // 0x80
317353 //uint8_t dmy = RM(PCD); //Will save.Need to keep.
318354 RM(PCD); //Will save.Need to keep.
@@ -324,6 +360,7 @@ int MC6809_BASE::run(int clock)
324360 }
325361 extra_icount = 0;
326362 PC++;
363+ debugger_hook();
327364 total_icount += first_icount - icount;
328365 return first_icount - icount;
329366 }
@@ -336,10 +373,28 @@ int MC6809_BASE::run(int clock)
336373 goto check_firq;
337374 //if ((int_state & MC6809_LDS) == 0)
338375 // goto check_firq;
339- cpu_nmi();
376+ if(run_phase != MC6809_PHASE_NMI_PUSH_STACK) {
377+ write_signals(&outputs_bus_bs, 0x00000000);
378+ old_run_phase = run_phase;
379+ run_phase = MC6809_PHASE_NMI_PUSH_STACK;
380+ cpu_nmi_push();
381+ debugger_hook();
382+ cycle = 19 - 2;
383+ icount -= cycle;
384+ total_icount += first_icount - icount;
385+ return first_icount - icount;
386+ } else {
387+ write_signals(&outputs_bus_bs, 0xffffffff);
388+ cpu_nmi_fetch_vector_address();
389+ run_phase = MC6809_PHASE_NMI_FETCH_VECTOR;
390+ }
340391 run_one_opecode();
341392 int_state &= ~MC6809_SYNC_IN;
342- cycle = 19;
393+ cycle = 2;
394+ //cycle = 19;
395+ write_signals(&outputs_bus_bs, 0x00000000);
396+ write_signals(&outputs_bus_ba, 0x00000000);
397+ run_phase = old_run_phase;
343398 goto int_cycle;
344399 } else {
345400 goto check_ok;
@@ -348,22 +403,58 @@ int MC6809_BASE::run(int clock)
348403 check_firq:
349404 if ((int_state & MC6809_FIRQ_BIT) != 0) {
350405 int_state &= ~MC6809_SYNC_IN; // Moved to before checking.Thanks to Ryu Takegami.
351- if ((CC & CC_IF) != 0)
352- goto check_irq;
353- cpu_firq();
406+ if(run_phase != MC6809_PHASE_FIRQ_PUSH_STACK) {
407+ if ((CC & CC_IF) != 0)
408+ goto check_irq;
409+ write_signals(&outputs_bus_bs, 0x00000000);
410+ old_run_phase = run_phase;
411+ run_phase = MC6809_PHASE_FIRQ_PUSH_STACK;
412+ cpu_firq_push();
413+ debugger_hook();
414+ cycle = 10 - 2;
415+ icount -= cycle;
416+ total_icount += first_icount - icount;
417+ return first_icount - icount;
418+ } else {
419+ write_signals(&outputs_bus_bs, 0xffffffff);
420+ cpu_firq_fetch_vector_address();
421+ run_phase = MC6809_PHASE_FIRQ_FETCH_VECTOR;
422+ }
354423 run_one_opecode();
355- cycle = 10;
424+ run_phase = old_run_phase;
425+ //cycle = 10;
426+ cycle = 2;
427+ write_signals(&outputs_bus_bs, 0x00000000);
428+ write_signals(&outputs_bus_ba, 0x00000000);
356429 goto int_cycle;
357430 }
358431
359432 check_irq:
360433 if ((int_state & MC6809_IRQ_BIT) != 0) {
361434 int_state &= ~MC6809_SYNC_IN; // Moved to before checking.Thanks to Ryu Takegami.
362- if ((CC & CC_II) != 0)
363- goto check_ok;
364- cpu_irq();
435+ if(run_phase != MC6809_PHASE_IRQ_PUSH_STACK) {
436+ if ((CC & CC_II) != 0)
437+ goto check_ok;
438+ write_signals(&outputs_bus_bs, 0x00000000);
439+ old_run_phase = run_phase;
440+ run_phase = MC6809_PHASE_IRQ_PUSH_STACK;
441+ cpu_irq_push();
442+ debugger_hook();
443+ cycle = 19 - 2;
444+ icount -= cycle;
445+ total_icount += first_icount - icount;
446+ return first_icount - icount;
447+ } else {
448+ write_signals(&outputs_bus_bs, 0xffffffff);
449+ cpu_irq_fetch_vector_address();
450+ run_phase = MC6809_PHASE_IRQ_FETCH_VECTOR;
451+ }
365452 run_one_opecode();
366- cycle = 19;
453+ //cycle = 19;
454+ cycle = 2;
455+ run_phase = old_run_phase;
456+ write_signals(&outputs_bus_bs, 0x00000000);
457+ write_signals(&outputs_bus_ba, 0x00000000);
367458 goto int_cycle;
368459 }
369460 /*
@@ -419,6 +510,11 @@ check_ok:
419510
420511 }
421512
513+void MC6809_BASE::debugger_hook()
514+{
515+
516+}
517+
422518 void MC6809_BASE::run_one_opecode()
423519 {
424520 pPPC = pPC;
@@ -1244,6 +1340,8 @@ OP_HANDLER(nop) {
12441340 OP_HANDLER(sync_09) // Rename 20101110
12451341 {
12461342 int_state |= MC6809_SYNC_IN;
1343+ write_signals(&outputs_bus_ba, 0xffffffff);
1344+ write_signals(&outputs_bus_bs, 0x00000000);
12471345 }
12481346
12491347
@@ -3761,7 +3859,7 @@ OP_HANDLER(pref11) {
37613859 }
37623860 }
37633861
3764-#define STATE_VERSION 1
3862+#define STATE_VERSION 2
37653863
37663864 void MC6809_BASE::save_state(FILEIO* state_fio)
37673865 {
@@ -3782,6 +3880,14 @@ void MC6809_BASE::save_state(FILEIO* state_fio)
37823880 state_fio->FputUint32(y.d);
37833881 state_fio->FputUint8(cc);
37843882 state_fio->FputUint32(ea.d);
3883+
3884+ // V2
3885+ state_fio->FputBool(req_halt_on);
3886+ state_fio->FputBool(req_halt_off);
3887+ state_fio->FputBool(busreq);
3888+
3889+ state_fio->FputUint8(old_run_phase);
3890+ state_fio->FputUint8(run_phase);
37853891 }
37863892
37873893 bool MC6809_BASE::load_state(FILEIO* state_fio)
@@ -3807,6 +3913,13 @@ bool MC6809_BASE::load_state(FILEIO* state_fio)
38073913 cc = state_fio->FgetUint8();
38083914 ea.d = state_fio->FgetUint32();
38093915
3916+ // V2
3917+ req_halt_on = state_fio->FgetBool();
3918+ req_halt_off = state_fio->FgetBool();
3919+ busreq = state_fio->FgetBool();
3920+
3921+ old_run_phase = state_fio->FgetUint8();
3922+ run_phase = state_fio->FgetUint8();
38103923 return true;
38113924 }
38123925
Show on old repository browser