2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
14 #include "./i8080_regdef.h"
20 #ifndef CPU_START_ADDR
21 #define CPU_START_ADDR 0
26 void I8080::ANA(uint8_t v)
33 void I8080::ANA(uint8_t v)
35 int i = (((_A | v) >> 3) & 1) * HF;
43 void I8080::JMP(uint8_t c)
52 void I8080::CALL(uint8_t c)
55 uint16_t a = FETCH16();
65 void I8080::JMP(uint8_t c)
74 void I8080::CALL(uint8_t c)
77 uint16_t a = FETCH16();
87 void I8080::dec_count(uint8_t code)
90 count -= cc_op_8085[code];
92 count -= cc_op_8080[code];
96 void I8080::check_reg_c(uint8_t val)
99 if(_C == val) _F |= XF; else _F &= ~XF;
103 void I8080::check_reg_e(uint8_t val)
106 if(_E == val) _F |= XF; else _F &= ~XF;
110 void I8080::check_reg_l(uint8_t val)
113 if(_L == val) _F |= XF; else _F &= ~XF;
117 void I8080::check_reg_sp(uint8_t val)
120 if((SP & 0xff) == val) _F |= XF; else _F &= ~XF;
124 void I8080::INSN_0x08(void)
131 void I8080::INSN_0x10(void)
135 _F = (_F & ~CF) | (_L & CF);
141 void I8080::RLDE(void)
144 _F = (_F & ~(CF | VF)) | (_D >> 7);
145 DE = (DE << 1) | (DE >> 15);
146 if(0 != (((DE >> 15) ^ _F) & CF)) {
152 void I8080::RIM(void)
155 _A = (IM & 0x7f) | (SID ? 0x80 : 0) | RIM_IEN;
160 void I8080::_DAA(void)
165 if(_F & CF) tmp16 |= 0x100;
166 if(_F & HF) tmp16 |= 0x200;
167 if(_F & NF) tmp16 |= 0x400;
174 void I8080::LDEH(void)
177 DE = (HL + FETCH8()) & 0xffff;
181 void I8080::CMA(void)
192 void I8080::SIM(void)
196 write_signals(&outputs_sod, (_A & 0x80) ? 0xffffffff : 0);
202 IM = (IM & ~(IM_M5 | IM_M6 | IM_M7)) | (_A & (IM_M5 | IM_M6 | IM_M7));
207 void I8080::LDES(void)
210 DE = (SP + FETCH8()) & 0xffff;
214 void I8080::INSN_0xcb(void)
236 void I8080::INSN_0xd9(void)
244 void I8080::INSN_0xdd(void)
253 void I8080::INSN_0xed(void)
256 HL = RM16(DE); // LHLX
262 void I8080::INSN_0xfd(void)
274 void I8080::initialize()
276 I8080_BASE::initialize();
278 d_mem_stored = d_mem;
280 d_debugger->set_context_mem(d_mem);
281 d_debugger->set_context_io(d_io);
292 void I8080::write_signal(int id, uint32_t data, uint32_t mask)
294 if(id == SIG_CPU_NMI) {
300 } else if(id == SIG_CPU_BUSREQ) {
301 BUSREQ = ((data & mask) != 0);
302 write_signals(&outputs_busack, BUSREQ ? 0xffffffff : 0);
303 } else if(id == SIG_I8080_INTR) {
310 } else if(id == SIG_I8085_RST5) {
316 } else if(id == SIG_I8085_RST6) {
322 } else if(id == SIG_I8085_RST7) {
328 } else if(id == SIG_I8085_SID) {
329 SID = ((data & mask) != 0);
335 int I8080::run(int clock)
345 // run only one opcode
352 int first_count = count;
354 // run cpu while given clocks
355 while(count > 0 && !BUSREQ) {
358 // if busreq is raised, spin cpu while remained clock
359 if(count > 0 && BUSREQ) {
361 total_count += count;
365 return first_count - count;
369 void I8080::run_one_opecode()
373 bool now_debugging = d_debugger->now_debugging;
375 d_debugger->check_break_points(PC);
376 if(d_debugger->now_suspended) {
377 d_debugger->now_waiting = true;
378 emu->start_waiting_in_debugger();
379 while(d_debugger->now_debugging && d_debugger->now_suspended) {
380 emu->process_waiting_in_debugger();
382 emu->finish_waiting_in_debugger();
383 d_debugger->now_waiting = false;
385 if(d_debugger->now_debugging) {
386 d_mem = d_io = d_debugger;
388 now_debugging = false;
391 afterHALT = afterEI = false;
392 d_debugger->add_cpu_trace(PC);
393 int first_count = count;
395 total_count += first_count - count;
401 if(!d_debugger->now_going) {
402 d_debugger->now_suspended = true;
404 d_mem = d_mem_stored;
409 afterHALT = afterEI = false;
411 d_debugger->add_cpu_trace(PC);
412 int first_count = count;
416 total_count += first_count - count;
425 // ei: run next opecode
428 bool now_debugging = d_debugger->now_debugging;
430 d_debugger->check_break_points(PC);
431 if(d_debugger->now_suspended) {
432 d_debugger->now_waiting = true;
433 emu->start_waiting_in_debugger();
434 while(d_debugger->now_debugging && d_debugger->now_suspended) {
435 emu->process_waiting_in_debugger();
437 emu->finish_waiting_in_debugger();
438 d_debugger->now_waiting = false;
440 if(d_debugger->now_debugging) {
441 d_mem = d_io = d_debugger;
443 now_debugging = false;
447 d_debugger->add_cpu_trace(PC);
448 int first_count = count;
450 total_count += first_count - count;
451 d_pic->notify_intr_ei();
455 if(!d_debugger->now_going) {
456 d_debugger->now_suspended = true;
458 d_mem = d_mem_stored;
465 d_debugger->add_cpu_trace(PC);
466 int first_count = count;
470 total_count += first_count - count;
472 d_pic->notify_intr_ei();
480 void I8080::check_interrupt()
483 int first_count = count;
489 count -= 5; // unknown
490 RIM_IEN = IM & IM_IEN;
491 IM &= ~(IM_IEN | IM_NMI);
492 } else if(IM & IM_IEN) {
495 if(/*!(IM & IM_M7) &&*/ (IM & IM_I7)) {
497 if(!(IM & IM_M7) && (IM & IM_I7)) {
500 count -= 7; // unknown
502 IM &= ~(IM_IEN | IM_I7);
503 } else if(!(IM & IM_M6) && (IM & IM_I6)) {
505 count -= 7; // unknown
507 IM &= ~(IM_IEN | IM_I6);
508 } else if(!(IM & IM_M5) && (IM & IM_I5)) {
510 count -= 7; // unknown
512 IM &= ~(IM_IEN | IM_I5);
516 uint32_t vector = ACK_INTR();
518 uint16_t v12 = vector >> 8;
519 // support JMP/CALL/RST only
520 //count -= cc_op[v0];
522 count -= cc_op_8085[v0];
524 count -= cc_op_8080[v0];
567 IM &= ~(IM_IEN | IM_INT);
572 total_count += first_count - count;
577 #define STATE_VERSION 2
579 bool I8080::process_state(FILEIO* state_fio, bool loading)
581 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
584 if(!state_fio->StateCheckInt32(this_device_id)) {
588 state_fio->StateValue(total_count);
590 state_fio->StateValue(count);
591 state_fio->StateArray(regs, sizeof(regs), 1); // ToDo:
592 state_fio->StateValue(SP);
593 state_fio->StateValue(PC);
594 state_fio->StateValue(prevPC);
595 state_fio->StateValue(IM);
596 state_fio->StateValue(RIM_IEN);
597 state_fio->StateValue(afterHALT);
598 state_fio->StateValue(BUSREQ);
599 state_fio->StateValue(SID);
600 state_fio->StateValue(afterEI);
605 prev_total_count = total_count;