Common Source Code Project for Qt (a.k.a for FM-7).
Revision | cc9f25ca1f420c751ea6f33f4edef7ac5e7079fb (tree) |
---|---|
Zeit | 2023-03-06 20:15:18 |
Autor | K.Ohta <whatisthis.sowhat@gmai...> |
Commiter | K.Ohta |
[VM][Z80][PC9801][DISPLAY] Merge upstream 2022-09-30 .
[VM][Z80] Split Z80::check_interrupt() .
@@ -1,3 +1,10 @@ | ||
1 | +9/30/2022 | |
2 | + | |
3 | +[VM/Z80] fix for DI,EI,EI,DI case | |
4 | + | |
5 | +[PC9801/DISPLAY] fix scroll register | |
6 | + | |
7 | + | |
1 | 8 | 9/11/2022 |
2 | 9 | |
3 | 10 | [VM/SCSI_DEV] fix delay to raise REQ signal after ACK is raised |
@@ -1,6 +1,6 @@ | ||
1 | 1 | message("* vm/common_vm") |
2 | 2 | |
3 | -SET(THIS_LIB_VERSION 7.7.0) | |
3 | +SET(THIS_LIB_VERSION 7.7.1) | |
4 | 4 | |
5 | 5 | #include(cotire) |
6 | 6 | set(s_vm_common_vm_srcs |
@@ -1742,9 +1742,6 @@ void DISPLAY::draw_chr_screen() | ||
1742 | 1742 | // if(ytop >= (_height << 4)) break; |
1743 | 1743 | } |
1744 | 1744 | |
1745 | - uint32_t *addr = &gdc_addr[0][0]; | |
1746 | -// uint32_t *addr2 = addr + 160 * (sur + sdr); | |
1747 | - uint32_t *addr2 = addr + 80 * (sur + sdr); | |
1748 | 1745 | |
1749 | 1746 | uint32_t cursor_addr = d_gdc_chr->cursor_addr(0x1fff); |
1750 | 1747 | int cursor_top = d_gdc_chr->cursor_top(); |
@@ -1761,6 +1758,9 @@ void DISPLAY::draw_chr_screen() | ||
1761 | 1758 | int xofs = modereg1[MODE1_COLUMN] ? (FONT_WIDTH * 2) : FONT_WIDTH; |
1762 | 1759 | int addrofs = modereg1[MODE1_COLUMN] ? 2 : 1; |
1763 | 1760 | |
1761 | + uint32_t *addr = &gdc_addr[0][0]; | |
1762 | + uint32_t *addr2 = addr; | |
1763 | + | |
1764 | 1764 | memset(screen_chr, 0, sizeof(screen_chr)); |
1765 | 1765 | |
1766 | 1766 | _width <<= 4; |
@@ -1789,7 +1789,8 @@ void DISPLAY::draw_chr_screen() | ||
1789 | 1789 | uint8_t attr = tvram[(*addr) | 0x2000]; |
1790 | 1790 | uint8_t color = (attr & ATTR_COL) ? (attr >> 5) : 8; |
1791 | 1791 | bool cursor = ((*addr) == cursor_addr); |
1792 | - addr += addrofs; | |
1792 | + addr += addrofs; | |
1793 | + addr2 += addrofs; | |
1793 | 1794 | if(kanji2nd) { |
1794 | 1795 | kanji2nd = 0; |
1795 | 1796 | offset = last + KANJI_2ND_OFS; |
@@ -143,17 +143,17 @@ | ||
143 | 143 | Z80_INLINE uint8_t Z80::RM8(uint32_t addr) |
144 | 144 | { |
145 | 145 | //#ifdef Z80_MEMORY_WAIT |
146 | - UPDATE_EVENT_IN_OP(2); | |
146 | + UPDATE_EVENT_IN_OP(1); | |
147 | 147 | if(has_memory_wait) { |
148 | 148 | int wait_clock; |
149 | 149 | uint8_t val = d_mem->read_data8w(addr, &wait_clock); |
150 | 150 | icount -= wait_clock; |
151 | - CLOCK_IN_OP(1 + wait_clock); | |
151 | + CLOCK_IN_OP(2 + wait_clock); | |
152 | 152 | return val; |
153 | 153 | } else { |
154 | 154 | //#else |
155 | 155 | uint8_t val = d_mem->read_data8(addr); |
156 | - CLOCK_IN_OP(1); | |
156 | + CLOCK_IN_OP(2); | |
157 | 157 | return val; |
158 | 158 | } |
159 | 159 | //#endif |
@@ -162,16 +162,16 @@ Z80_INLINE uint8_t Z80::RM8(uint32_t addr) | ||
162 | 162 | Z80_INLINE void Z80::WM8(uint32_t addr, uint8_t val) |
163 | 163 | { |
164 | 164 | //#ifdef Z80_MEMORY_WAIT |
165 | - UPDATE_EVENT_IN_OP(2); | |
165 | + UPDATE_EVENT_IN_OP(1); | |
166 | 166 | if(has_memory_wait) { |
167 | 167 | int wait_clock; |
168 | 168 | d_mem->write_data8w(addr, val, &wait_clock); |
169 | 169 | icount -= wait_clock; |
170 | - CLOCK_IN_OP(1 + wait_clock); | |
170 | + CLOCK_IN_OP(2 + wait_clock); | |
171 | 171 | } else { |
172 | 172 | //#else |
173 | 173 | d_mem->write_data8(addr, val); |
174 | - CLOCK_IN_OP(1); | |
174 | + CLOCK_IN_OP(2); | |
175 | 175 | } |
176 | 176 | //#endif |
177 | 177 | } |
@@ -195,11 +195,11 @@ Z80_INLINE uint8_t Z80::FETCHOP() | ||
195 | 195 | R++; |
196 | 196 | |
197 | 197 | // consider m1 cycle wait |
198 | - UPDATE_EVENT_IN_OP(2); | |
198 | + UPDATE_EVENT_IN_OP(1); | |
199 | 199 | int wait_clock; |
200 | 200 | uint8_t val = d_mem->fetch_op(pctmp, &wait_clock); |
201 | 201 | icount -= wait_clock; |
202 | - CLOCK_IN_OP(2 + wait_clock); | |
202 | + CLOCK_IN_OP(3 + wait_clock); | |
203 | 203 | return val; |
204 | 204 | } |
205 | 205 |
@@ -220,17 +220,17 @@ Z80_INLINE uint32_t Z80::FETCH16() | ||
220 | 220 | Z80_INLINE uint8_t Z80::IN8(uint32_t addr) |
221 | 221 | { |
222 | 222 | //#ifdef Z80_IO_WAIT |
223 | - UPDATE_EVENT_IN_OP(3); | |
223 | + UPDATE_EVENT_IN_OP(2); | |
224 | 224 | if(has_io_wait) { |
225 | 225 | int wait_clock; |
226 | 226 | uint8_t val = d_io->read_io8w(addr, &wait_clock); |
227 | 227 | icount -= wait_clock; |
228 | - CLOCK_IN_OP(1 + wait_clock); | |
228 | + CLOCK_IN_OP(2 + wait_clock); | |
229 | 229 | return val; |
230 | 230 | } else { |
231 | 231 | //#else |
232 | 232 | uint8_t val = d_io->read_io8(addr); |
233 | - CLOCK_IN_OP(1); | |
233 | + CLOCK_IN_OP(2); | |
234 | 234 | return val; |
235 | 235 | } |
236 | 236 | //#endif |
@@ -239,11 +239,11 @@ Z80_INLINE uint8_t Z80::IN8(uint32_t addr) | ||
239 | 239 | Z80_INLINE void Z80::OUT8(uint32_t addr, uint8_t val) |
240 | 240 | { |
241 | 241 | //#ifdef HAS_NSC800 |
242 | - UPDATE_EVENT_IN_OP(3); | |
242 | + UPDATE_EVENT_IN_OP(2); | |
243 | 243 | if(has_nsc800) { |
244 | 244 | if((addr & 0xff) == 0xbb) { |
245 | 245 | icr = val; |
246 | - CLOCK_IN_OP(1); | |
246 | + CLOCK_IN_OP(2); | |
247 | 247 | return; |
248 | 248 | } |
249 | 249 | } |
@@ -253,11 +253,11 @@ Z80_INLINE void Z80::OUT8(uint32_t addr, uint8_t val) | ||
253 | 253 | int wait_clock; |
254 | 254 | d_io->write_io8w(addr, val, &wait_clock); |
255 | 255 | icount -= wait_clock; |
256 | - CLOCK_IN_OP(1 + wait_clock); | |
256 | + CLOCK_IN_OP(2 + wait_clock); | |
257 | 257 | } else { |
258 | 258 | //#else |
259 | 259 | d_io->write_io8(addr, val); |
260 | - CLOCK_IN_OP(1); | |
260 | + CLOCK_IN_OP(2); | |
261 | 261 | } |
262 | 262 | //#endif |
263 | 263 | } |
@@ -1909,7 +1909,7 @@ void Z80::OP(uint8_t code) | ||
1909 | 1909 | case 0xf0: RET_COND(!(F & SF), 0xf0); break; /* RET P */ |
1910 | 1910 | case 0xf1: POP(af); break; /* POP AF */ |
1911 | 1911 | case 0xf2: JP_COND(!(F & SF)); break; /* JP P,a */ |
1912 | - case 0xf3: iff1 = iff2 = 0; break; /* DI */ | |
1912 | + case 0xf3: iff1 = iff2 = 0; after_di = true; break; /* DI */ | |
1913 | 1913 | case 0xf4: CALL_COND(!(F & SF), 0xf4); break; /* CALL P,a */ |
1914 | 1914 | case 0xf5: PUSH(af); break; /* PUSH AF */ |
1915 | 1915 | case 0xf6: OR(FETCH8()); break; /* OR n */ |
@@ -2107,7 +2107,7 @@ void Z80::special_reset(int num) | ||
2107 | 2107 | ea = 0; |
2108 | 2108 | |
2109 | 2109 | im = iff1 = iff2 = icr = 0; |
2110 | - after_halt = after_ei = false; | |
2110 | + after_halt = after_di = after_ei = false; | |
2111 | 2111 | after_ldair = false; |
2112 | 2112 | intr_req_bit = intr_pend_bit = 0; |
2113 | 2113 | } |
@@ -2381,7 +2381,7 @@ void Z80::run_one_opecode() | ||
2381 | 2381 | // rune one opecode |
2382 | 2382 | bool prev_after_ei = after_ei; |
2383 | 2383 | |
2384 | - after_halt = after_ei = false; | |
2384 | + after_halt = after_di = after_ei = false; | |
2385 | 2385 | after_ldair = false; |
2386 | 2386 | |
2387 | 2387 | bool now_debugging = false; |
@@ -2413,11 +2413,12 @@ void Z80::run_one_opecode() | ||
2413 | 2413 | } |
2414 | 2414 | } |
2415 | 2415 | //#endif |
2416 | - if(prev_after_ei) { | |
2417 | - d_pic->notify_intr_ei(); | |
2418 | - check_interrupt(); | |
2419 | - after_ei = false; | |
2420 | - } else if(!after_ei) { | |
2416 | + if(!after_ei) { | |
2417 | + // not just after EI is done | |
2418 | + if(prev_after_ei && !after_di) { | |
2419 | + // EI and any instruction (ex. RET, not DI/EI) are done | |
2420 | + d_pic->notify_intr_ei(); | |
2421 | + } | |
2421 | 2422 | check_interrupt(); |
2422 | 2423 | } |
2423 | 2424 | if(now_debugging) { |
@@ -2441,11 +2442,12 @@ void Z80::run_one_opecode() | ||
2441 | 2442 | } |
2442 | 2443 | } |
2443 | 2444 | //#endif |
2444 | - if(prev_after_ei) { | |
2445 | - d_pic->notify_intr_ei(); | |
2446 | - check_interrupt(); | |
2447 | - after_ei = false; | |
2448 | - } else if(!after_ei) { | |
2445 | + if(!after_ei) { | |
2446 | + // not just after EI is done | |
2447 | + if(prev_after_ei && !after_di) { | |
2448 | + // EI and any instruction (ex. RET, not DI/EI) are done | |
2449 | + d_pic->notify_intr_ei(); | |
2450 | + } | |
2449 | 2451 | check_interrupt(); |
2450 | 2452 | } |
2451 | 2453 | //#ifdef USE_DEBUGGER |
@@ -2453,10 +2455,92 @@ void Z80::run_one_opecode() | ||
2453 | 2455 | //#endif |
2454 | 2456 | } |
2455 | 2457 | |
2458 | +void Z80::check_interrupt_standard() | |
2459 | +{ | |
2460 | + if(iff1) { // Standard Z80. | |
2461 | + // interrupt | |
2462 | + LEAVE_HALT(); | |
2463 | + | |
2464 | + uint32_t vector = d_pic->get_intr_ack(); | |
2465 | + if(im == 0) { | |
2466 | + // mode 0 (support NOP/JMP/CALL/RST only) | |
2467 | + switch(vector & 0xff) { | |
2468 | + case 0x00: break; // NOP | |
2469 | + case 0xc3: PCD = vector >> 8; break; // JMP | |
2470 | + case 0xcd: PUSH(pc); PCD = vector >> 8; break; // CALL | |
2471 | + case 0xc7: PUSH(pc); PCD = 0x0000; break; // RST 00H | |
2472 | + case 0xcf: PUSH(pc); PCD = 0x0008; break; // RST 08H | |
2473 | + case 0xd7: PUSH(pc); PCD = 0x0010; break; // RST 10H | |
2474 | + case 0xdf: PUSH(pc); PCD = 0x0018; break; // RST 18H | |
2475 | + case 0xe7: PUSH(pc); PCD = 0x0020; break; // RST 20H | |
2476 | + case 0xef: PUSH(pc); PCD = 0x0028; break; // RST 28H | |
2477 | + case 0xf7: PUSH(pc); PCD = 0x0030; break; // RST 30H | |
2478 | + case 0xff: PUSH(pc); PCD = 0x0038; break; // RST 38H | |
2479 | + } | |
2480 | + icount -= cc_op[vector & 0xff] + cc_ex[0xff]; | |
2481 | + } else if(im == 1) { | |
2482 | + // mode 1 | |
2483 | + PUSH(pc); | |
2484 | + PCD = 0x0038; | |
2485 | + icount -= cc_op[0xff] + cc_ex[0xff]; | |
2486 | + } else { | |
2487 | + // mode 2 | |
2488 | + PUSH(pc); | |
2489 | + RM16((vector & 0xff) | (I << 8), &pc); | |
2490 | + icount -= cc_op[0xcd] + cc_ex[0xff]; | |
2491 | + } | |
2492 | + iff1 = iff2 = 0; | |
2493 | + intr_req_bit = 0; | |
2494 | + WZ = PCD; | |
2495 | + } else { | |
2496 | + intr_req_bit &= intr_pend_bit; | |
2497 | + } | |
2498 | +} | |
2499 | + | |
2500 | +void Z80::check_interrupt_nsc800() | |
2501 | +{ | |
2502 | + if(iff1) { // NSC800 | |
2503 | + if((intr_req_bit & 8) && (icr & 8)) { | |
2504 | + // RSTA | |
2505 | + LEAVE_HALT(); | |
2506 | + PUSH(pc); | |
2507 | + PCD = WZ = 0x003c; | |
2508 | + icount -= cc_op[0xff] + cc_ex[0xff]; | |
2509 | + iff1 = iff2 = 0; | |
2510 | + intr_req_bit &= ~8; | |
2511 | + } else if((intr_req_bit & 4) && (icr & 4)) { | |
2512 | + // RSTB | |
2513 | + LEAVE_HALT(); | |
2514 | + PUSH(pc); | |
2515 | + PCD = WZ = 0x0034; | |
2516 | + icount -= cc_op[0xff] + cc_ex[0xff]; | |
2517 | + iff1 = iff2 = 0; | |
2518 | + intr_req_bit &= ~4; | |
2519 | + } else if((intr_req_bit & 2) && (icr & 2)) { | |
2520 | + // RSTC | |
2521 | + LEAVE_HALT(); | |
2522 | + PUSH(pc); | |
2523 | + PCD = WZ = 0x002c; | |
2524 | + icount -= cc_op[0xff] + cc_ex[0xff]; | |
2525 | + iff1 = iff2 = 0; | |
2526 | + intr_req_bit &= ~2; | |
2527 | + } else if((intr_req_bit & 1) && (icr & 1)) { | |
2528 | + // INTR | |
2529 | + LEAVE_HALT(); | |
2530 | + PUSH(pc); | |
2531 | + PCD = WZ = d_pic->get_intr_ack() & 0xffff; | |
2532 | + icount -= cc_op[0xcd] + cc_ex[0xff]; | |
2533 | + iff1 = iff2 = 0; | |
2534 | + intr_req_bit &= ~1; | |
2535 | + } | |
2536 | + } | |
2537 | +} | |
2538 | + | |
2456 | 2539 | void Z80::check_interrupt() |
2457 | 2540 | { |
2458 | 2541 | // check interrupt |
2459 | 2542 | if(intr_req_bit) { |
2543 | + // Processing NMI is commonly both Z80 and NSC800 . | |
2460 | 2544 | if(intr_req_bit & NMI_REQ_BIT) { |
2461 | 2545 | // nmi |
2462 | 2546 | LEAVE_HALT(); |
@@ -2465,87 +2549,11 @@ void Z80::check_interrupt() | ||
2465 | 2549 | icount -= 11; |
2466 | 2550 | iff1 = 0; |
2467 | 2551 | intr_req_bit &= ~NMI_REQ_BIT; |
2468 | -//#ifdef HAS_NSC800 | |
2469 | 2552 | } else if(has_nsc800) { |
2470 | - if((intr_req_bit & 1) && (icr & 1)) { | |
2471 | - // INTR | |
2472 | - LEAVE_HALT(); | |
2473 | - PUSH(pc); | |
2474 | - if(d_pic != NULL) { // OK? | |
2475 | - PCD = WZ = d_pic->get_intr_ack() & 0xffff; | |
2476 | - } else { | |
2477 | - PCD = WZ = (PCD & 0xff00) | 0xcd; | |
2478 | - } | |
2479 | - icount -= cc_op[0xcd] + cc_ex[0xff]; | |
2480 | - iff1 = iff2 = 0; | |
2481 | - intr_req_bit &= ~1; | |
2482 | - } else if((intr_req_bit & 8) && (icr & 8)) { | |
2483 | - // RSTA | |
2484 | - LEAVE_HALT(); | |
2485 | - PUSH(pc); | |
2486 | - PCD = WZ = 0x003c; | |
2487 | - icount -= cc_op[0xff] + cc_ex[0xff]; | |
2488 | - iff1 = iff2 = 0; | |
2489 | - intr_req_bit &= ~8; | |
2490 | - } else if((intr_req_bit & 4) && (icr & 4)) { | |
2491 | - // RSTB | |
2492 | - LEAVE_HALT(); | |
2493 | - PUSH(pc); | |
2494 | - PCD = WZ = 0x0034; | |
2495 | - icount -= cc_op[0xff] + cc_ex[0xff]; | |
2496 | - iff1 = iff2 = 0; | |
2497 | - intr_req_bit &= ~4; | |
2498 | - } else if((intr_req_bit & 2) && (icr & 2)) { | |
2499 | - // RSTC | |
2500 | - LEAVE_HALT(); | |
2501 | - PUSH(pc); | |
2502 | - PCD = WZ = 0x002c; | |
2503 | - icount -= cc_op[0xff] + cc_ex[0xff]; | |
2504 | - iff1 = iff2 = 0; | |
2505 | - intr_req_bit &= ~2; | |
2506 | - } | |
2507 | - } else { // Normal Z80 | |
2508 | - if(iff1) { | |
2509 | - // interrupt | |
2510 | - LEAVE_HALT(); | |
2511 | - | |
2512 | - uint32_t vector = 0xcd; | |
2513 | - if(d_pic != NULL) vector = d_pic->get_intr_ack(); | |
2514 | - if(im == 0) { | |
2515 | - // mode 0 (support NOP/JMP/CALL/RST only) | |
2516 | - switch(vector & 0xff) { | |
2517 | - case 0x00: break; // NOP | |
2518 | - case 0xc3: PCD = vector >> 8; break; // JMP | |
2519 | - case 0xcd: PUSH(pc); PCD = vector >> 8; break; // CALL | |
2520 | - case 0xc7: PUSH(pc); PCD = 0x0000; break; // RST 00H | |
2521 | - case 0xcf: PUSH(pc); PCD = 0x0008; break; // RST 08H | |
2522 | - case 0xd7: PUSH(pc); PCD = 0x0010; break; // RST 10H | |
2523 | - case 0xdf: PUSH(pc); PCD = 0x0018; break; // RST 18H | |
2524 | - case 0xe7: PUSH(pc); PCD = 0x0020; break; // RST 20H | |
2525 | - case 0xef: PUSH(pc); PCD = 0x0028; break; // RST 28H | |
2526 | - case 0xf7: PUSH(pc); PCD = 0x0030; break; // RST 30H | |
2527 | - case 0xff: PUSH(pc); PCD = 0x0038; break; // RST 38H | |
2528 | - } | |
2529 | - icount -= cc_op[vector & 0xff] + cc_ex[0xff]; | |
2530 | - } else if(im == 1) { | |
2531 | - // mode 1 | |
2532 | - PUSH(pc); | |
2533 | - PCD = 0x0038; | |
2534 | - icount -= cc_op[0xff] + cc_ex[0xff]; | |
2535 | - } else { | |
2536 | - // mode 2 | |
2537 | - PUSH(pc); | |
2538 | - RM16((vector & 0xff) | (I << 8), &pc); | |
2539 | - icount -= cc_op[0xcd] + cc_ex[0xff]; | |
2540 | - } | |
2541 | - iff1 = iff2 = 0; | |
2542 | - intr_req_bit = 0; | |
2543 | - WZ = PCD; | |
2544 | - } else { | |
2545 | - intr_req_bit &= intr_pend_bit; | |
2546 | -//#endif | |
2547 | - } | |
2548 | -//#else | |
2553 | + // Another processing is different both Z80 and NSC800 . | |
2554 | + check_interrupt_nsc800(); | |
2555 | + } else { | |
2556 | + check_interrupt_standard(); | |
2549 | 2557 | } |
2550 | 2558 | } |
2551 | 2559 | } |
@@ -4085,7 +4093,7 @@ int Z80::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len | ||
4085 | 4093 | return z80_dasm_main(pc, buffer, buffer_len, d_debugger->first_symbol); |
4086 | 4094 | } |
4087 | 4095 | |
4088 | -#define STATE_VERSION 5 | |
4096 | +#define STATE_VERSION 6 | |
4089 | 4097 | |
4090 | 4098 | bool Z80::process_state(FILEIO* state_fio, bool loading) |
4091 | 4099 | { |
@@ -4126,6 +4134,7 @@ bool Z80::process_state(FILEIO* state_fio, bool loading) | ||
4126 | 4134 | state_fio->StateValue(iff1); |
4127 | 4135 | state_fio->StateValue(iff2); |
4128 | 4136 | state_fio->StateValue(icr); |
4137 | + state_fio->StateValue(after_di); | |
4129 | 4138 | state_fio->StateValue(after_ei); |
4130 | 4139 | state_fio->StateValue(after_ldair); |
4131 | 4140 | state_fio->StateValue(intr_req_bit); |
@@ -79,7 +79,7 @@ protected: | ||
79 | 79 | |
80 | 80 | bool busreq, wait, after_halt; |
81 | 81 | uint8_t im, iff1, iff2, icr; |
82 | - bool after_ei, after_ldair; | |
82 | + bool after_di, after_ei, after_ldair; | |
83 | 83 | uint32_t intr_req_bit, intr_pend_bit; |
84 | 84 | |
85 | 85 | Z80_INLINE uint8_t __FASTCALL RM8(uint32_t addr); |
@@ -256,6 +256,8 @@ protected: | ||
256 | 256 | int nsc800_rstc_count; |
257 | 257 | |
258 | 258 | void check_interrupt(); |
259 | + void check_interrupt_standard(); | |
260 | + void check_interrupt_nsc800(); | |
259 | 261 | |
260 | 262 | public: |
261 | 263 | Z80(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) |