m6805: misc changes

* Turn a lot of macros into inline methods so they can be scoped down
* Correct affected flags in comments on opcode handlers (actual code was correct)
* Remove unnecessary flag calculation tables
* Add a table with CMOS instruction timings
This commit is contained in:
Vas Crabb 2017-01-21 22:17:18 +11:00
parent f2a9a936a2
commit 05b0a89007
6 changed files with 567 additions and 635 deletions

File diff suppressed because it is too large Load Diff

View File

@ -40,8 +40,6 @@
#include <algorithm>
#define IRQ_LEVEL_DETECT 0
#define OP(name) (&m6805_base_device::name)
#define OP_T(name) (&m6805_base_device::name<true>)
#define OP_F(name) (&m6805_base_device::name<false>)
@ -51,7 +49,7 @@
#define OP_IX(name) (&m6805_base_device::name<addr_mode::IX>)
#define OP_IX1(name) (&m6805_base_device::name<addr_mode::IX1>)
#define OP_IX2(name) (&m6805_base_device::name<addr_mode::IX2>)
const m6805_base_device::op_handler_func m6805_base_device::m_ophndlr[256] =
const m6805_base_device::op_handler_func m6805_base_device::m_hmos_ops[256] =
{
/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
/* 0 */ OP(brset<0>),OP(brclr<0>),OP(brset<1>),OP(brclr<1>),OP(brset<2>),OP(brclr<2>),OP(brset<3>),OP(brclr<3>),
@ -88,50 +86,8 @@ const m6805_base_device::op_handler_func m6805_base_device::m_ophndlr[256] =
OP_IX(eora), OP_IX(adca), OP_IX(ora), OP_IX(adda), OP_IX(jmp), OP_IX(jsr), OP_IX(ldx), OP_IX(stx)
};
const uint8_t m6805_base_device::m_flags8i[256] = /* increment */
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/*0*/ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*1*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*2*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*3*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*4*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*5*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*6*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*7*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*8*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*9*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*A*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*B*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*C*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*D*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*E*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*F*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
};
const uint8_t m6805_base_device::m_flags8d[256] = /* decrement */
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/*0*/ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*1*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*2*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*3*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*4*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*5*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*6*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*7*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*8*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*9*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*A*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*B*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*C*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*D*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*E*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
/*F*/ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
};
/* what they say it is ... */
const uint8_t m6805_base_device::m_cycles1[] =
const uint8_t m6805_base_device::m_hmos_cycles[] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
@ -152,48 +108,31 @@ const uint8_t m6805_base_device::m_cycles1[] =
/*F*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5
};
void m6805_base_device::rd_s_handler_b(uint8_t *b)
const uint8_t m6805_base_device::m_cmos_cycles[] =
{
SP_INC;
*b = RM( S );
}
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/*0*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
/*1*/ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
/*2*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/*3*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5,
/*4*/ 3, 0,11, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3,
/*5*/ 3, 0, 0, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3,
/*6*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 5, 0, 6,
/*7*/ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 4, 0, 5,
/*8*/ 9, 6, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
/*9*/ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2,
/*A*/ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 6, 2, 0,
/*B*/ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 5, 3, 4,
/*C*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 6, 4, 5,
/*D*/ 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 7, 5, 6,
/*E*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 6, 4, 5,
/*F*/ 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 2, 5, 3, 4
};
void m6805_base_device::rd_s_handler_w(PAIR *p)
{
CLEAR_PAIR(p);
SP_INC;
p->b.h = RM( S );
SP_INC;
p->b.l = RM( S );
}
void m6805_base_device::wr_s_handler_b(uint8_t *b)
{
WM( S, *b );
SP_DEC;
}
void m6805_base_device::wr_s_handler_w(PAIR *p)
{
WM( S, p->b.l );
SP_DEC;
WM( S, p->b.h );
SP_DEC;
}
void m6805_base_device::RM16(uint32_t addr, PAIR *p)
{
CLEAR_PAIR(p);
p->b.h = RM(addr);
++addr;
// if( ++addr > AMASK ) addr = 0;
p->b.l = RM(addr);
}
void m6805_base_device::interrupt_vector()
{
RM16(0xffff - 5, &m_pc);
rm16(0xfffa, m_pc);
}
void m68hc05eg_device::interrupt_vector()
@ -201,17 +140,17 @@ void m68hc05eg_device::interrupt_vector()
if ((m_pending_interrupts & (1 << M68HC05EG_INT_IRQ)) != 0)
{
m_pending_interrupts &= ~(1 << M68HC05EG_INT_IRQ);
RM16(0x1ffa, &m_pc);
rm16(0x1ffa, m_pc);
}
else if((m_pending_interrupts & (1 << M68HC05EG_INT_TIMER)) != 0)
{
m_pending_interrupts &= ~(1 << M68HC05EG_INT_TIMER);
RM16(0x1ff8, &m_pc);
rm16(0x1ff8, m_pc);
}
else if((m_pending_interrupts & (1 << M68HC05EG_INT_CPI)) != 0)
{
m_pending_interrupts &= ~(1 << M68HC05EG_INT_CPI);
RM16(0x1ff6, &m_pc);
rm16(0x1ff6, m_pc);
}
}
@ -223,42 +162,42 @@ void hd63705_device::interrupt_vector()
if ((m_pending_interrupts & (1 << HD63705_INT_IRQ1)) != 0)
{
m_pending_interrupts &= ~(1 << HD63705_INT_IRQ1);
RM16(0x1ff8, &m_pc);
rm16(0x1ff8, m_pc);
}
else if ((m_pending_interrupts & (1 << HD63705_INT_IRQ2)) != 0)
{
m_pending_interrupts &= ~(1 << HD63705_INT_IRQ2);
RM16(0x1fec, &m_pc);
rm16(0x1fec, m_pc);
}
else if ((m_pending_interrupts & (1 << HD63705_INT_ADCONV)) != 0)
{
m_pending_interrupts &= ~(1 << HD63705_INT_ADCONV);
RM16(0x1fea, &m_pc);
rm16(0x1fea, m_pc);
}
else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER1)) != 0)
{
m_pending_interrupts &= ~(1 << HD63705_INT_TIMER1);
RM16(0x1ff6, &m_pc);
rm16(0x1ff6, m_pc);
}
else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER2)) != 0)
{
m_pending_interrupts &= ~(1 << HD63705_INT_TIMER2);
RM16(0x1ff4, &m_pc);
rm16(0x1ff4, m_pc);
}
else if ((m_pending_interrupts & (1 << HD63705_INT_TIMER3)) != 0)
{
m_pending_interrupts &= ~(1<<HD63705_INT_TIMER3);
RM16(0x1ff2, &m_pc);
rm16(0x1ff2, m_pc);
}
else if ((m_pending_interrupts & (1 << HD63705_INT_PCI)) != 0)
{
m_pending_interrupts &= ~(1 << HD63705_INT_PCI);
RM16(0x1ff0, &m_pc);
rm16(0x1ff0, m_pc);
}
else if ((m_pending_interrupts & (1 << HD63705_INT_SCI)) != 0)
{
m_pending_interrupts &= ~(1 << HD63705_INT_SCI);
RM16(0x1fee, &m_pc);
rm16(0x1fee, m_pc);
}
}
@ -271,15 +210,15 @@ void m6805_base_device::interrupt()
if ((m_pending_interrupts & (1 << HD63705_INT_NMI)) != 0)
{
PUSHWORD(m_pc);
PUSHBYTE(m_x);
PUSHBYTE(m_a);
PUSHBYTE(m_cc);
pushword(m_pc);
pushbyte(m_x);
pushbyte(m_a);
pushbyte(m_cc);
SEI;
/* no vectors supported, just do the callback to clear irq_state if needed */
standard_irq_callback(0);
RM16(0x1ffc, &m_pc);
rm16(0x1ffc, m_pc);
m_pending_interrupts &= ~(1 << HD63705_INT_NMI);
m_icount -= 11;
@ -290,10 +229,10 @@ void m6805_base_device::interrupt()
if ((CC & IFLAG) == 0)
{
/* standard IRQ */
PUSHWORD(m_pc);
PUSHBYTE(m_x);
PUSHBYTE(m_a);
PUSHBYTE(m_cc);
pushword(m_pc);
pushbyte(m_x);
pushbyte(m_a);
pushbyte(m_cc);
SEI;
/* no vectors supported, just do the callback to clear irq_state if needed */
standard_irq_callback(0);
@ -382,7 +321,7 @@ void m6805_base_device::device_reset()
/* IRQ disabled */
SEI;
RM16(0xfffe, &m_pc);
rm16(0xfffe, m_pc);
}
@ -546,11 +485,11 @@ void m6805_base_device::execute_run()
debugger_instruction_hook(this, PC);
u8 const ireg = M_RDOP(PC++);
u8 const ireg = rdop(PC++);
(this->*m_ophndlr[ireg])();
m_icount -= m_cycles1[ireg];
burn_cycles(m_cycles1[ireg]);
(this->*m_hmos_ops[ireg])();
m_icount -= m_hmos_cycles[ireg];
burn_cycles(m_hmos_cycles[ireg]);
}
while (m_icount > 0);
}
@ -565,7 +504,7 @@ void m68hc05eg_device::device_reset()
m_sp_mask = 0xff;
m_sp_low = 0xc0;
RM16(0x1ffe, &m_pc);
rm16(0x1ffe, m_pc);
}
void m68hc05eg_device::execute_set_input(int inputnum, int state)
@ -593,7 +532,7 @@ void hd63705_device::device_reset()
m_sp_low = 0x100;
m_s.w.l = SP_MASK;
RM16(0x1ffe, &m_pc);
rm16(0x1ffe, m_pc);
}
void hd63705_device::execute_set_input(int inputnum, int state)

View File

@ -26,8 +26,10 @@ public:
m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, const char *shortname, const char *source);
protected:
// addressing mode selector for opcode handler templates
enum class addr_mode { IM, DI, EX, IX, IX1, IX2 };
// state index constants
enum
{
M6805_PC = 1,
@ -38,6 +40,24 @@ protected:
M6805_IRQ_STATE
};
// CC masks H INZC
// 7654 3210
enum
{
CFLAG = 0x01,
ZFLAG = 0x02,
NFLAG = 0x04,
IFLAG = 0x08,
HFLAG = 0x10
};
typedef void (m6805_base_device::*op_handler_func)();
// opcode tables
static op_handler_func const m_hmos_ops[256];
static u8 const m_hmos_cycles[256];
static u8 const m_cmos_cycles[256];
m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source);
// device-level overrides
@ -67,11 +87,38 @@ protected:
// for devices with timing-sensitive peripherals
virtual void burn_cycles(unsigned count) { }
void rd_s_handler_b(uint8_t *b);
void rd_s_handler_w(PAIR *p);
void wr_s_handler_b(uint8_t *b);
void wr_s_handler_w(PAIR *p);
void RM16(uint32_t addr, PAIR *p);
void clr_nz() { m_cc &= ~(NFLAG | ZFLAG); }
void clr_nzc() { m_cc &= ~(NFLAG | ZFLAG | CFLAG); }
void clr_hnzc() { m_cc &= ~(HFLAG | NFLAG | ZFLAG | CFLAG); }
// macros for CC -- CC bits affected should be reset before calling
void set_z8(u8 a) { if (!a) m_cc |= ZFLAG; }
void set_n8(u8 a) { m_cc |= (a & 0x80) >> 5; }
void set_h(u8 a, u8 b, u8 r) { m_cc |= (a ^ b ^ r) & 0x10; }
void set_c8(u16 a) { m_cc |= BIT(a, 8); }
// combos
void set_nz8(u8 a) { set_n8(a); set_z8(a); }
void set_nzc8(u16 a) { set_nz8(a); set_c8(a); }
void set_hnzc8(u8 a, u8 b, u16 r) { set_h(a, b, r); set_nzc8(r); }
unsigned rdmem(u32 addr) { return unsigned(m_program->read_byte(addr)); }
void wrmem(u32 addr, u8 value) { m_program->write_byte(addr, value); }
unsigned rdop(u32 addr) { return unsigned(m_direct->read_byte(addr)); }
unsigned rdop_arg(u32 addr) { return unsigned(m_direct->read_byte(addr)); }
unsigned rm(u32 addr) { return rdmem(addr); }
void rm16(u32 addr, PAIR &p);
void wm(u32 addr, u8 value) { wrmem(addr, value); }
void pushbyte(u8 b);
void pushword(PAIR const &p);
void pullbyte(u8 &b);
void pullword(PAIR &p);
template <typename T> void immbyte(T &b);
void immword(PAIR &w);
void skipbyte();
template <unsigned B> void brset();
template <unsigned B> void brclr();
@ -168,15 +215,15 @@ protected:
const address_space_config m_program_config;
// CPU registers
PAIR m_ea; /* effective address */
PAIR m_ea; // effective address (should really be a temporary in opcode handlers)
uint32_t m_sp_mask; /* Stack pointer address mask */
uint32_t m_sp_low; /* Stack pointer low water mark (or floor) */
PAIR m_pc; /* Program counter */
PAIR m_s; /* Stack pointer */
uint8_t m_a; /* Accumulator */
uint8_t m_x; /* Index register */
uint8_t m_cc; /* Condition codes */
u32 m_sp_mask; // Stack pointer address mask
u32 m_sp_low; // Stack pointer low water mark (or floor)
PAIR m_pc; // Program counter
PAIR m_s; // Stack pointer
u8 m_a; // Accumulator
u8 m_x; // Index register
u8 m_cc; // Condition codes
uint16_t m_pending_interrupts; /* MB */
@ -189,15 +236,6 @@ protected:
// address spaces
address_space *m_program;
direct_read_data *m_direct;
private:
typedef void (m6805_base_device::*op_handler_func)();
// opcode/condition tables
static const op_handler_func m_ophndlr[256];
static const uint8_t m_flags8i[256];
static const uint8_t m_flags8d[256];
static const uint8_t m_cycles1[256];
};

View File

@ -5,101 +5,72 @@
#pragma once
/****************************************************************************/
/* Read a byte from given memory location */
/****************************************************************************/
#define M6805_RDMEM(addr) ((unsigned)m_program->read_byte(addr))
#define SP_MASK m_sp_mask // stack pointer mask
#define SP_LOW m_sp_low // stack pointer low water mark
#define PC m_pc.w.l // program counter lower word
#define S m_s.w.l // stack pointer lower word
#define A m_a // accumulator
#define X m_x // index register
#define CC m_cc // condition codes
/****************************************************************************/
/* Write a byte to given memory location */
/****************************************************************************/
#define M6805_WRMEM(addr, value) (m_program->write_byte(addr, value))
#define EAD m_ea.d
#define EA m_ea.w.l
/****************************************************************************/
/* M6805_RDOP() is identical to M6805_RDMEM() except it is used for reading */
/* opcodes. In case of system with memory mapped I/O, this function can be */
/* used to greatly speed up emulation */
/****************************************************************************/
#define M6805_RDOP(addr) ((unsigned)m_direct->read_byte(addr))
/****************************************************************************/
/* M6805_RDOP_ARG() is identical to M6805_RDOP() but it's used for reading */
/* opcode arguments. This difference can be used to support systems that */
/* use different encoding mechanisms for opcodes and opcode arguments */
/****************************************************************************/
#define M6805_RDOP_ARG(addr) ((unsigned)m_direct->read_byte(addr))
#define SP_MASK m_sp_mask /* stack pointer mask */
#define SP_LOW m_sp_low /* stack pointer low water mark */
#define PC m_pc.w.l /* program counter lower word */
#define S m_s.w.l /* stack pointer lower word */
#define A m_a /* accumulator */
#define X m_x /* index register */
#define CC m_cc /* condition codes */
#define EAD m_ea.d
#define EA m_ea.w.l
/* DS -- THESE ARE RE-DEFINED IN m6805.h TO RAM, ROM or FUNCTIONS IN cpuintrf.c */
#define RM(addr) M6805_RDMEM(addr)
#define WM(addr, value) M6805_WRMEM(addr, value)
#define M_RDOP(addr) M6805_RDOP(addr)
#define M_RDOP_ARG(addr) M6805_RDOP_ARG(addr)
// pre-clear a PAIR union; clearing h2 and h3 only might be faster?
inline void clear_pair(PAIR &p) { p.d = 0; }
/* macros to tweak the PC and SP */
#define SP_INC if( ++S > SP_MASK) S = SP_LOW
#define SP_DEC if( --S < SP_LOW) S = SP_MASK
#define SP_ADJUST(s) ( ( (s) & SP_MASK ) | SP_LOW )
#define SP_INC if (++S > SP_MASK) S = SP_LOW
#define SP_DEC if (--S < SP_LOW) S = SP_MASK
#define SP_ADJUST(s) (((s) & SP_MASK) | SP_LOW)
inline void m6805_base_device::rm16(u32 addr, PAIR &p)
{
clear_pair(p);
p.b.h = rm(addr);
p.b.l = rm(addr + 1);
}
inline void m6805_base_device::pushbyte(u8 b)
{
wm(S, b);
SP_DEC;
}
inline void m6805_base_device::pushword(PAIR const &p)
{
pushbyte(p.b.l);
pushbyte(p.b.h);
}
inline void m6805_base_device::pullbyte(u8 &b)
{
SP_INC;
b = rm(S);
}
inline void m6805_base_device::pullword(PAIR &p)
{
clear_pair(p);
pullbyte(p.b.h);
pullbyte(p.b.l);
}
/* macros to access memory */
#define IMMBYTE(b) do { b = M_RDOP_ARG(PC++); } while (false)
#define IMMWORD(w) do { w.d = 0; w.b.h = M_RDOP_ARG(PC); w.b.l = M_RDOP_ARG(PC+1); PC+=2; } while (false)
#define SKIPBYTE() do { M_RDOP_ARG(PC++); } while (false)
#define PUSHBYTE(b) wr_s_handler_b(&b)
#define PUSHWORD(w) wr_s_handler_w(&w)
#define PULLBYTE(b) rd_s_handler_b(&b)
#define PULLWORD(w) rd_s_handler_w(&w)
/* CC masks H INZC
7654 3210 */
#define CFLAG 0x01
#define ZFLAG 0x02
#define NFLAG 0x04
#define IFLAG 0x08
#define HFLAG 0x10
#define CLR_NZ CC&=~(NFLAG|ZFLAG)
#define CLR_HNZC CC&=~(HFLAG|NFLAG|ZFLAG|CFLAG)
#define CLR_Z CC&=~(ZFLAG)
#define CLR_NZC CC&=~(NFLAG|ZFLAG|CFLAG)
#define CLR_ZC CC&=~(ZFLAG|CFLAG)
/* macros for CC -- CC bits affected should be reset before calling */
#define SET_Z(a) if(!a)SEZ
#define SET_Z8(a) SET_Z((uint8_t)a)
#define SET_N8(a) CC|=((a&0x80)>>5)
#define SET_H(a,b,r) CC|=((a^b^r)&0x10)
#define SET_C8(a) CC|=((a&0x100)>>8)
#define SET_FLAGS8I(a) {CC |= m_flags8i[(a) & 0xff];}
#define SET_FLAGS8D(a) {CC |= m_flags8d[(a) & 0xff];}
/* combos */
#define SET_NZ8(a) {SET_N8(a); SET_Z(a);}
#define SET_FLAGS8(a,b,r) {SET_N8(r); SET_Z8(r); SET_C8(r);}
template <typename T> inline void m6805_base_device::immbyte(T &b) { b = rdop_arg(PC++); }
inline void m6805_base_device::immword(PAIR &w) { w.d = 0; immbyte(w.b.h); immbyte(w.b.l); }
inline void m6805_base_device::skipbyte() { rdop_arg(PC++); }
/* for treating an unsigned uint8_t as a signed int16_t */
#define SIGNED(b) (int16_t(b & 0x80 ? b | 0xff00 : b))
/* Macros for addressing modes */
#define DIRECT do { EAD=0; IMMBYTE(m_ea.b.l); } while (false)
#define DIRECT do { EAD=0; immbyte(m_ea.b.l); } while (false)
#define IMM8 do { EA = PC++; } while (false)
#define EXTENDED IMMWORD(m_ea)
#define EXTENDED immword(m_ea)
#define INDEXED do { EA = X; } while (false)
#define INDEXED1 do { EAD = 0; IMMBYTE(m_ea.b.l); EA += X; } while (false)
#define INDEXED2 do { IMMWORD(m_ea); EA += X;} while (false)
#define INDEXED1 do { EAD = 0; immbyte(m_ea.b.l); EA += X; } while (false)
#define INDEXED2 do { immword(m_ea); EA += X;} while (false)
/* macros to set status flags */
#if defined(SEC)
@ -126,14 +97,14 @@
case addr_mode::IX1: INDEXED1; break; \
case addr_mode::IX2: INDEXED2; break; \
} } while (false)
#define DIRBYTE(b) do { DIRECT; b = RM(EAD); } while (false)
#define EXTBYTE(b) do { EXTENDED; b = RM(EAD); } while (false)
#define IDXBYTE(b) do { INDEXED; b = RM(EAD); } while (false)
#define IDX1BYTE(b) do { INDEXED1; b = RM(EAD); } while (false)
#define IDX2BYTE(b) do { INDEXED2; b = RM(EAD); } while (false)
#define DIRBYTE(b) do { DIRECT; b = rm(EAD); } while (false)
#define EXTBYTE(b) do { EXTENDED; b = rm(EAD); } while (false)
#define IDXBYTE(b) do { INDEXED; b = rm(EAD); } while (false)
#define IDX1BYTE(b) do { INDEXED1; b = rm(EAD); } while (false)
#define IDX2BYTE(b) do { INDEXED2; b = rm(EAD); } while (false)
#define ARGBYTE(b) \
do { switch (M) { \
case addr_mode::IM: IMMBYTE(b); break; \
case addr_mode::IM: immbyte(b); break; \
case addr_mode::DI: DIRBYTE(b); break; \
case addr_mode::EX: EXTBYTE(b); break; \
case addr_mode::IX: IDXBYTE(b); break; \
@ -143,10 +114,7 @@
} } while (false)
/* Macros for branch instructions */
#define BRANCH(f) do { uint8_t t; IMMBYTE(t); if (bool(f) == bool(C)) PC += SIGNED(t); } while (false)
/* pre-clear a PAIR union; clearing h2 and h3 only might be faster? */
#define CLEAR_PAIR(p) p->d = 0
#define BRANCH(f) do { u8 t; immbyte(t); if (bool(f) == bool(C)) PC += SIGNED(t); } while (false)
offs_t CPU_DISASSEMBLE_NAME(m6805)(
cpu_device *device,

View File

@ -69,6 +69,13 @@ ROM_START( m68705u3 )
ROM_LOAD("bootstrap.bin", 0x0000, 0x0078, CRC(5946479b) SHA1(834ea00aef5de12dbcd6421a6e21d5ea96cfbf37))
ROM_END
constexpr u16 M68705_VECTOR_BOOTSTRAP = 0xfff6;
constexpr u16 M68705_VECTOR_TIMER = 0xfff8;
//constexpr u16 M68705_VECTOR_INT2 = 0xfff8;
constexpr u16 M68705_VECTOR_INT = 0xfffa;
//constexpr u16 M68705_VECTOR_SWI = 0xfffc;
constexpr u16 M68705_VECTOR_RESET = 0xfffe;
} // anonymous namespace
@ -500,7 +507,12 @@ void m68705_device::device_reset()
if (CLEAR_LINE != m_vihtp)
{
LOG("loading bootstrap vector\n");
RM16(0xfff6, &m_pc);
rm16(M68705_VECTOR_BOOTSTRAP, m_pc);
}
else
{
LOG("loading reset vector\n");
rm16(M68705_VECTOR_RESET, m_pc);
}
}
@ -548,10 +560,10 @@ void m68705_device::interrupt()
{
if ((CC & IFLAG) == 0)
{
PUSHWORD(m_pc);
PUSHBYTE(m_x);
PUSHBYTE(m_a);
PUSHBYTE(m_cc);
pushword(m_pc);
pushbyte(m_x);
pushbyte(m_a);
pushbyte(m_cc);
SEI;
standard_irq_callback(0);
@ -559,12 +571,12 @@ void m68705_device::interrupt()
{
LOGINT("servicing /INT interrupt\n");
m_pending_interrupts &= ~(1 << M68705_IRQ_LINE);
RM16(0xfffa, &m_pc);
rm16(M68705_VECTOR_INT, m_pc);
}
else if (BIT(m_pending_interrupts, M68705_INT_TIMER))
{
LOGINT("servicing timer/counter interrupt\n");
RM16(0xfff8, &m_pc);
rm16(M68705_VECTOR_TIMER, m_pc);
}
else
{

View File

@ -56,6 +56,7 @@ public:
{ return downcast<m68705_device &>(device).m_port_cb_w[N].set_callback(std::forward<Object>(obj)); }
protected:
// state index constants
enum
{
M68705_A = M6805_A,