z80: Rewrite the core to handle interruptibility

This commit is contained in:
holub 2023-08-30 05:44:56 -04:00 committed by GitHub
parent 8fbfd4936c
commit a94254a005
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 2656 additions and 3057 deletions

View File

@ -206,7 +206,7 @@ bool kc82_device::memory_translate(int spacenum, int intention, offs_t &address,
// rm - read one byte from memory
//-------------------------------------------------
u8 kc82_device::rm(u16 addr)
u8 kc82_device::data_read(u16 addr)
{
return m_data.read_byte(addr + m_mmu_base[addr >> 10]);
}
@ -216,7 +216,7 @@ u8 kc82_device::rm(u16 addr)
// wm - write one byte to memory
//-------------------------------------------------
void kc82_device::wm(u16 addr, u8 value)
void kc82_device::data_write(u16 addr, u8 value)
{
m_data.write_byte(addr + m_mmu_base[addr >> 10], value);
}
@ -226,10 +226,9 @@ void kc82_device::wm(u16 addr, u8 value)
// rop - read opcode
//-------------------------------------------------
u8 kc82_device::rop()
u8 kc82_device::opcode_read()
{
u32 pc = m_pc.w.l + m_mmu_base[m_pc.b.h >> 2];
m_pc.w.l++;
// no refresh
return m_opcodes.read_byte(pc);
}
@ -239,21 +238,8 @@ u8 kc82_device::rop()
// arg - read 8-bit argument
//-------------------------------------------------
u8 kc82_device::arg()
u8 kc82_device::arg_read()
{
u32 pc = m_pc.w.l + m_mmu_base[m_pc.b.h >> 2];
m_pc.w.l++;
return m_args.read_byte(pc);
}
//-------------------------------------------------
// arg16 - read 16-bit argument
//-------------------------------------------------
u16 kc82_device::arg16()
{
u16 d16 = arg();
d16 |= u16(arg()) << 8;
return d16;
}

View File

@ -41,11 +41,10 @@ protected:
virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// z80_device overrides
virtual u8 rm(u16 addr) override;
virtual void wm(u16 addr, u8 value) override;
virtual u8 rop() override;
virtual u8 arg() override;
virtual u16 arg16() override;
virtual u8 data_read(u16 addr) override;
virtual void data_write(u16 addr, u8 value) override;
virtual u8 opcode_read() override;
virtual u8 arg_read() override;
// MMU access
u8 mmu_r(offs_t offset);

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ enum
NSC800_RSTB,
NSC800_RSTC,
Z80_INPUT_LINE_WAIT,
Z80_INPUT_LINE_BOGUSWAIT, /* WAIT pin implementation used to be nonexistent, please remove this when all drivers are updated with Z80_INPUT_LINE_WAIT */
Z80_INPUT_LINE_BOGUSWAIT, // WAIT pin implementation used to be nonexistent, please remove this when all drivers are updated with Z80_INPUT_LINE_WAIT
Z80_INPUT_LINE_BUSRQ
};
@ -30,10 +30,11 @@ enum
class z80_device : public cpu_device, public z80_daisy_chain_interface
{
public:
z80_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
z80_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
void z80_set_cycle_tables(const uint8_t *op, const uint8_t *cb, const uint8_t *ed, const uint8_t *xy, const uint8_t *xycb, const uint8_t *ex);
void set_mtm_cycles(uint8_t mtm_cycles);
void z80_set_m1_cycles(u8 m1_cycles) { m_m1_cycles = m1_cycles; }
void z80_set_memrq_cycles(u8 memrq_cycles) { m_memrq_cycles = memrq_cycles; }
void z80_set_iorq_cycles(u8 iorq_cycles) { m_iorq_cycles = iorq_cycles; }
template <typename... T> void set_memory_map(T &&... args) { set_addrmap(AS_PROGRAM, std::forward<T>(args)...); }
template <typename... T> void set_m1_map(T &&... args) { set_addrmap(AS_OPCODES, std::forward<T>(args)...); }
template <typename... T> void set_io_map(T &&... args) { set_addrmap(AS_IO, std::forward<T>(args)...); }
@ -43,17 +44,91 @@ public:
auto halt_cb() { return m_halt_cb.bind(); }
protected:
z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
using ops_type = std::vector<std::function<void()>>;
enum op_prefix : u8
{
NONE = 0, CB, DD, ED, FD, XY_CB
};
class op_builder
{
public:
op_builder (z80_device& z80) : m_z80(z80) {};
ops_type get_steps() { return m_steps; }
op_builder * foo(std::function<void()> step) { return this; } // discards content. needed to make macros balanced
op_builder * add(ops_type steps)
{
assert(!steps.empty());
auto to = m_if_condition == nullptr ? &m_steps : &m_if_steps;
to->insert(to->end(), steps.begin(), steps.end());
return this;
}
op_builder * add(std::function<void()> step)
{
auto to = m_if_condition == nullptr ? &m_steps : &m_if_steps;
to->push_back(step);
return this;
}
op_builder * call(std::function<ops_type()> steps) { return add(steps()); }
op_builder * do_if(std::function<bool()> if_condition) { m_if_condition = if_condition; return this; }
op_builder * do_else() { assert(!m_if_steps.empty()); m_else_at = m_if_steps.size(); return this; }
op_builder * edo()
{
assert(!m_if_steps.empty());
auto cond = m_if_condition;
m_if_condition = nullptr;
z80_device& z80 = m_z80;
if (m_else_at)
{
auto steps = m_else_at + 1;
add([&z80, steps, cond](){ if (!cond()) { z80.m_cycle += steps; }});
add({m_if_steps.begin(), m_if_steps.begin() + m_else_at});
steps = m_if_steps.size() - m_else_at;
add([&z80, steps](){ z80.m_cycle += steps; });
add({m_if_steps.begin() + m_else_at, m_if_steps.end()});
m_else_at = 0;
}
else
{
auto steps = m_if_steps.size();
add([&z80, steps, cond](){ if (!cond()) { z80.m_cycle += steps; }});
add(m_if_steps);
}
m_if_steps.clear();
return this;
}
ops_type jump(op_prefix prefix, u8 opcode)
{
z80_device& z80 = m_z80;
add([&z80, prefix, opcode](){ z80.m_cycle = ~0; z80.m_prefix = prefix; z80.m_opcode = opcode; });
return m_steps;
}
ops_type jump(u8 opcode) { return jump(NONE, opcode); }
ops_type build() { add(m_z80.next_op()); return m_steps; }
private:
z80_device& m_z80;
ops_type m_steps;
std::function<bool()> m_if_condition = nullptr;
ops_type m_if_steps;
u8 m_else_at = 0;
};
z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
void init_op_steps();
// device_execute_interface overrides
virtual uint32_t execute_min_cycles() const noexcept override { return 2; }
virtual uint32_t execute_max_cycles() const noexcept override { return 16; }
virtual uint32_t execute_input_lines() const noexcept override { return 4; }
virtual uint32_t execute_default_irq_vector(int inputnum) const noexcept override { return 0xff; }
virtual bool cpu_is_interruptible() const override { return true; }
virtual u32 execute_min_cycles() const noexcept override { return 2; }
virtual u32 execute_max_cycles() const noexcept override { return 16; }
virtual u32 execute_input_lines() const noexcept override { return 4; }
virtual u32 execute_default_irq_vector(int inputnum) const noexcept override { return 0xff; }
virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; }
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
@ -70,175 +145,112 @@ protected:
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
#undef PROTOTYPES
#define PROTOTYPES(prefix) \
void prefix##_00(); void prefix##_01(); void prefix##_02(); void prefix##_03(); \
void prefix##_04(); void prefix##_05(); void prefix##_06(); void prefix##_07(); \
void prefix##_08(); void prefix##_09(); void prefix##_0a(); void prefix##_0b(); \
void prefix##_0c(); void prefix##_0d(); void prefix##_0e(); void prefix##_0f(); \
void prefix##_10(); void prefix##_11(); void prefix##_12(); void prefix##_13(); \
void prefix##_14(); void prefix##_15(); void prefix##_16(); void prefix##_17(); \
void prefix##_18(); void prefix##_19(); void prefix##_1a(); void prefix##_1b(); \
void prefix##_1c(); void prefix##_1d(); void prefix##_1e(); void prefix##_1f(); \
void prefix##_20(); void prefix##_21(); void prefix##_22(); void prefix##_23(); \
void prefix##_24(); void prefix##_25(); void prefix##_26(); void prefix##_27(); \
void prefix##_28(); void prefix##_29(); void prefix##_2a(); void prefix##_2b(); \
void prefix##_2c(); void prefix##_2d(); void prefix##_2e(); void prefix##_2f(); \
void prefix##_30(); void prefix##_31(); void prefix##_32(); void prefix##_33(); \
void prefix##_34(); void prefix##_35(); void prefix##_36(); void prefix##_37(); \
void prefix##_38(); void prefix##_39(); void prefix##_3a(); void prefix##_3b(); \
void prefix##_3c(); void prefix##_3d(); void prefix##_3e(); void prefix##_3f(); \
void prefix##_40(); void prefix##_41(); void prefix##_42(); void prefix##_43(); \
void prefix##_44(); void prefix##_45(); void prefix##_46(); void prefix##_47(); \
void prefix##_48(); void prefix##_49(); void prefix##_4a(); void prefix##_4b(); \
void prefix##_4c(); void prefix##_4d(); void prefix##_4e(); void prefix##_4f(); \
void prefix##_50(); void prefix##_51(); void prefix##_52(); void prefix##_53(); \
void prefix##_54(); void prefix##_55(); void prefix##_56(); void prefix##_57(); \
void prefix##_58(); void prefix##_59(); void prefix##_5a(); void prefix##_5b(); \
void prefix##_5c(); void prefix##_5d(); void prefix##_5e(); void prefix##_5f(); \
void prefix##_60(); void prefix##_61(); void prefix##_62(); void prefix##_63(); \
void prefix##_64(); void prefix##_65(); void prefix##_66(); void prefix##_67(); \
void prefix##_68(); void prefix##_69(); void prefix##_6a(); void prefix##_6b(); \
void prefix##_6c(); void prefix##_6d(); void prefix##_6e(); void prefix##_6f(); \
void prefix##_70(); void prefix##_71(); void prefix##_72(); void prefix##_73(); \
void prefix##_74(); void prefix##_75(); void prefix##_76(); void prefix##_77(); \
void prefix##_78(); void prefix##_79(); void prefix##_7a(); void prefix##_7b(); \
void prefix##_7c(); void prefix##_7d(); void prefix##_7e(); void prefix##_7f(); \
void prefix##_80(); void prefix##_81(); void prefix##_82(); void prefix##_83(); \
void prefix##_84(); void prefix##_85(); void prefix##_86(); void prefix##_87(); \
void prefix##_88(); void prefix##_89(); void prefix##_8a(); void prefix##_8b(); \
void prefix##_8c(); void prefix##_8d(); void prefix##_8e(); void prefix##_8f(); \
void prefix##_90(); void prefix##_91(); void prefix##_92(); void prefix##_93(); \
void prefix##_94(); void prefix##_95(); void prefix##_96(); void prefix##_97(); \
void prefix##_98(); void prefix##_99(); void prefix##_9a(); void prefix##_9b(); \
void prefix##_9c(); void prefix##_9d(); void prefix##_9e(); void prefix##_9f(); \
void prefix##_a0(); void prefix##_a1(); void prefix##_a2(); void prefix##_a3(); \
void prefix##_a4(); void prefix##_a5(); void prefix##_a6(); void prefix##_a7(); \
void prefix##_a8(); void prefix##_a9(); void prefix##_aa(); void prefix##_ab(); \
void prefix##_ac(); void prefix##_ad(); void prefix##_ae(); void prefix##_af(); \
void prefix##_b0(); void prefix##_b1(); void prefix##_b2(); void prefix##_b3(); \
void prefix##_b4(); void prefix##_b5(); void prefix##_b6(); void prefix##_b7(); \
void prefix##_b8(); void prefix##_b9(); void prefix##_ba(); void prefix##_bb(); \
void prefix##_bc(); void prefix##_bd(); void prefix##_be(); void prefix##_bf(); \
void prefix##_c0(); void prefix##_c1(); void prefix##_c2(); void prefix##_c3(); \
void prefix##_c4(); void prefix##_c5(); void prefix##_c6(); void prefix##_c7(); \
void prefix##_c8(); void prefix##_c9(); void prefix##_ca(); void prefix##_cb(); \
void prefix##_cc(); void prefix##_cd(); void prefix##_ce(); void prefix##_cf(); \
void prefix##_d0(); void prefix##_d1(); void prefix##_d2(); void prefix##_d3(); \
void prefix##_d4(); void prefix##_d5(); void prefix##_d6(); void prefix##_d7(); \
void prefix##_d8(); void prefix##_d9(); void prefix##_da(); void prefix##_db(); \
void prefix##_dc(); void prefix##_dd(); void prefix##_de(); void prefix##_df(); \
void prefix##_e0(); void prefix##_e1(); void prefix##_e2(); void prefix##_e3(); \
void prefix##_e4(); void prefix##_e5(); void prefix##_e6(); void prefix##_e7(); \
void prefix##_e8(); void prefix##_e9(); void prefix##_ea(); void prefix##_eb(); \
void prefix##_ec(); void prefix##_ed(); void prefix##_ee(); void prefix##_ef(); \
void prefix##_f0(); void prefix##_f1(); void prefix##_f2(); void prefix##_f3(); \
void prefix##_f4(); void prefix##_f5(); void prefix##_f6(); void prefix##_f7(); \
void prefix##_f8(); void prefix##_f9(); void prefix##_fa(); void prefix##_fb(); \
void prefix##_fc(); void prefix##_fd(); void prefix##_fe(); void prefix##_ff();
void execute_cycles(u8 icount);
void halt();
void leave_halt();
virtual u8 data_read(u16 addr);
virtual void data_write(u16 addr, u8 value);
virtual u8 opcode_read();
virtual u8 arg_read();
/* deprecated */ void rm16(u16 addr, PAIR &r);
/* deprecated */ void wm16_sp(PAIR &r);
void illegal_1();
void illegal_2();
ops_type in();
ops_type out();
ops_type rm();
ops_type rm_reg();
ops_type rm16();
ops_type wm();
ops_type wm16();
ops_type wm16_sp();
ops_type rop();
ops_type arg();
ops_type arg16();
PROTOTYPES(op)
PROTOTYPES(cb)
PROTOTYPES(dd)
PROTOTYPES(ed)
PROTOTYPES(fd)
PROTOTYPES(xycb)
void halt();
void leave_halt();
uint8_t in(uint16_t port);
void out(uint16_t port, uint8_t value);
virtual uint8_t rm(uint16_t addr);
uint8_t rm_reg(uint16_t addr);
void rm16(uint16_t addr, PAIR &r);
virtual void wm(uint16_t addr, uint8_t value);
void wm16(uint16_t addr, PAIR &r);
void wm16_sp(PAIR &r);
virtual uint8_t rop();
virtual uint8_t arg();
virtual uint16_t arg16();
void eax();
void eay();
void pop(PAIR &r);
void push(PAIR &r);
void jp(void);
void jp_cond(bool cond);
void jr();
void jr_cond(bool cond, uint8_t opcode);
void call();
void call_cond(bool cond, uint8_t opcode);
void ret_cond(bool cond, uint8_t opcode);
void retn();
void reti();
void ld_r_a();
void ld_a_r();
void ld_i_a();
void ld_a_i();
void rst(uint16_t addr);
uint8_t inc(uint8_t value);
uint8_t dec(uint8_t value);
ops_type eax();
ops_type eay();
ops_type push();
ops_type pop();
ops_type jp();
ops_type jp_cond();
ops_type jr();
ops_type jr_cond(u8 opcode);
ops_type call();
ops_type call_cond(u8 opcode);
ops_type ret_cond(u8 opcode);
ops_type retn();
ops_type reti();
ops_type ld_r_a();
ops_type ld_a_r();
ops_type ld_i_a();
ops_type ld_a_i();
ops_type rst(u16 addr);
void inc(u8 &r);
void dec(u8 &r);
void rlca();
void rrca();
void rla();
void rra();
void rrd();
void rld();
void add_a(uint8_t value);
void adc_a(uint8_t value);
void sub(uint8_t value);
void sbc_a(uint8_t value);
ops_type rrd();
ops_type rld();
void add_a(u8 value);
void adc_a(u8 value);
void sub(u8 value);
void sbc_a(u8 value);
void neg();
void daa();
void and_a(uint8_t value);
void or_a(uint8_t value);
void xor_a(uint8_t value);
void cp(uint8_t value);
void ex_af();
void ex_de_hl();
void and_a(u8 value);
void or_a(u8 value);
void xor_a(u8 value);
void cp(u8 value);
void exx();
void ex_sp(PAIR &r);
void add16(PAIR &dr, PAIR &sr);
void adc_hl(PAIR &r);
void sbc_hl(PAIR &r);
uint8_t rlc(uint8_t value);
uint8_t rrc(uint8_t value);
uint8_t rl(uint8_t value);
uint8_t rr(uint8_t value);
uint8_t sla(uint8_t value);
uint8_t sra(uint8_t value);
uint8_t sll(uint8_t value);
uint8_t srl(uint8_t value);
void bit(int bit, uint8_t value);
void bit_hl(int bit, uint8_t value);
void bit_xy(int bit, uint8_t value);
uint8_t res(int bit, uint8_t value);
uint8_t set(int bit, uint8_t value);
void ldi();
void cpi();
void ini();
void outi();
void ldd();
void cpd();
void ind();
void outd();
void ldir();
void cpir();
void inir();
void otir();
void lddr();
void cpdr();
void indr();
void otdr();
ops_type ex_sp();
ops_type add16();
ops_type adc_hl();
ops_type sbc_hl();
u8 rlc(u8 value);
u8 rrc(u8 value);
u8 rl(u8 value);
u8 rr(u8 value);
u8 sla(u8 value);
u8 sra(u8 value);
u8 sll(u8 value);
u8 srl(u8 value);
void bit(int bit, u8 value);
void bit_hl(int bit, u8 value);
void bit_xy(int bit, u8 value);
u8 res(int bit, u8 value);
u8 set(int bit, u8 value);
ops_type ldi();
ops_type cpi();
ops_type ini();
ops_type outi();
ops_type ldd();
ops_type cpd();
ops_type ind();
ops_type outd();
ops_type ldir();
ops_type cpir();
ops_type inir();
ops_type otir();
ops_type lddr();
ops_type cpdr();
ops_type indr();
ops_type otdr();
void ei();
void set_f(u8 f);
void block_io_interrupted_flags();
ops_type next_op();
virtual void check_interrupts();
void take_interrupt();
void take_nmi();
void nomreq_ir(s8 cycles);
void nomreq_addr(u16 addr, s8 cycles);
ops_type nomreq_ir(s8 cycles);
ops_type nomreq_addr(s8 cycles);
// address spaces
const address_space_config m_program_config;
@ -268,32 +280,38 @@ protected:
PAIR m_bc2;
PAIR m_de2;
PAIR m_hl2;
uint8_t m_r;
uint8_t m_r2;
uint8_t m_iff1;
uint8_t m_iff2;
uint8_t m_halt;
uint8_t m_im;
uint8_t m_i;
uint8_t m_nmi_state; /* nmi line state */
uint8_t m_nmi_pending; /* nmi pending */
uint8_t m_irq_state; /* irq line state */
u8 m_qtemp;
u8 m_q;
u8 m_r;
u8 m_r2;
u8 m_iff1;
u8 m_iff2;
u8 m_halt;
u8 m_im;
u8 m_i;
u8 m_nmi_state; // nmi line state
u8 m_nmi_pending; // nmi pending
u8 m_irq_state; // irq line state
int m_wait_state; // wait line state
int m_busrq_state; // bus request line state
uint8_t m_after_ei; /* are we in the EI shadow? */
uint8_t m_after_ldair; /* same, but for LD A,I or LD A,R */
uint32_t m_ea;
u8 m_after_ei; // are we in the EI shadow?
u8 m_after_ldair; // same, but for LD A,I or LD A,R
u32 m_ea;
u8 m_cycle;
op_prefix m_prefix;
u8 m_opcode;
int m_icount;
int m_icount_executing;
uint8_t m_rtemp;
const uint8_t * m_cc_op;
const uint8_t * m_cc_cb;
const uint8_t * m_cc_ed;
const uint8_t * m_cc_xy;
const uint8_t * m_cc_xycb;
const uint8_t * m_cc_ex;
uint8_t m_mtm_cycles;
PAIR16 m_m_shared_addr;
PAIR16 m_m_shared_data;
PAIR16 m_m_shared_data2;
u8 m_rtemp;
ops_type m_op_steps[6][0x100];
u8 m_m1_cycles = 4;
u8 m_memrq_cycles = 3;
u8 m_iorq_cycles = 4;
};
DECLARE_DEVICE_TYPE(Z80, z80_device)
@ -301,7 +319,7 @@ DECLARE_DEVICE_TYPE(Z80, z80_device)
class nsc800_device : public z80_device
{
public:
nsc800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
nsc800_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
// device-level overrides
@ -309,12 +327,12 @@ protected:
virtual void device_reset() override;
// device_execute_interface overrides
virtual uint32_t execute_input_lines() const noexcept override { return 7; }
virtual u32 execute_input_lines() const noexcept override { return 7; }
virtual void execute_set_input(int inputnum, int state) override;
virtual void check_interrupts() override;
void take_interrupt_nsc800();
uint8_t m_nsc800_irq_state[4]; /* state of NSC800 restart interrupts A, B, C */
u8 m_nsc800_irq_state[4]; // state of NSC800 restart interrupts A, B, C
};
DECLARE_DEVICE_TYPE(NSC800, nsc800_device)

View File

@ -93,10 +93,10 @@ Some bugs left :
#include "amstrad.h"
/* Components */
#include "machine/i8255.h" /* for 8255 ppi */
#include "cpu/z80/z80.h" /* for cycle tables */
#include "video/mc6845.h" /* CRTC */
#include "machine/upd765.h" /* for floppy disc controller */
#include "machine/i8255.h" /* for 8255 ppi */
#include "cpu/z80/z80.h" /* for cycle tables */
#include "video/mc6845.h" /* CRTC */
#include "machine/upd765.h" /* for floppy disc controller */
#include "sound/ay8910.h"
#include "machine/mc146818.h" /* Aleste RTC */
#include "bus/centronics/ctronics.h"
@ -121,19 +121,11 @@ Some bugs left :
#define SYSTEM_GX4000 2
/* Memory is banked in 16k blocks. However, the multiface
pages the memory in 8k blocks! The ROM can
be paged into bank 0 and bank 3. */
/* Memory is banked in 16k blocks. However, the multiface pages the memory in 8k blocks!
The ROM can be paged into bank 0 and bank 3. */
void amstrad_state::amstrad_mem(address_map &map)
{
map(0x00000, 0x01fff).bankr("bank1").bankw("bank9");
map(0x02000, 0x03fff).bankr("bank2").bankw("bank10");
map(0x04000, 0x05fff).bankr("bank3").bankw("bank11");
map(0x06000, 0x07fff).bankr("bank4").bankw("bank12");
map(0x08000, 0x09fff).bankr("bank5").bankw("bank13");
map(0x0a000, 0x0bfff).bankr("bank6").bankw("bank14");
map(0x0c000, 0x0dfff).bankr("bank7").bankw("bank15");
map(0x0e000, 0x0ffff).bankr("bank8").bankw("bank16");
map(0x0000, 0xffff).rw(FUNC(amstrad_state::amstrad_cpc_mem_r), FUNC(amstrad_state::amstrad_cpc_mem_w));
}
/* I've handled the I/O ports in this way, because the ports
@ -153,9 +145,9 @@ void amstrad_state::amstrad_io(address_map &map)
static INPUT_PORTS_START( amstrad_keyboard )
PORT_START("kbrow.0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
@ -163,7 +155,7 @@ static INPUT_PORTS_START( amstrad_keyboard )
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))
PORT_START("kbrow.1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Copy") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END))
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
@ -343,8 +335,8 @@ static INPUT_PORTS_START( amx_mouse )
PORT_BIT(0xff , 0, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02)
PORT_START("mouse_input3")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("Left mouse button") PORT_CODE(MOUSECODE_BUTTON1) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02)
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("Left mouse button") PORT_CODE(MOUSECODE_BUTTON1) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_NAME("Middle mouse button") PORT_CODE(MOUSECODE_BUTTON3) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02)
PORT_START("controller_type")
@ -1200,8 +1192,7 @@ void amstrad_state::aleste(machine_config &config)
/* cpc6128.rom contains OS in first 16k, BASIC in second 16k */
/* cpcados.rom contains Amstrad DOS */
/* I am loading the roms outside of the Z80 memory area, because they
are banked. */
/* I am loading the roms outside of the Z80 memory area, because they are banked. */
ROM_START( cpc6128 )
/* this defines the total memory size - 64k ram, 16k OS, 16k BASIC, 16k DOS */
ROM_REGION(0x020000, "maincpu", 0)
@ -1212,7 +1203,7 @@ ROM_END
ROM_START( cpc6128f )
/* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k*/
/* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k */
ROM_REGION(0x020000, "maincpu", 0)
/* load the os to offset 0x01000 from memory base */
@ -1222,7 +1213,7 @@ ROM_END
ROM_START( cpc6128s )
/* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k*/
/* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k */
ROM_REGION(0x020000, "maincpu", 0)
/* load the os to offset 0x01000 from memory base */
@ -1231,7 +1222,7 @@ ROM_START( cpc6128s )
ROM_END
ROM_START( cpc6128sp )
/* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k*/
/* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k */
ROM_REGION(0x020000, "maincpu", 0)
/* load the os to offset 0x01000 from memory base */
@ -1309,15 +1300,16 @@ ROM_END
*
*************************************/
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1984, cpc464, 0, 0, cpc464, cpc464, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464", 0 )
COMP( 1985, cpc664, cpc464, 0, cpc664, cpc664, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC664", 0 )
COMP( 1985, cpc6128, cpc464, 0, cpc6128, cpc6128, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128", 0 )
COMP( 1985, cpc6128f, cpc464, 0, cpc6128, cpc6128f, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (France, AZERTY Keyboard)", 0 )
COMP( 1985, cpc6128s, cpc464, 0, cpc6128, cpc6128s, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Sweden/Finland)", 0 )
COMP( 1985, cpc6128sp, cpc464, 0, cpc6128, cpc6128sp, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Spain)", 0 )
COMP( 1990, cpc464p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464+", 0 )
COMP( 1990, cpc6128p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128+", 0 )
CONS( 1990, gx4000, 0, 0, gx4000, gx4000, amstrad_state, empty_init, "Amstrad plc", "Amstrad GX4000", 0 )
COMP( 1989, kccomp, cpc464, 0, kccomp, kccomp, amstrad_state, empty_init, u8"VEB Mikroelektronik \"Wilhelm Pieck\" Mühlhausen", "KC Compact", 0 )
COMP( 1993, al520ex, cpc464, 0, aleste, aleste, amstrad_state, empty_init, "Patisonic", "Aleste 520EX", MACHINE_IMPERFECT_SOUND )
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1984, cpc464, 0, 0, cpc464, cpc464, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464", 0 )
COMP( 1985, cpc664, cpc464, 0, cpc664, cpc664, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC664", 0 )
COMP( 1985, cpc6128, cpc464, 0, cpc6128, cpc6128, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128", 0 )
COMP( 1985, cpc6128f, cpc464, 0, cpc6128, cpc6128f, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (France, AZERTY Keyboard)", 0 )
COMP( 1985, cpc6128s, cpc464, 0, cpc6128, cpc6128s, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Sweden/Finland)", 0 )
COMP( 1985, cpc6128sp, cpc464, 0, cpc6128, cpc6128sp, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Spain)", 0 )
COMP( 1990, cpc464p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464+", 0 )
COMP( 1990, cpc6128p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128+", 0 )
CONS( 1990, gx4000, 0, 0, gx4000, gx4000, amstrad_state, empty_init, "Amstrad plc", "Amstrad GX4000", 0 )
COMP( 1989, kccomp, cpc464, 0, kccomp, kccomp, amstrad_state, empty_init, u8"VEB Mikroelektronik \"Wilhelm Pieck\" Mühlhausen",
"KC Compact", 0 )
COMP( 1993, al520ex, cpc464, 0, aleste, aleste, amstrad_state, empty_init, "Patisonic", "Aleste 520EX", MACHINE_IMPERFECT_SOUND )

View File

@ -211,6 +211,8 @@ private:
void aleste_msx_mapper(offs_t offset, uint8_t data);
uint8_t amstrad_cpc_io_r(offs_t offset);
void amstrad_cpc_io_w(offs_t offset, uint8_t data);
uint8_t amstrad_cpc_mem_r(offs_t offset);
void amstrad_cpc_mem_w(offs_t offset, uint8_t data);
uint8_t amstrad_psg_porta_read();
void amstrad_plus_seqcheck(int data);
DECLARE_MACHINE_START(amstrad);
@ -266,7 +268,7 @@ private:
required_memory_region m_region_maincpu;
optional_memory_region m_region_user1;
required_memory_bank_array<16> m_banks;
memory_bank_array_creator<16> m_banks;
optional_ioport_array<11> m_io_kbrow;
optional_ioport_array<4> m_io_analog;
optional_ioport_array<3> m_io_mouse;

View File

@ -31,8 +31,14 @@ the name I give to the time taken for one NOP command to execute.
This happens to be 1us.
From measurement, there are 64 NOPs per line, with 312 lines per screen.
This gives a total of 19968 NOPs per frame.
Timings:
From measurement, there are 64 NOPs per line, with 312 lines per screen. This
gives a total of 19968 NOPs per frame.
The Amstrad hardware issues a HALT for each memory fetch. This has the effect
of stretching the timing for Z80 opcodes, so that they are all multiple of 4 T
states long. All opcode timings are a multiple of 1us in length.
***************************************************************************/
@ -97,14 +103,14 @@ static const uint8_t asic_unlock_seq[15] =
The following tables show the possible ram configurations :*/
static const int RamConfigurations[8 * 4] =
{
0, 1, 2, 3, /* config 0 */
0, 1, 2, 7, /* config 1 */
4, 5, 6, 7, /* config 2 */
0, 3, 2, 7, /* config 3 */
0, 4, 2, 3, /* config 4 */
0, 5, 2, 3, /* config 5 */
0, 6, 2, 3, /* config 6 */
0, 7, 2, 3 /* config 7 */
0, 1, 2, 3, /* config 0 */
0, 1, 2, 7, /* config 1 */
4, 5, 6, 7, /* config 2 */
0, 3, 2, 7, /* config 3 */
0, 4, 2, 3, /* config 4 */
0, 5, 2, 3, /* config 5 */
0, 6, 2, 3, /* config 6 */
0, 7, 2, 3 /* config 7 */
};
@ -165,32 +171,32 @@ static const rgb_t amstrad_green_palette[32] =
rgb_t(0x000, 0x07F, 0x000), /*13*/
rgb_t(0x000, 0x0BA, 0x000), /*19*/
rgb_t(0x000, 0x0F5, 0x000), /*25*/
rgb_t(0x000, 0x009, 0x000), /*1*/
rgb_t(0x000, 0x044, 0x000), /*7*/
rgb_t(0x000, 0x009, 0x000), /* 1*/
rgb_t(0x000, 0x044, 0x000), /* 7*/
rgb_t(0x000, 0x062, 0x000), /*10*/
rgb_t(0x000, 0x09C, 0x000), /*16*/
rgb_t(0x000, 0x044, 0x000), /*7*/
rgb_t(0x000, 0x044, 0x000), /* 7*/
rgb_t(0x000, 0x0F5, 0x000), /*25*/
rgb_t(0x000, 0x0EB, 0x000), /*24*/
rgb_t(0x000, 0x0FF, 0x000), /*26*/
rgb_t(0x000, 0x03A, 0x000), /*6*/
rgb_t(0x000, 0x04E, 0x000), /*8*/
rgb_t(0x000, 0x03A, 0x000), /* 6*/
rgb_t(0x000, 0x04E, 0x000), /* 8*/
rgb_t(0x000, 0x093, 0x000), /*15*/
rgb_t(0x000, 0x0A6, 0x000), /*17*/
rgb_t(0x000, 0x009, 0x000), /*1*/
rgb_t(0x000, 0x009, 0x000), /* 1*/
rgb_t(0x000, 0x0BA, 0x000), /*19*/
rgb_t(0x000, 0x0B0, 0x000), /*18*/
rgb_t(0x000, 0x0C4, 0x000), /*20*/
rgb_t(0x000, 0x000, 0x000), /*0*/
rgb_t(0x000, 0x013, 0x000), /*2*/
rgb_t(0x000, 0x058, 0x000), /*9*/
rgb_t(0x000, 0x000, 0x000), /* 0*/
rgb_t(0x000, 0x013, 0x000), /* 2*/
rgb_t(0x000, 0x058, 0x000), /* 9*/
rgb_t(0x000, 0x06B, 0x000), /*11*/
rgb_t(0x000, 0x027, 0x000), /*4*/
rgb_t(0x000, 0x027, 0x000), /* 4*/
rgb_t(0x000, 0x0D7, 0x000), /*22*/
rgb_t(0x000, 0x0CD, 0x000), /*21*/
rgb_t(0x000, 0x0E1, 0x000), /*23*/
rgb_t(0x000, 0x01D, 0x000), /*3*/
rgb_t(0x000, 0x031, 0x000), /*5*/
rgb_t(0x000, 0x01D, 0x000), /* 3*/
rgb_t(0x000, 0x031, 0x000), /* 5*/
rgb_t(0x000, 0x075, 0x000), /*12*/
rgb_t(0x000, 0x089, 0x000) /*14*/
};
@ -2174,6 +2180,18 @@ The exception is the case where none of b7-b0 are reset (i.e. port &FBFF), which
}
}
uint8_t amstrad_state::amstrad_cpc_mem_r(offs_t offset)
{
if (!machine().side_effects_disabled())
m_maincpu->adjust_icount(-((4 - m_maincpu->total_cycles() % 4) % 4));
return ((u8*)m_banks[(offset >> 13)]->base())[offset & 0x1fff];
}
void amstrad_state::amstrad_cpc_mem_w(offs_t offset, uint8_t data)
{
m_maincpu->adjust_icount(-((4 - m_maincpu->total_cycles() % 4) % 4));
((u8*)m_banks[(offset >> 13) + 8]->base())[offset & 0x1fff] = data;
}
/* load CPCEMU style snapshots */
void amstrad_state::amstrad_handle_snapshot(unsigned char *pSnapshot)
@ -2766,125 +2784,6 @@ IRQ_CALLBACK_MEMBER(amstrad_state::amstrad_cpu_acknowledge_int)
}
/* the following timings have been measured! */
static const uint8_t amstrad_cycle_table_op[256] = {
4, 12, 8, 8, 4, 4, 8, 4, 4, 12, 8, 8, 4, 4, 8, 4,
12, 12, 8, 8, 4, 4, 8, 4, 12, 12, 8, 8, 4, 4, 8, 4,
8, 12, 20, 8, 4, 4, 8, 4, 8, 12, 20, 8, 4, 4, 8, 4,
8, 12, 16, 8, 12, 12, 12, 4, 8, 12, 16, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 8, 8, 8, 8, 8, 4, 8, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 12, 12, 12, 12, 16, 8, 16, 8, 12, 12, 4, 12, 20, 8, 16,
8, 12, 12, 12, 12, 16, 8, 16, 8, 4, 12, 12, 12, 4, 8, 16,
8, 12, 12, 24, 12, 16, 8, 16, 8, 4, 12, 4, 12, 4, 8, 16,
8, 12, 12, 4, 12, 16, 8, 16, 8, 8, 12, 4, 12, 4, 8, 16
};
static const uint8_t amstrad_cycle_table_cb[256]=
{
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4,
4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4
};
static const uint8_t amstrad_cycle_table_ed[256]=
{
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
12, 12, 12, 20, 4, 12, 4, 8, 12, 12, 12, 20, 4, 12, 4, 8,
12, 12, 12, 20, 4, 12, 4, 8, 12, 12, 12, 20, 4, 12, 4, 8,
12, 12, 12, 20, 4, 12, 4, 16, 12, 12, 12, 20, 4, 12, 4, 16,
12, 12, 12, 20, 4, 12, 4, 4, 12, 12, 12, 20, 4, 12, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
16, 12, 16, 16, 4, 4, 4, 4, 16, 12, 16, 16, 4, 4, 4, 4,
16, 12, 16, 16, 4, 4, 4, 4, 16, 12, 16, 16, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
};
static const uint8_t amstrad_cycle_table_xy[256]=
{
4, 12, 8, 8, 4, 4, 8, 4, 4, 12, 8, 8, 4, 4, 8, 4,
12, 12, 8, 8, 4, 4, 8, 4, 12, 12, 8, 8, 4, 4, 8, 4,
8, 12, 20, 8, 4, 4, 8, 4, 8, 12, 20, 8, 4, 4, 8, 4,
8, 12, 16, 8, 20, 20, 20, 4, 8, 12, 16, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4,
4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4,
4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4,
16, 16, 16, 16, 16, 16, 4, 16, 4, 4, 4, 4, 4, 4, 16, 4,
4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4,
4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4,
4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4,
4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4,
8, 12, 12, 12, 12, 16, 8, 16, 8, 12, 12, 8, 12, 20, 8, 16,
8, 12, 12, 12, 12, 16, 8, 16, 8, 4, 12, 12, 12, 4, 8, 16,
8, 12, 12, 24, 12, 16, 8, 16, 8, 4, 12, 4, 12, 4, 8, 16,
8, 12, 12, 4, 12, 16, 8, 16, 8, 8, 12, 4, 12, 4, 8, 16
};
static const uint8_t amstrad_cycle_table_xycb[0x100] = {
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16
};
static const uint8_t amstrad_cycle_table_ex[256]=
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 8, 4, 4, 0, 0, 0, 0, 4, 8, 4, 4, 0, 0, 0, 0,
8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0,
8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0,
8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0,
8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0
};
#define NEXT_ROM_SLOT m_rom_count++; \
if(slot3 && m_rom_count == 3) m_rom_count++; \
if(slot7 && m_rom_count == 7) m_rom_count++;
@ -3036,26 +2935,6 @@ void amstrad_state::amstrad_common_init()
m_maincpu->set_input_line_vector(0, 0xff); // Z80
else
m_maincpu->set_input_line_vector(0, 0x00); // Z80
/* The opcode timing in the Amstrad is different to the opcode
timing in the core for the Z80 CPU.
The Amstrad hardware issues a HALT for each memory fetch.
This has the effect of stretching the timing for Z80 opcodes,
so that they are all multiple of 4 T states long. All opcode
timings are a multiple of 1us in length. */
/* Using the cool code Juergen has provided, I will override
the timing tables with the values for the amstrad */
m_maincpu->z80_set_cycle_tables(
(const uint8_t*)amstrad_cycle_table_op,
(const uint8_t*)amstrad_cycle_table_cb,
(const uint8_t*)amstrad_cycle_table_ed,
(const uint8_t*)amstrad_cycle_table_xy,
(const uint8_t*)amstrad_cycle_table_xycb,
(const uint8_t*)amstrad_cycle_table_ex);
/* Juergen is a cool dude! */
}
TIMER_CALLBACK_MEMBER(amstrad_state::cb_set_resolution)

View File

@ -314,108 +314,10 @@ void msx_state::machine_start()
m_port_c_old = 0xff;
}
// Update instruction timings to add 1 wait cycle for each M1 opcode fetch.
static const u8 cc_op[0x100] = {
4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1,
7+1,10+1,13+1, 6+1,11+1,11+1,10+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
7+1, 7+1, 7+1, 7+1, 7+1, 7+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 4+1,10+1,17+1, 7+1,11+1,
5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 4+1, 7+1,11+1,
5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 4+1, 7+1,11+1,
5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 4+1, 7+1,11+1
};
static const u8 cc_cb[0x100] = {
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1
};
static const u8 cc_ed[0x100] = {
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1,
8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1,
8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1,14+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1,14+1,
8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 4+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1,12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1,
12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1,12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1
};
static const u8 cc_xy[0x100] = {
4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1,
7+1,10+1,13+1, 6+1,19+1,19+1,15+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
15+1,15+1,15+1,15+1,15+1,15+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1,
5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 7+1,10+1,17+1, 7+1,11+1,
5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 4+1, 7+1,11+1,
5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 4+1, 7+1,11+1,
5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 4+1, 7+1,11+1
};
/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
static const u8 cc_ex[0x100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DJNZ */
5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NZ/JR Z */
5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NC/JR C */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2+1
};
void msx_state::driver_start()
{
m_maincpu->set_input_line_vector(0, 0xff); // Z80
m_maincpu->z80_set_cycle_tables(cc_op, cc_cb, cc_ed, cc_xy, nullptr, cc_ex);
m_maincpu->z80_set_m1_cycles(5);
save_item(NAME(m_psg_b));
save_item(NAME(m_kanji_latch));

View File

@ -301,6 +301,14 @@ and bonus options). There is no screen which shows the bonus lives values like
other two sets, either. flickys1 allows for DEMO SOUND which none of the others sets
seem to have access to.
About main CPU clocking:
A 20MHz crystal clocks an LS161 which counts up from either 10 or 11 to 16 before
carrying out and forcing a reload. The low bit of the reload value comes from the
Z80's /M1 signal. When /M1 is low (an opcode is being fetched), the reload count
is 10, which means the 20MHz clock is divided by 6. When /M1 is high, the reload
count is 11, which means the clock is divided by 5.
******************************************************************************/
#include "emu.h"
@ -322,135 +330,6 @@ seem to have access to.
*
*************************************/
/*
About main CPU clocking:
A 20MHz crystal clocks an LS161 which counts up from either 10 or 11 to 16 before
carrying out and forcing a reload. The low bit of the reload value comes from the
Z80's /M1 signal. When /M1 is low (an opcode is being fetched), the reload count
is 10, which means the 20MHz clock is divided by 6. When /M1 is high, the reload
count is 11, which means the clock is divided by 5.
To account for this, we install custom cycle tables for the Z80. We clock the Z80
at 20MHz and count 5 cycles for each original Z80 cycle, plus an extra 2 cycles for
each opcode fetch (since the M1 line is low for 2 cycles per byte).
*/
static const u8 cc_op[0x100] = {
4*5+1*2,10*5+3*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
8*5+2*2,10*5+3*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,12*5+2*2,11*5+1*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
7*5+2*2,10*5+3*2,16*5+3*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2, 7*5+2*2,11*5+1*2,16*5+3*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
7*5+2*2,10*5+3*2,13*5+3*2, 6*5+1*2,11*5+1*2,11*5+1*2,10*5+2*2, 4*5+1*2, 7*5+2*2,11*5+1*2,13*5+3*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
7*5+1*2, 7*5+1*2, 7*5+1*2, 7*5+1*2, 7*5+1*2, 7*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+1*2, 4*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2,10*5+3*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2,10*5+1*2,10*5+3*2, 4*5+1*2,10*5+3*2,17*5+3*2, 7*5+2*2,11*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2,11*5+2*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2, 4*5+1*2,10*5+3*2,11*5+2*2,10*5+3*2, 4*5+1*2, 7*5+2*2,11*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2,19*5+1*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2, 4*5+1*2,10*5+3*2, 4*5+1*2,10*5+3*2, 4*5+1*2, 7*5+2*2,11*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2, 4*5+1*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2, 6*5+1*2,10*5+3*2, 4*5+1*2,10*5+3*2, 4*5+1*2, 7*5+2*2,11*5+1*2
};
static const u8 cc_cb[0x100] = {
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 4*5+1*2
};
static const u8 cc_ed[0x100] = {
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2, 5*5+1*2, 8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2, 5*5+1*2,
8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2, 5*5+1*2, 8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2, 5*5+1*2,
8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2,14*5+1*2, 8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2,14*5+1*2,
8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2, 4*5+1*2, 8*5+1*2, 8*5+1*2,11*5+1*2,16*5+3*2, 4*5+1*2,14*5+2*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
12*5+1*2,12*5+1*2,12*5+1*2,12*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,12*5+1*2,12*5+1*2,12*5+1*2,12*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
12*5+1*2,12*5+1*2,12*5+1*2,12*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,12*5+1*2,12*5+1*2,12*5+1*2,12*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2
};
static const u8 cc_xy[0x100] = {
4*5+1*2,10*5+3*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2, 4*5+1*2,11*5+1*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
8*5+2*2,10*5+3*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,12*5+2*2,11*5+1*2, 7*5+1*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
7*5+2*2,10*5+3*2,16*5+3*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2, 7*5+2*2,11*5+1*2,16*5+3*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
7*5+2*2,10*5+3*2,13*5+3*2, 6*5+1*2,19*5+2*2,19*5+2*2,15*5+3*2, 4*5+1*2, 7*5+2*2,11*5+1*2,13*5+3*2, 6*5+1*2, 4*5+1*2, 4*5+1*2, 7*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
15*5+2*2,15*5+2*2,15*5+2*2,15*5+2*2,15*5+2*2,15*5+2*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2, 4*5+1*2,15*5+2*2, 4*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2,10*5+3*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2,10*5+1*2,10*5+3*2, 7*5+1*2,10*5+3*2,17*5+3*2, 7*5+2*2,11*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2,11*5+2*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2, 4*5+1*2,10*5+3*2,11*5+2*2,10*5+3*2, 4*5+1*2, 7*5+2*2,11*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2,19*5+1*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2, 4*5+1*2,10*5+3*2, 4*5+1*2,10*5+3*2, 4*5+1*2, 7*5+2*2,11*5+1*2,
5*5+1*2,10*5+1*2,10*5+3*2, 4*5+1*2,10*5+3*2,11*5+1*2, 7*5+2*2,11*5+1*2, 5*5+1*2, 6*5+1*2,10*5+3*2, 4*5+1*2,10*5+3*2, 4*5+1*2, 7*5+2*2,11*5+1*2
};
static const u8 cc_xycb[0x100] = {
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5,
9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5,
9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5,
9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5, 9*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,
12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5,12*5
};
/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
static const u8 cc_ex[0x100] = {
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
5*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, /* DJNZ */
5*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 5*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, /* JR NZ/JR Z */
5*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 5*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, /* JR NC/JR C */
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5, 0*5,
5*5, 5*5, 5*5, 5*5, 0*5, 0*5, 0*5, 0*5, 5*5, 5*5, 5*5, 5*5, 0*5, 0*5, 0*5, 0*5, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5, 6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5,
6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5, 6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5,
6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5, 6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5,
6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5, 6*5, 0*5, 0*5, 0*5, 7*5, 0*5, 0*5, 2*5
};
void system1_state::machine_start()
{
const u32 numbanks = (m_maincpu_region->bytes() - 0x10000) / 0x4000;
@ -468,13 +347,12 @@ void system1_state::machine_start()
m_bank1d->set_entry(0);
}
m_maincpu->z80_set_cycle_tables(cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex);
m_maincpu->set_mtm_cycles(3*5);
m_mute_xor = 0x00;
m_dakkochn_mux_data = 0x00;
m_m1_num = 0;
save_item(NAME(m_dakkochn_mux_data));
save_item(NAME(m_m1_num));
save_item(NAME(m_videomode_prev));
save_item(NAME(m_mcu_control));
save_item(NAME(m_nob_maincpu_latch));
@ -2276,10 +2154,18 @@ GFXDECODE_END
void system1_state::sys1ppi(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, MASTER_CLOCK); /* not really, see notes above */
Z80(config, m_maincpu, MASTER_CLOCK / 5);
m_maincpu->set_addrmap(AS_PROGRAM, &system1_state::system1_map);
m_maincpu->set_addrmap(AS_IO, &system1_state::system1_ppi_io_map);
m_maincpu->set_vblank_int("screen", FUNC(system1_state::irq0_line_hold));
/* Lord Nightmare:
the divider is 5 for any z80 cycle that M1 is high, and 6 if M1 is low
since M1 is low for 2 cycles during opcode fetch, this makes every opcode fetch take an extra 2 20mhz clocks */
m_maincpu->refresh_cb().set([this](offs_t offset, u8 data) {
m_m1_num = (m_m1_num + 1) % 5;
if (m_m1_num == 2)
m_maincpu->adjust_icount(-1);
});
Z80(config, m_soundcpu, SOUND_CLOCK/2);
m_soundcpu->set_addrmap(AS_PROGRAM, &system1_state::sound_map);
@ -5610,9 +5496,6 @@ void system1_state::init_wbml()
void system1_state::init_tokisens()
{
// HACK otherwise player dies in attract mode and game gives a continue screen, probably the other Z80 timing kludges aren't quite accurate (or the encrypted CPU differs)
// could also be different screen refresh, or even just exactly when the first interrupt occurs
m_maincpu->set_clock_scale(1.07f);
init_wbml();
}

View File

@ -145,6 +145,8 @@ private:
u8 m_nob_mcu_status = 0;
int m_nobb_inport23_step = 0;
u8 m_m1_num = 0;
// video handlers
void common_videomode_w(u8 data);
void videomode_w(u8 data);