h8: Make fully wait-states compatible

This commit is contained in:
Olivier Galibert 2023-05-17 12:28:01 +02:00
parent 78661e9aa9
commit 82c1756aa3
5 changed files with 455 additions and 415 deletions

View file

@ -1,6 +1,19 @@
# license:BSD-3-Clause
# copyright-holders:Olivier Galibert, Devin Acker
macro prefetch_start
NPC = PC & 0xffffff;
PIR = read16i(PC);
PC += 2;
macro prefetch
prefetch_start
prefetch_done();
macro prefetch_noirq
prefetch_start
prefetch_done_noirq();
10000 reset
10001 irq
@ -12,12 +25,12 @@
0380 fff0 0 ldbank r8l bankl g
TMP1 = r8_r(IR[0]) & 0x3f;
m_banknum = (m_banknum & 0xffc0) | TMP1;
prefetch();
prefetch
03c0 fff0 0 ldbank r8l bankh g
TMP1 = r8_r(IR[0]) & 0x3f;
m_banknum = (TMP1 << 6) | (m_banknum & 0x3f);
prefetch();
prefetch
0400 ff00 0 orc imm8 ccr
0500 ff00 0 xorc imm8 ccr
@ -26,15 +39,15 @@
0740 ffc0 0 ldc imm6l ccr g
CCR = IR[0] & 0x3f;
update_irq_filter();
prefetch_noirq();
prefetch_noirq
0780 ffc0 0 ldbank imm6l bankl g
m_banknum = (m_banknum & 0xffc0) | (IR[0] & 0x3f);
prefetch();
prefetch
07c0 ffc0 0 ldbank imm6l bankh g
m_banknum = ((IR[0] & 0x3f) << 6) | (m_banknum & 0x3f);
prefetch();
prefetch
0800 ff00 0 add.b r8h r8l
0900 ff00 0 add.w r16h r16l
@ -114,7 +127,7 @@
internal(1);
m_banknum = ((IR[0] & 0x3f) << 2) | (IR[1] >> 14);
PC = 0x8000 | (IR[1] & 0x3fff);
prefetch();
prefetch
5c00 ff8f 0 jsr r16h -
5c80 ffff 0 jsr abs16e -
@ -131,7 +144,7 @@
67000000 ff8fff0f 0 btst r8h r16ihh
6800 ff80 0 mov.b r16ih r8l g
prefetch_start();
prefetch_start
internal(1);
TMP1 = read8ib(r16_r(IR[0] >> 4));
set_nzv8(TMP1);
@ -139,7 +152,7 @@
prefetch_done();
6900 ff88 0 mov.w r16ih r16l g
prefetch_start();
prefetch_start
internal(1);
TMP1 = read16ib(r16_r(IR[0] >> 4));
set_nzv16(TMP1);
@ -148,7 +161,7 @@
6a00 ff80 0 mov.b r16ph r8l g
TMP2 = r16_r(IR[0] >> 4);
prefetch_start();
prefetch_start
internal(2);
TMP1 = read8ib(TMP2);
TMP2 += 1;
@ -159,7 +172,7 @@
6b00 ff88 0 mov.w r16ph r16l g
TMP2 = r16_r(IR[0] >> 4);
prefetch_start();
prefetch_start
internal(2);
TMP1 = read16ib(TMP2);
TMP2 += 2;
@ -172,7 +185,7 @@
6d00 fff0 0 mov.w abs16 r16l
6e00 ff80 0 mov.b r16d16h r8l g
prefetch_start();
prefetch_start
TMP1 = uint16_t(r16_r(IR[0] >> 4) + IR[1]);
internal(1);
TMP2 = read8ib(TMP1);
@ -181,7 +194,7 @@
prefetch_done();
6f00 ff80 0 mov.w r16d16h r16l g
prefetch_start();
prefetch_start
TMP1 = uint16_t(r16_r(IR[0] >> 4) + IR[1]);
internal(1);
TMP2 = read16ib(TMP1);
@ -199,7 +212,7 @@
77000000 ff00ff0f 0 btst r8h abs8
7800 ff80 0 mov.b r8l r16ih g
prefetch_start();
prefetch_start
TMP1 = r8_r(IR[0]);
set_nzv8(TMP1);
internal(1);
@ -207,7 +220,7 @@
prefetch_done();
7900 ff88 0 mov.w r16l r16ih g
prefetch_start();
prefetch_start
TMP1 = r16_r(IR[0]);
set_nzv16(TMP1);
internal(1);
@ -217,7 +230,7 @@
7a00 ff80 0 mov.b r8l pr16h g
TMP1 = r8_r(IR[0]);
TMP2 = r16_r(IR[0] >> 4);
prefetch_start();
prefetch_start
internal(1);
TMP2 -= 1;
r16_w(IR[0] >> 4, TMP2);
@ -229,7 +242,7 @@
7b00 ff88 0 mov.w r16l pr16h g
TMP1 = r16_r(IR[0]);
TMP2 = r16_r(IR[0] >> 4);
prefetch_start();
prefetch_start
internal(1);
TMP2 -= 2;
r16_w(IR[0] >> 4, TMP2);
@ -242,7 +255,7 @@
7d00 fff0 0 mov.w r16l abs16
7e00 ff80 0 mov.b r8l r16d16h g
prefetch_start();
prefetch_start
TMP1 = uint16_t(r16_r(IR[0] >> 4) + IR[1]);
TMP2 = r8_r(IR[0]);
set_nzv8(TMP2);
@ -251,7 +264,7 @@
prefetch_done();
7f00 ff80 0 mov.w r16l r16d16h g
prefetch_start();
prefetch_start
TMP1 = uint16_t(r16_r(IR[0] >> 4) + IR[1]);
TMP2 = r16_r(IR[0]);
set_nzv16(TMP2);

View file

@ -46,11 +46,11 @@ void h8_device::device_start()
uint32_t pcmask = mode_advanced ? 0xffffff : 0xffff;
state_add<uint32_t>(H8_PC, "PC",
[this]() { return NPC; },
[this](uint32_t pc) { PC = PPC = NPC = pc; prefetch_noirq_notrace(); }
[this](uint32_t pc) { PC = PPC = NPC = pc; PIR = read16i(PC); PC += 2; prefetch_done_noirq_notrace(); }
).mask(pcmask);
state_add<uint32_t>(STATE_GENPC, "GENPC",
[this]() { return NPC; },
[this](uint32_t pc) { PC = PPC = NPC = pc; prefetch_noirq_notrace(); }
[this](uint32_t pc) { PC = PPC = NPC = pc; PIR = read16i(PC); PC += 2; prefetch_done_noirq_notrace(); }
).mask(pcmask).noshow();
state_add(STATE_GENPCBASE, "CURPC", PPC).mask(pcmask).noshow();
state_add(H8_CCR, "CCR", CCR);
@ -361,13 +361,6 @@ uint16_t h8_device::read16i(uint32_t adr)
return cache.read_word(adr & ~1);
}
uint16_t h8_device::fetch()
{
uint16_t res = read16i(PC);
PC += 2;
return res;
}
uint8_t h8_device::read8(uint32_t adr)
{
icount--;

View file

@ -95,6 +95,7 @@ protected:
virtual void device_reset() override;
// device_execute_interface overrides
virtual bool cpu_is_interruptible() const override { return true; }
virtual uint32_t execute_min_cycles() const noexcept override;
virtual uint32_t execute_max_cycles() const noexcept override;
virtual uint32_t execute_input_lines() const noexcept override;
@ -156,17 +157,11 @@ protected:
virtual void irq_setup() = 0;
uint16_t read16i(uint32_t adr);
uint16_t fetch();
inline void fetch(int slot) { IR[slot] = fetch(); }
uint8_t read8(uint32_t adr);
void write8(uint32_t adr, uint8_t data);
uint16_t read16(uint32_t adr);
void write16(uint32_t adr, uint16_t data);
void internal(int cycles);
inline void prefetch() { prefetch_start(); prefetch_done(); }
inline void prefetch_noirq() { prefetch_start(); prefetch_done_noirq(); }
inline void prefetch_noirq_notrace() { prefetch_start(); prefetch_done_noirq_notrace(); }
void prefetch_start() { NPC = PC & 0xffffff; PIR = fetch(); }
void prefetch_switch(uint32_t pc, uint16_t ir) { NPC = pc & 0xffffff; PC = pc+2; PIR = ir; }
void prefetch_done();
void prefetch_done_noirq();

File diff suppressed because it is too large Load diff

View file

@ -52,7 +52,7 @@ def hexsplit(str):
return res
def has_memory(ins):
for s in ["read", "write", "sp_push", "sp_pop", "sp32_push", "sp32_pop", "fetch(", "prefetch_start(", "prefetch(", "prefetch_noirq("]:
for s in ["read", "write"]:
if s in ins:
return True
return False
@ -68,9 +68,16 @@ def save_full_one(f, t, name, source):
substate = 1
for line in source:
if has_memory(line):
print("\tif(icount <= bcount) { inst_substate = %d; return; }" % substate, file=f)
print(line, file=f)
substate += 1
print("\tif(icount <= bcount) {", file=f)
print("\t\tif(access_to_be_redone()) {", file=f)
print("\t\t\ticount++;", file=f)
print("\t\t\tinst_substate = %d;" % substate, file=f)
print("\t\t} else", file=f)
print("\t\t\tinst_substate = %d;" % (substate+1), file=f)
print("\t\treturn;", file=f)
print("\t}", file=f)
substate += 2
elif has_eat(line):
print("\tif(icount) { icount = bcount; } inst_substate = %d; return;" % substate, file=f)
substate += 1
@ -87,11 +94,20 @@ def save_partial_one(f, t, name, source):
substate = 1
for line in source:
if has_memory(line):
print("\tif(icount <= bcount) { inst_substate = %d; return; }" % substate, file=f)
print("\t[[fallthrough]];", file=f)
print("case %d:;" % substate, file=f)
print(line, file=f)
substate += 1
print("\tif(icount <= bcount) {", file=f)
print("\t\tif(access_to_be_redone()) {", file=f)
print("\t\t\ticount++;", file=f)
print("\t\t\tinst_substate = %d;" % substate, file=f)
print("\t\t} else", file=f)
print("\t\t\tinst_substate = %d;" % (substate+1), file=f)
print("\t\treturn;", file=f)
print("\t}", file=f)
print("\t[[fallthrough]];", file=f)
print("case %d:;" % (substate+1), file=f)
substate += 2
elif has_eat(line):
print("\tif(icount) { icount = bcount; } inst_substate = %d; return;" % substate, file=f)
print("case %d:;" % substate, file=f)
@ -156,7 +172,8 @@ class Opcode:
self.extra_words = extra_words
base_offset = len(self.val)/2 + self.skip
for i in range(0, extra_words):
self.source.append("\tfetch(%d);\n" % (i+base_offset))
self.source.append("\tIR[%d] = read16i(PC);" % (i+base_offset))
self.source.append("\tPC += 2;")
def description(self):
return "%s %s %s" % (self.name, self.am1, self.am2)
@ -269,7 +286,8 @@ class DispatchStep:
end = start + self.skip
s = []
for i in range(start, end+1):
s.append("\tIR[%d] = fetch();" % i)
s.append("\tIR[%d] = read16i(PC);" % i)
s.append("\tPC += 2;")
s.append("\tinst_state = 0x%x0000 | IR[%d];" % (self.id, end))
return s