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 // 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]); 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 // 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); 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 // 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]; u32 pc = m_pc.w.l + m_mmu_base[m_pc.b.h >> 2];
m_pc.w.l++;
// no refresh // no refresh
return m_opcodes.read_byte(pc); return m_opcodes.read_byte(pc);
} }
@ -239,21 +238,8 @@ u8 kc82_device::rop()
// arg - read 8-bit argument // 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]; u32 pc = m_pc.w.l + m_mmu_base[m_pc.b.h >> 2];
m_pc.w.l++;
return m_args.read_byte(pc); 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; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// z80_device overrides // z80_device overrides
virtual u8 rm(u16 addr) override; virtual u8 data_read(u16 addr) override;
virtual void wm(u16 addr, u8 value) override; virtual void data_write(u16 addr, u8 value) override;
virtual u8 rop() override; virtual u8 opcode_read() override;
virtual u8 arg() override; virtual u8 arg_read() override;
virtual u16 arg16() override;
// MMU access // MMU access
u8 mmu_r(offs_t offset); 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_RSTB,
NSC800_RSTC, NSC800_RSTC,
Z80_INPUT_LINE_WAIT, 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 Z80_INPUT_LINE_BUSRQ
}; };
@ -30,10 +30,11 @@ enum
class z80_device : public cpu_device, public z80_daisy_chain_interface class z80_device : public cpu_device, public z80_daisy_chain_interface
{ {
public: 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 z80_set_m1_cycles(u8 m1_cycles) { m_m1_cycles = m1_cycles; }
void set_mtm_cycles(uint8_t mtm_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_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_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)...); } 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(); } auto halt_cb() { return m_halt_cb.bind(); }
protected: 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 // device-level overrides
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
void init_op_steps();
// device_execute_interface overrides // device_execute_interface overrides
virtual uint32_t execute_min_cycles() const noexcept override { return 2; } virtual bool cpu_is_interruptible() const override { return true; }
virtual uint32_t execute_max_cycles() const noexcept override { return 16; } virtual u32 execute_min_cycles() const noexcept override { return 2; }
virtual uint32_t execute_input_lines() const noexcept override { return 4; } virtual u32 execute_max_cycles() const noexcept override { return 16; }
virtual uint32_t execute_default_irq_vector(int inputnum) const noexcept override { return 0xff; } 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 bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; }
virtual void execute_run() override; virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override; virtual void execute_set_input(int inputnum, int state) override;
@ -70,175 +145,112 @@ protected:
// device_disasm_interface overrides // device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
#undef PROTOTYPES void execute_cycles(u8 icount);
#define PROTOTYPES(prefix) \ void halt();
void prefix##_00(); void prefix##_01(); void prefix##_02(); void prefix##_03(); \ void leave_halt();
void prefix##_04(); void prefix##_05(); void prefix##_06(); void prefix##_07(); \
void prefix##_08(); void prefix##_09(); void prefix##_0a(); void prefix##_0b(); \ virtual u8 data_read(u16 addr);
void prefix##_0c(); void prefix##_0d(); void prefix##_0e(); void prefix##_0f(); \ virtual void data_write(u16 addr, u8 value);
void prefix##_10(); void prefix##_11(); void prefix##_12(); void prefix##_13(); \ virtual u8 opcode_read();
void prefix##_14(); void prefix##_15(); void prefix##_16(); void prefix##_17(); \ virtual u8 arg_read();
void prefix##_18(); void prefix##_19(); void prefix##_1a(); void prefix##_1b(); \
void prefix##_1c(); void prefix##_1d(); void prefix##_1e(); void prefix##_1f(); \ /* deprecated */ void rm16(u16 addr, PAIR &r);
void prefix##_20(); void prefix##_21(); void prefix##_22(); void prefix##_23(); \ /* deprecated */ void wm16_sp(PAIR &r);
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 illegal_1(); void illegal_1();
void illegal_2(); 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) ops_type eax();
PROTOTYPES(cb) ops_type eay();
PROTOTYPES(dd) ops_type push();
PROTOTYPES(ed) ops_type pop();
PROTOTYPES(fd) ops_type jp();
PROTOTYPES(xycb) ops_type jp_cond();
ops_type jr();
void halt(); ops_type jr_cond(u8 opcode);
void leave_halt(); ops_type call();
uint8_t in(uint16_t port); ops_type call_cond(u8 opcode);
void out(uint16_t port, uint8_t value); ops_type ret_cond(u8 opcode);
virtual uint8_t rm(uint16_t addr); ops_type retn();
uint8_t rm_reg(uint16_t addr); ops_type reti();
void rm16(uint16_t addr, PAIR &r); ops_type ld_r_a();
virtual void wm(uint16_t addr, uint8_t value); ops_type ld_a_r();
void wm16(uint16_t addr, PAIR &r); ops_type ld_i_a();
void wm16_sp(PAIR &r); ops_type ld_a_i();
virtual uint8_t rop(); ops_type rst(u16 addr);
virtual uint8_t arg(); void inc(u8 &r);
virtual uint16_t arg16(); void dec(u8 &r);
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);
void rlca(); void rlca();
void rrca(); void rrca();
void rla(); void rla();
void rra(); void rra();
void rrd(); ops_type rrd();
void rld(); ops_type rld();
void add_a(uint8_t value); void add_a(u8 value);
void adc_a(uint8_t value); void adc_a(u8 value);
void sub(uint8_t value); void sub(u8 value);
void sbc_a(uint8_t value); void sbc_a(u8 value);
void neg(); void neg();
void daa(); void daa();
void and_a(uint8_t value); void and_a(u8 value);
void or_a(uint8_t value); void or_a(u8 value);
void xor_a(uint8_t value); void xor_a(u8 value);
void cp(uint8_t value); void cp(u8 value);
void ex_af();
void ex_de_hl();
void exx(); void exx();
void ex_sp(PAIR &r); ops_type ex_sp();
void add16(PAIR &dr, PAIR &sr); ops_type add16();
void adc_hl(PAIR &r); ops_type adc_hl();
void sbc_hl(PAIR &r); ops_type sbc_hl();
uint8_t rlc(uint8_t value); u8 rlc(u8 value);
uint8_t rrc(uint8_t value); u8 rrc(u8 value);
uint8_t rl(uint8_t value); u8 rl(u8 value);
uint8_t rr(uint8_t value); u8 rr(u8 value);
uint8_t sla(uint8_t value); u8 sla(u8 value);
uint8_t sra(uint8_t value); u8 sra(u8 value);
uint8_t sll(uint8_t value); u8 sll(u8 value);
uint8_t srl(uint8_t value); u8 srl(u8 value);
void bit(int bit, uint8_t value); void bit(int bit, u8 value);
void bit_hl(int bit, uint8_t value); void bit_hl(int bit, u8 value);
void bit_xy(int bit, uint8_t value); void bit_xy(int bit, u8 value);
uint8_t res(int bit, uint8_t value); u8 res(int bit, u8 value);
uint8_t set(int bit, uint8_t value); u8 set(int bit, u8 value);
void ldi(); ops_type ldi();
void cpi(); ops_type cpi();
void ini(); ops_type ini();
void outi(); ops_type outi();
void ldd(); ops_type ldd();
void cpd(); ops_type cpd();
void ind(); ops_type ind();
void outd(); ops_type outd();
void ldir(); ops_type ldir();
void cpir(); ops_type cpir();
void inir(); ops_type inir();
void otir(); ops_type otir();
void lddr(); ops_type lddr();
void cpdr(); ops_type cpdr();
void indr(); ops_type indr();
void otdr(); ops_type otdr();
void ei(); void ei();
void set_f(u8 f);
void block_io_interrupted_flags();
ops_type next_op();
virtual void check_interrupts(); virtual void check_interrupts();
void take_interrupt(); void take_interrupt();
void take_nmi(); void take_nmi();
void nomreq_ir(s8 cycles); ops_type nomreq_ir(s8 cycles);
void nomreq_addr(u16 addr, s8 cycles); ops_type nomreq_addr(s8 cycles);
// address spaces // address spaces
const address_space_config m_program_config; const address_space_config m_program_config;
@ -268,32 +280,38 @@ protected:
PAIR m_bc2; PAIR m_bc2;
PAIR m_de2; PAIR m_de2;
PAIR m_hl2; PAIR m_hl2;
uint8_t m_r; u8 m_qtemp;
uint8_t m_r2; u8 m_q;
uint8_t m_iff1; u8 m_r;
uint8_t m_iff2; u8 m_r2;
uint8_t m_halt; u8 m_iff1;
uint8_t m_im; u8 m_iff2;
uint8_t m_i; u8 m_halt;
uint8_t m_nmi_state; /* nmi line state */ u8 m_im;
uint8_t m_nmi_pending; /* nmi pending */ u8 m_i;
uint8_t m_irq_state; /* irq line state */ 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_wait_state; // wait line state
int m_busrq_state; // bus request line state int m_busrq_state; // bus request line state
uint8_t m_after_ei; /* are we in the EI shadow? */ u8 m_after_ei; // are we in the EI shadow?
uint8_t m_after_ldair; /* same, but for LD A,I or LD A,R */ u8 m_after_ldair; // same, but for LD A,I or LD A,R
uint32_t m_ea; u32 m_ea;
u8 m_cycle;
op_prefix m_prefix;
u8 m_opcode;
int m_icount; int m_icount;
int m_icount_executing; PAIR16 m_m_shared_addr;
uint8_t m_rtemp; PAIR16 m_m_shared_data;
const uint8_t * m_cc_op; PAIR16 m_m_shared_data2;
const uint8_t * m_cc_cb; u8 m_rtemp;
const uint8_t * m_cc_ed;
const uint8_t * m_cc_xy; ops_type m_op_steps[6][0x100];
const uint8_t * m_cc_xycb;
const uint8_t * m_cc_ex; u8 m_m1_cycles = 4;
uint8_t m_mtm_cycles; u8 m_memrq_cycles = 3;
u8 m_iorq_cycles = 4;
}; };
DECLARE_DEVICE_TYPE(Z80, z80_device) DECLARE_DEVICE_TYPE(Z80, z80_device)
@ -301,7 +319,7 @@ DECLARE_DEVICE_TYPE(Z80, z80_device)
class nsc800_device : public z80_device class nsc800_device : public z80_device
{ {
public: 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: protected:
// device-level overrides // device-level overrides
@ -309,12 +327,12 @@ protected:
virtual void device_reset() override; virtual void device_reset() override;
// device_execute_interface overrides // 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 execute_set_input(int inputnum, int state) override;
virtual void check_interrupts() override; virtual void check_interrupts() override;
void take_interrupt_nsc800(); 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) DECLARE_DEVICE_TYPE(NSC800, nsc800_device)

View File

@ -93,10 +93,10 @@ Some bugs left :
#include "amstrad.h" #include "amstrad.h"
/* Components */ /* Components */
#include "machine/i8255.h" /* for 8255 ppi */ #include "machine/i8255.h" /* for 8255 ppi */
#include "cpu/z80/z80.h" /* for cycle tables */ #include "cpu/z80/z80.h" /* for cycle tables */
#include "video/mc6845.h" /* CRTC */ #include "video/mc6845.h" /* CRTC */
#include "machine/upd765.h" /* for floppy disc controller */ #include "machine/upd765.h" /* for floppy disc controller */
#include "sound/ay8910.h" #include "sound/ay8910.h"
#include "machine/mc146818.h" /* Aleste RTC */ #include "machine/mc146818.h" /* Aleste RTC */
#include "bus/centronics/ctronics.h" #include "bus/centronics/ctronics.h"
@ -121,19 +121,11 @@ Some bugs left :
#define SYSTEM_GX4000 2 #define SYSTEM_GX4000 2
/* Memory is banked in 16k blocks. However, the multiface /* Memory is banked in 16k blocks. However, the multiface pages the memory in 8k blocks!
pages the memory in 8k blocks! The ROM can The ROM can be paged into bank 0 and bank 3. */
be paged into bank 0 and bank 3. */
void amstrad_state::amstrad_mem(address_map &map) void amstrad_state::amstrad_mem(address_map &map)
{ {
map(0x00000, 0x01fff).bankr("bank1").bankw("bank9"); map(0x0000, 0xffff).rw(FUNC(amstrad_state::amstrad_cpc_mem_r), FUNC(amstrad_state::amstrad_cpc_mem_w));
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");
} }
/* I've handled the I/O ports in this way, because the ports /* 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 ) static INPUT_PORTS_START( amstrad_keyboard )
PORT_START("kbrow.0") 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(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(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(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(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(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)) 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_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_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(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(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)) 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_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_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(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(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_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") 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 */ /* cpc6128.rom contains OS in first 16k, BASIC in second 16k */
/* cpcados.rom contains Amstrad DOS */ /* cpcados.rom contains Amstrad DOS */
/* I am loading the roms outside of the Z80 memory area, because they /* I am loading the roms outside of the Z80 memory area, because they are banked. */
are banked. */
ROM_START( cpc6128 ) ROM_START( cpc6128 )
/* this defines the total memory size - 64k ram, 16k OS, 16k BASIC, 16k DOS */ /* this defines the total memory size - 64k ram, 16k OS, 16k BASIC, 16k DOS */
ROM_REGION(0x020000, "maincpu", 0) ROM_REGION(0x020000, "maincpu", 0)
@ -1212,7 +1203,7 @@ ROM_END
ROM_START( cpc6128f ) 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) ROM_REGION(0x020000, "maincpu", 0)
/* load the os to offset 0x01000 from memory base */ /* load the os to offset 0x01000 from memory base */
@ -1222,7 +1213,7 @@ ROM_END
ROM_START( cpc6128s ) 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) ROM_REGION(0x020000, "maincpu", 0)
/* load the os to offset 0x01000 from memory base */ /* load the os to offset 0x01000 from memory base */
@ -1231,7 +1222,7 @@ ROM_START( cpc6128s )
ROM_END ROM_END
ROM_START( cpc6128sp ) 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) ROM_REGION(0x020000, "maincpu", 0)
/* load the os to offset 0x01000 from memory base */ /* 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 */ /* 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( 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, 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, 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, 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, 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( 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, 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 ) 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 ) 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( 1989, kccomp, cpc464, 0, kccomp, kccomp, amstrad_state, empty_init, u8"VEB Mikroelektronik \"Wilhelm Pieck\" Mühlhausen",
COMP( 1993, al520ex, cpc464, 0, aleste, aleste, amstrad_state, empty_init, "Patisonic", "Aleste 520EX", MACHINE_IMPERFECT_SOUND ) "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); void aleste_msx_mapper(offs_t offset, uint8_t data);
uint8_t amstrad_cpc_io_r(offs_t offset); uint8_t amstrad_cpc_io_r(offs_t offset);
void amstrad_cpc_io_w(offs_t offset, uint8_t data); 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(); uint8_t amstrad_psg_porta_read();
void amstrad_plus_seqcheck(int data); void amstrad_plus_seqcheck(int data);
DECLARE_MACHINE_START(amstrad); DECLARE_MACHINE_START(amstrad);
@ -266,7 +268,7 @@ private:
required_memory_region m_region_maincpu; required_memory_region m_region_maincpu;
optional_memory_region m_region_user1; 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<11> m_io_kbrow;
optional_ioport_array<4> m_io_analog; optional_ioport_array<4> m_io_analog;
optional_ioport_array<3> m_io_mouse; 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. 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 :*/ The following tables show the possible ram configurations :*/
static const int RamConfigurations[8 * 4] = static const int RamConfigurations[8 * 4] =
{ {
0, 1, 2, 3, /* config 0 */ 0, 1, 2, 3, /* config 0 */
0, 1, 2, 7, /* config 1 */ 0, 1, 2, 7, /* config 1 */
4, 5, 6, 7, /* config 2 */ 4, 5, 6, 7, /* config 2 */
0, 3, 2, 7, /* config 3 */ 0, 3, 2, 7, /* config 3 */
0, 4, 2, 3, /* config 4 */ 0, 4, 2, 3, /* config 4 */
0, 5, 2, 3, /* config 5 */ 0, 5, 2, 3, /* config 5 */
0, 6, 2, 3, /* config 6 */ 0, 6, 2, 3, /* config 6 */
0, 7, 2, 3 /* config 7 */ 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, 0x07F, 0x000), /*13*/
rgb_t(0x000, 0x0BA, 0x000), /*19*/ rgb_t(0x000, 0x0BA, 0x000), /*19*/
rgb_t(0x000, 0x0F5, 0x000), /*25*/ rgb_t(0x000, 0x0F5, 0x000), /*25*/
rgb_t(0x000, 0x009, 0x000), /*1*/ rgb_t(0x000, 0x009, 0x000), /* 1*/
rgb_t(0x000, 0x044, 0x000), /*7*/ rgb_t(0x000, 0x044, 0x000), /* 7*/
rgb_t(0x000, 0x062, 0x000), /*10*/ rgb_t(0x000, 0x062, 0x000), /*10*/
rgb_t(0x000, 0x09C, 0x000), /*16*/ 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, 0x0F5, 0x000), /*25*/
rgb_t(0x000, 0x0EB, 0x000), /*24*/ rgb_t(0x000, 0x0EB, 0x000), /*24*/
rgb_t(0x000, 0x0FF, 0x000), /*26*/ rgb_t(0x000, 0x0FF, 0x000), /*26*/
rgb_t(0x000, 0x03A, 0x000), /*6*/ rgb_t(0x000, 0x03A, 0x000), /* 6*/
rgb_t(0x000, 0x04E, 0x000), /*8*/ rgb_t(0x000, 0x04E, 0x000), /* 8*/
rgb_t(0x000, 0x093, 0x000), /*15*/ rgb_t(0x000, 0x093, 0x000), /*15*/
rgb_t(0x000, 0x0A6, 0x000), /*17*/ 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, 0x0BA, 0x000), /*19*/
rgb_t(0x000, 0x0B0, 0x000), /*18*/ rgb_t(0x000, 0x0B0, 0x000), /*18*/
rgb_t(0x000, 0x0C4, 0x000), /*20*/ rgb_t(0x000, 0x0C4, 0x000), /*20*/
rgb_t(0x000, 0x000, 0x000), /*0*/ rgb_t(0x000, 0x000, 0x000), /* 0*/
rgb_t(0x000, 0x013, 0x000), /*2*/ rgb_t(0x000, 0x013, 0x000), /* 2*/
rgb_t(0x000, 0x058, 0x000), /*9*/ rgb_t(0x000, 0x058, 0x000), /* 9*/
rgb_t(0x000, 0x06B, 0x000), /*11*/ 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, 0x0D7, 0x000), /*22*/
rgb_t(0x000, 0x0CD, 0x000), /*21*/ rgb_t(0x000, 0x0CD, 0x000), /*21*/
rgb_t(0x000, 0x0E1, 0x000), /*23*/ rgb_t(0x000, 0x0E1, 0x000), /*23*/
rgb_t(0x000, 0x01D, 0x000), /*3*/ rgb_t(0x000, 0x01D, 0x000), /* 3*/
rgb_t(0x000, 0x031, 0x000), /*5*/ rgb_t(0x000, 0x031, 0x000), /* 5*/
rgb_t(0x000, 0x075, 0x000), /*12*/ rgb_t(0x000, 0x075, 0x000), /*12*/
rgb_t(0x000, 0x089, 0x000) /*14*/ 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 */ /* load CPCEMU style snapshots */
void amstrad_state::amstrad_handle_snapshot(unsigned char *pSnapshot) 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++; \ #define NEXT_ROM_SLOT m_rom_count++; \
if(slot3 && m_rom_count == 3) m_rom_count++; \ if(slot3 && m_rom_count == 3) m_rom_count++; \
if(slot7 && m_rom_count == 7) 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 m_maincpu->set_input_line_vector(0, 0xff); // Z80
else else
m_maincpu->set_input_line_vector(0, 0x00); // Z80 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) TIMER_CALLBACK_MEMBER(amstrad_state::cb_set_resolution)

View File

@ -314,108 +314,10 @@ void msx_state::machine_start()
m_port_c_old = 0xff; 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() void msx_state::driver_start()
{ {
m_maincpu->set_input_line_vector(0, 0xff); // Z80 m_maincpu->set_input_line_vector(0, 0xff); // Z80
m_maincpu->z80_set_m1_cycles(5);
m_maincpu->z80_set_cycle_tables(cc_op, cc_cb, cc_ed, cc_xy, nullptr, cc_ex);
save_item(NAME(m_psg_b)); save_item(NAME(m_psg_b));
save_item(NAME(m_kanji_latch)); 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 other two sets, either. flickys1 allows for DEMO SOUND which none of the others sets
seem to have access to. 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" #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() void system1_state::machine_start()
{ {
const u32 numbanks = (m_maincpu_region->bytes() - 0x10000) / 0x4000; const u32 numbanks = (m_maincpu_region->bytes() - 0x10000) / 0x4000;
@ -468,13 +347,12 @@ void system1_state::machine_start()
m_bank1d->set_entry(0); 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_mute_xor = 0x00;
m_dakkochn_mux_data = 0x00; m_dakkochn_mux_data = 0x00;
m_m1_num = 0;
save_item(NAME(m_dakkochn_mux_data)); save_item(NAME(m_dakkochn_mux_data));
save_item(NAME(m_m1_num));
save_item(NAME(m_videomode_prev)); save_item(NAME(m_videomode_prev));
save_item(NAME(m_mcu_control)); save_item(NAME(m_mcu_control));
save_item(NAME(m_nob_maincpu_latch)); save_item(NAME(m_nob_maincpu_latch));
@ -2276,10 +2154,18 @@ GFXDECODE_END
void system1_state::sys1ppi(machine_config &config) void system1_state::sys1ppi(machine_config &config)
{ {
/* basic machine hardware */ /* 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_PROGRAM, &system1_state::system1_map);
m_maincpu->set_addrmap(AS_IO, &system1_state::system1_ppi_io_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)); 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); Z80(config, m_soundcpu, SOUND_CLOCK/2);
m_soundcpu->set_addrmap(AS_PROGRAM, &system1_state::sound_map); m_soundcpu->set_addrmap(AS_PROGRAM, &system1_state::sound_map);
@ -5610,9 +5496,6 @@ void system1_state::init_wbml()
void system1_state::init_tokisens() 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(); init_wbml();
} }

View File

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