mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
m6805: refactoring and improvements
* Moved 68705 devices into their own file. * Made P3, P5 and U3 variants and made them load bootstrap ROMs. * Implemented EPROM control (write is stubbed out with a logerror). * Implemented differences for open drain I/O ports. (nw) Base device with peripherals should really derive from the 6805 device directly, not the 68705 devices, as I/O ports are present on mask devices (e.g. 6805P2). All drivers and devices that were using M68705_NEW have been changed to M68705P5 - someone who knows the drivers better should fix them up.
This commit is contained in:
parent
9d6025015e
commit
02d69ca65a
@ -1335,7 +1335,10 @@ if (CPUS["M6805"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/m6805/m6805.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m6805/m6805.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6805/6805defs.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6805/6805ops.hxx",
|
||||
MAME_DIR .. "src/devices/cpu/m6805/m68705.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m6805/m68705.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "emu.h"
|
||||
#include "a2bus.h"
|
||||
#include "machine/6821pia.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
|
@ -33,89 +33,13 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "debugger.h"
|
||||
#include "m6805.h"
|
||||
#include "m6805defs.h"
|
||||
|
||||
#include "debugger.h"
|
||||
|
||||
#define IRQ_LEVEL_DETECT 0
|
||||
|
||||
/****************************************************************************/
|
||||
/* Read a byte from given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDMEM(addr) ((unsigned)m_program->read_byte(addr))
|
||||
|
||||
/****************************************************************************/
|
||||
/* Write a byte to given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_WRMEM(addr, value) (m_program->write_byte(addr, value))
|
||||
|
||||
/****************************************************************************/
|
||||
/* 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)
|
||||
|
||||
/* 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 )
|
||||
|
||||
/* macros to access memory */
|
||||
#define IMMBYTE(b) {b = M_RDOP_ARG(PC++);}
|
||||
#define IMMWORD(w) {w.d = 0; w.b.h = M_RDOP_ARG(PC); w.b.l = M_RDOP_ARG(PC+1); PC+=2;}
|
||||
#define SKIPBYTE() {M_RDOP_ARG(PC++);}
|
||||
|
||||
#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)
|
||||
|
||||
const uint8_t m6805_base_device::m_flags8i[256]= /* increment */
|
||||
{
|
||||
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
@ -155,47 +79,6 @@ const uint8_t m6805_base_device::m_flags8d[256]= /* decrement */
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
|
||||
};
|
||||
#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);}
|
||||
|
||||
/* 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 EAD=0; IMMBYTE(m_ea.b.l)
|
||||
#define IMM8 EA = PC++
|
||||
#define EXTENDED IMMWORD(m_ea)
|
||||
#define INDEXED EA = X
|
||||
#define INDEXED1 {EAD = 0; IMMBYTE(m_ea.b.l); EA += X;}
|
||||
#define INDEXED2 {IMMWORD(m_ea); EA += X;}
|
||||
|
||||
/* macros to set status flags */
|
||||
#if defined(SEC)
|
||||
#undef SEC
|
||||
#endif
|
||||
#define SEC CC |= CFLAG
|
||||
#define CLC CC &=~ CFLAG
|
||||
#define SEZ CC |= ZFLAG
|
||||
#define CLZ CC &=~ ZFLAG
|
||||
#define SEN CC |= NFLAG
|
||||
#define CLN CC &=~ NFLAG
|
||||
#define SEH CC |= HFLAG
|
||||
#define CLH CC &=~ HFLAG
|
||||
#define SEI CC |= IFLAG
|
||||
#define CLI CC &=~ IFLAG
|
||||
|
||||
/* macros for convenience */
|
||||
#define DIRBYTE(b) {DIRECT; b = RM(EAD);}
|
||||
#define EXTBYTE(b) {EXTENDED; b = RM(EAD);}
|
||||
#define IDXBYTE(b) {INDEXED; b = RM(EAD);}
|
||||
#define IDX1BYTE(b) {INDEXED1; b = RM(EAD);}
|
||||
#define IDX2BYTE(b) {INDEXED2; b = RM(EAD);}
|
||||
/* Macros for branch instructions */
|
||||
#define BRANCH(f) { uint8_t t; IMMBYTE(t); if(f) { PC += SIGNED(t); } }
|
||||
|
||||
/* what they say it is ... */
|
||||
const uint8_t m6805_base_device::m_cycles1[] =
|
||||
@ -220,9 +103,6 @@ const uint8_t m6805_base_device::m_cycles1[] =
|
||||
};
|
||||
|
||||
|
||||
/* pre-clear a PAIR union; clearing h2 and h3 only might be faster? */
|
||||
#define CLEAR_PAIR(p) p->d = 0
|
||||
|
||||
void m6805_base_device::rd_s_handler_b(uint8_t *b)
|
||||
{
|
||||
SP_INC;
|
||||
@ -261,35 +141,6 @@ void m6805_base_device::RM16(uint32_t addr, PAIR *p)
|
||||
p->b.l = RM(addr);
|
||||
}
|
||||
|
||||
/* Generate interrupt - m68705 version */
|
||||
void m68705_device::interrupt()
|
||||
{
|
||||
if ((m_pending_interrupts & ((1 << M6805_IRQ_LINE) | M68705_INT_MASK)) != 0 )
|
||||
{
|
||||
if ((CC & IFLAG) == 0)
|
||||
{
|
||||
PUSHWORD(m_pc);
|
||||
PUSHBYTE(m_x);
|
||||
PUSHBYTE(m_a);
|
||||
PUSHBYTE(m_cc);
|
||||
SEI;
|
||||
standard_irq_callback(0);
|
||||
|
||||
if ((m_pending_interrupts & (1 << M68705_IRQ_LINE)) != 0 )
|
||||
{
|
||||
m_pending_interrupts &= ~(1 << M68705_IRQ_LINE);
|
||||
RM16(0xfffa, &m_pc);
|
||||
}
|
||||
else if ((m_pending_interrupts & (1 << M68705_INT_TIMER)) != 0)
|
||||
{
|
||||
m_pending_interrupts &= ~(1 << M68705_INT_TIMER);
|
||||
RM16(0xfff8, &m_pc);
|
||||
}
|
||||
}
|
||||
m_icount -= 11;
|
||||
}
|
||||
}
|
||||
|
||||
void m6805_base_device::interrupt_vector()
|
||||
{
|
||||
RM16(0xffff - 5, &m_pc);
|
||||
@ -410,14 +261,14 @@ void m6805_base_device::interrupt()
|
||||
//-------------------------------------------------
|
||||
|
||||
m6805_base_device::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)
|
||||
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
m_program_config("program", ENDIANNESS_BIG, 8, addr_width)
|
||||
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
, m_program_config("program", ENDIANNESS_BIG, 8, addr_width)
|
||||
{
|
||||
}
|
||||
|
||||
m6805_base_device::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)
|
||||
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
m_program_config("program", ENDIANNESS_BIG, 8, addr_width, 0, internal_map)
|
||||
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
, m_program_config("program", ENDIANNESS_BIG, 8, addr_width, 0, internal_map)
|
||||
{
|
||||
}
|
||||
|
||||
@ -940,377 +791,6 @@ void m68hc05eg_device::execute_set_input(int inputnum, int state)
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* M68705 section
|
||||
****************************************************************************/
|
||||
void m68705_device::device_reset()
|
||||
{
|
||||
m6805_base_device::device_reset();
|
||||
|
||||
RM16(0xfffe, &m_pc);
|
||||
}
|
||||
|
||||
void m68705_device::execute_set_input(int inputnum, int state)
|
||||
{
|
||||
if (m_irq_state[inputnum] != state)
|
||||
{
|
||||
m_irq_state[inputnum] = state;
|
||||
|
||||
if (state != CLEAR_LINE)
|
||||
{
|
||||
m_pending_interrupts |= 1 << inputnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ddr - direction registers */
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_ddrA_w)
|
||||
{
|
||||
const u8 ddr_old = m_ddrA;
|
||||
m_ddrA = data;
|
||||
|
||||
// update outputs if lines switched to output
|
||||
if ((m_ddrA & ~ddr_old) != 0)
|
||||
update_portA_state();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_ddrB_w)
|
||||
{
|
||||
const u8 ddr_old = m_ddrB;
|
||||
m_ddrB = data;
|
||||
|
||||
// update outputs if lines switched to output
|
||||
if ((m_ddrB & ~ddr_old) != 0)
|
||||
update_portB_state();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_ddrC_w)
|
||||
{
|
||||
const u8 ddr_old = m_ddrC;
|
||||
m_ddrC = data;
|
||||
|
||||
// update outputs if lines switched to output
|
||||
if ((m_ddrC & ~ddr_old) != 0)
|
||||
update_portC_state();
|
||||
}
|
||||
|
||||
/* read ports */
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_portA_r)
|
||||
{
|
||||
if (!m_portA_cb_r.isnull())
|
||||
m_portA_in = m_portA_cb_r(space, 0, ~m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pulled
|
||||
u8 res = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
|
||||
return res;
|
||||
}
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_portB_r)
|
||||
{
|
||||
if (!m_portB_cb_r.isnull())
|
||||
m_portB_in = m_portB_cb_r(space, 0, ~m_ddrB);
|
||||
u8 res = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
|
||||
return res;
|
||||
}
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_portC_r)
|
||||
{
|
||||
if (!m_portC_cb_r.isnull())
|
||||
m_portC_in = m_portC_cb_r(space, 0, ~m_ddrC);
|
||||
u8 res = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* write ports */
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_portA_w)
|
||||
{
|
||||
// load the output latch
|
||||
m_portA_out = data;
|
||||
|
||||
// update the output lines
|
||||
update_portA_state();
|
||||
}
|
||||
|
||||
void m68705_new_device::update_portA_state()
|
||||
{
|
||||
// pass bits through DDR output mask
|
||||
m_portA_in = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
|
||||
|
||||
// pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed
|
||||
m_portA_cb_w(space(AS_PROGRAM), 0, m_portA_in, m_ddrA);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_portB_w)
|
||||
{
|
||||
// load the output latch
|
||||
m_portB_out = data;
|
||||
|
||||
// update the output lines
|
||||
update_portB_state();
|
||||
}
|
||||
|
||||
void m68705_new_device::update_portB_state()
|
||||
{
|
||||
// pass bits through DDR output mask
|
||||
m_portB_in = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
|
||||
|
||||
// pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed
|
||||
m_portB_cb_w(space(AS_PROGRAM), 0, m_portB_in, m_ddrB);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_portC_w)
|
||||
{
|
||||
// load the output latch
|
||||
m_portC_out = data;
|
||||
|
||||
// update the output lines
|
||||
update_portC_state();
|
||||
}
|
||||
|
||||
void m68705_new_device::update_portC_state()
|
||||
{
|
||||
// pass bits through DDR output mask
|
||||
m_portC_in = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
|
||||
|
||||
// pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed
|
||||
m_portC_cb_w(space(AS_PROGRAM), 0, m_portC_in, m_ddrC);
|
||||
}
|
||||
|
||||
READ8_MEMBER(m68705_new_device::pa_r)
|
||||
{
|
||||
return m_portA_in;
|
||||
}
|
||||
|
||||
READ8_MEMBER(m68705_new_device::pb_r)
|
||||
{
|
||||
return m_portB_in;
|
||||
}
|
||||
|
||||
READ8_MEMBER(m68705_new_device::pc_r)
|
||||
{
|
||||
return m_portC_in;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::pa_w)
|
||||
{
|
||||
COMBINE_DATA(&m_portA_in);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::pb_w)
|
||||
{
|
||||
COMBINE_DATA(&m_portB_in);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::pc_w)
|
||||
{
|
||||
COMBINE_DATA(&m_portC_in);
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_68705_tdr_r)
|
||||
{
|
||||
//logerror("internal_68705 TDR read, returning %02X\n", m_tdr);
|
||||
return m_tdr;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_68705_tdr_w)
|
||||
{
|
||||
//logerror("internal_68705 TDR written with %02X, was %02X\n", data, m_tdr);
|
||||
m_tdr = data;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_68705_tcr_r)
|
||||
{
|
||||
//logerror("internal_68705 TCR read, returning %02X\n", (m_tcr&0xF7));
|
||||
return (m_tcr & 0xF7);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_68705_tcr_w)
|
||||
{
|
||||
/*
|
||||
logerror("internal_68705 TCR written with %02X\n", data);
|
||||
if (data&0x80) logerror(" TIR=1, Timer Interrupt state is set\n"); else logerror(" TIR=0; Timer Interrupt state is cleared\n");
|
||||
if (data&0x40) logerror(" TIM=1, Timer Interrupt is now masked\n"); else logerror(" TIM=0, Timer Interrupt is now unmasked\n");
|
||||
if (data&0x20) logerror(" TIN=1, Timer Clock source is set to external\n"); else logerror(" TIN=0, Timer Clock source is set to internal\n");
|
||||
if (data&0x10) logerror(" TIE=1, Timer External pin is enabled\n"); else logerror(" TIE=0, Timer External pin is disabled\n");
|
||||
if (data&0x08) logerror(" PSC=1, Prescaler counter cleared\n"); else logerror(" PSC=0, Prescaler counter left alone\n");
|
||||
logerror(" Prescaler: %d\n", (1<<(data&0x7)));
|
||||
*/
|
||||
// if timer was enabled but now isn't, shut it off.
|
||||
// below is a hack assuming the TIMER pin isn't going anywhere except tied to +5v, so basically TIN is acting as an active-low timer enable, and TIE is ignored even in the case where TIE=1, the timer will end up being 5v ANDED against the internal timer clock which == the internal timer clock.
|
||||
// Note this hack is incorrect; the timer pin actually does connect somewhere (vblank or maybe one of the V counter bits?), but the game never actually uses the timer pin in external clock mode, so the TIMER connection must be left over from development. We can apparently safely ignore it.
|
||||
if ((m_tcr^data)&0x20)// check if TIN state changed
|
||||
{
|
||||
/* logerror("timer enable state changed!\n"); */
|
||||
if (data&0x20) m_68705_timer->adjust(attotime::never, TIMER_68705_PRESCALER_EXPIRED);
|
||||
else m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
// prescaler check: if timer prescaler has changed, or the PSC bit is set, adjust the timer length for the prescaler expired timer, but only if the timer would be running
|
||||
if ( (((m_tcr&0x07)!=(data&0x07))||(data&0x08)) && ((data&0x20)==0) )
|
||||
{
|
||||
/* logerror("timer reset due to PSC or prescaler change!\n"); */
|
||||
m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
m_tcr = data;
|
||||
// if int state is set, and TIM is unmasked, assert an interrupt. otherwise clear it.
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
|
||||
}
|
||||
|
||||
void m68705_new_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_68705_PRESCALER_EXPIRED:
|
||||
timer_68705_increment(ptr, param);
|
||||
break;
|
||||
default:
|
||||
assert_always(false, "Unknown id in m68705_new_device::device_timer");
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(m68705_new_device::timer_68705_increment)
|
||||
{
|
||||
m_tdr++;
|
||||
if (m_tdr == 0x00) m_tcr |= 0x80; // if we overflowed, set the int bit
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(m_tcr&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
The 68(7)05 peripheral memory map:
|
||||
Common for Px, Rx, Ux parts:
|
||||
0x00: Port A data (RW)
|
||||
0x01: Port B data (RW)
|
||||
0x02: Port C data (RW) [top 4 bits do nothing (read as 1s) on Px parts, work as expected on Rx, Ux parts]
|
||||
0x03: [Port D data (RW), only on Rx, Ux parts]
|
||||
0x04: Port A DDR (Write only, reads as 0xFF)
|
||||
0x05: Port B DDR (Write only, reads as 0xFF)
|
||||
0x06: Port C DDR (Write only, reads as 0xFF) [top 4 bits do nothing on Px parts, work as expected on Rx, Ux parts]
|
||||
0x07: Unused (reads as 0xFF?)
|
||||
0x08: Timer Data Register (RW; acts as ram when timer isn't counting, otherwise decrements once per prescaler expiry)
|
||||
0x09: Timer Control Register (RW; on certain mask part and when MOR bit 6 is not set, all bits are RW except bit 3 which
|
||||
always reads as zero. when MOR bit 6 is set and on all mask parts except one listed in errata in the 6805 daatsheet,
|
||||
the top two bits are RW, bottom 6 always read as 1 and writes do nothing; on the errata chip, bit 3 is writable and
|
||||
clears the prescaler, reads as zero)
|
||||
0x0A: [Miscellaneous Register, only on Rx, Sx, Ux parts]
|
||||
0x0B: [Eprom parts: Programming Control Register (write only?, low 3 bits; reads as 0xFF?); Unused (reads as 0xFF?) on
|
||||
Mask parts]
|
||||
0x0C: Unused (reads as 0xFF?)
|
||||
0x0D: Unused (reads as 0xFF?)
|
||||
0x0E: [A/D control register, only on Rx, Ux, Sx parts]
|
||||
0x0F: [A/D result register, only on Rx, Ux, Sx parts]
|
||||
0x10-0x7f: internal ram; SP can only point to 0x60-0x7F. Rx parts have an unused hole from 0x10-0x3F (reads as 0xFF?)
|
||||
0x80-0xFF: Page 0 user rom
|
||||
The remainder of the memory map differs here between parts, see appropriate datasheet for each part.
|
||||
The four vectors are always stored in big endian form as the last 8 bytes of the address space.
|
||||
|
||||
Sx specific differences:
|
||||
0x02: Port C data (RW) [top 6 bits do nothing (read as 1s) on Sx parts]
|
||||
0x06: Port C DDR (Write only, reads as 0xFF) [top 6 bits do nothing on Sx parts]
|
||||
0x0B: Timer 2 Data Register MSB
|
||||
0x0C: Timer 2 Data Register LSB
|
||||
0x0D: Timer 2 Control Register
|
||||
0x10: SPI Data Register
|
||||
0x11: SPI Control Register
|
||||
0x12-0x3F: Unused (reads as 0xFF?)
|
||||
|
||||
MOR ADDRESS: Mask Option Register; does not exist on R2 and several other but not all mask parts, located at 0x784 on Px parts
|
||||
|
||||
Rx Parts: 40 pins; address space is 0x000-0xfff with an unused hole at 0x10-0x3f and and 0x100-0x7BF; has A/D converter, Ports A-D;
|
||||
eprom parts have MOR at 0xF38; mask parts have selftest rom at similar area; selftest roms differ between the U2 and U3 versions
|
||||
|
||||
Px Parts: 28 pins; address space is 0x000-0x7ff; eprom parts have MOR at 0x784 and bootstrap rom at 0x785-0x7f7; mask parts have a
|
||||
selftest rom at similar area; port c is just 4 bits.
|
||||
|
||||
Sx Parts: 40 pins; address space is 0x000-0xfff with an unused hole at 0x12-0x3f and and 0x100-0x9BF; has A/D converter; has SPI
|
||||
serial; port C is just two bits; has an extra 16-bit timer compared to Ux/Rx; selftest rom at 0xF00-0xFF7
|
||||
|
||||
Ux Parts: 40 pins; address space is 0x000-0xfff; has A/D converter, Ports A-D; eprom parts have MOR at 0xF38; mask parts have
|
||||
selftest rom at similar area; selftest roms differ between the U2 and U3 versions
|
||||
|
||||
*/
|
||||
|
||||
DEVICE_ADDRESS_MAP_START( internal_map, 8, m68705_new_device )
|
||||
AM_RANGE(0x000, 0x000) AM_READWRITE(internal_portA_r, internal_portA_w)
|
||||
AM_RANGE(0x001, 0x001) AM_READWRITE(internal_portB_r, internal_portB_w)
|
||||
AM_RANGE(0x002, 0x002) AM_READWRITE(internal_portC_r, internal_portC_w)
|
||||
AM_RANGE(0x004, 0x004) AM_WRITE(internal_ddrA_w)
|
||||
AM_RANGE(0x005, 0x005) AM_WRITE(internal_ddrB_w)
|
||||
AM_RANGE(0x006, 0x006) AM_WRITE(internal_ddrC_w)
|
||||
|
||||
AM_RANGE(0x008, 0x008) AM_READWRITE(internal_68705_tdr_r, internal_68705_tdr_w)
|
||||
AM_RANGE(0x009, 0x009) AM_READWRITE(internal_68705_tcr_r, internal_68705_tcr_w)
|
||||
|
||||
|
||||
AM_RANGE(0x010, 0x07f) AM_RAM
|
||||
AM_RANGE(0x080, 0x7ff) AM_ROM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
void m68705_new_device::device_start()
|
||||
{
|
||||
m68705_device::device_start();
|
||||
|
||||
save_item(NAME(m_portA_in));
|
||||
save_item(NAME(m_portB_in));
|
||||
save_item(NAME(m_portC_in));
|
||||
|
||||
save_item(NAME(m_portA_out));
|
||||
save_item(NAME(m_portB_out));
|
||||
save_item(NAME(m_portC_out));
|
||||
|
||||
save_item(NAME(m_ddrA));
|
||||
save_item(NAME(m_ddrB));
|
||||
save_item(NAME(m_ddrC));
|
||||
|
||||
m_portA_cb_w.resolve_safe();
|
||||
m_portB_cb_w.resolve_safe();
|
||||
m_portC_cb_w.resolve_safe();
|
||||
|
||||
m_portA_cb_r.resolve();
|
||||
m_portB_cb_r.resolve();
|
||||
m_portC_cb_r.resolve();
|
||||
|
||||
m_portA_in = 0xff;
|
||||
m_portB_in = 0xff;
|
||||
m_portC_in = 0xff;
|
||||
|
||||
// allocate the MCU timer, and set it to fire NEVER.
|
||||
m_68705_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m68705_new_device::timer_68705_increment),this));
|
||||
m_68705_timer->adjust(attotime::never);
|
||||
|
||||
save_item(NAME(m_tdr));
|
||||
save_item(NAME(m_tcr));
|
||||
|
||||
}
|
||||
|
||||
void m68705_new_device::device_reset()
|
||||
{
|
||||
m68705_device::device_reset();
|
||||
|
||||
// all bits of ports A, B and C revert to inputs on reset
|
||||
m_ddrA = 0;
|
||||
m_ddrB = 0;
|
||||
m_ddrC = 0;
|
||||
|
||||
m_tdr = 0xFF;
|
||||
m_tcr = 0x7F;
|
||||
|
||||
//set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<7)));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* HD63705 section
|
||||
****************************************************************************/
|
||||
@ -1355,6 +835,4 @@ void hd63705_device::execute_set_input(int inputnum, int state)
|
||||
|
||||
const device_type M6805 = &device_creator<m6805_device>;
|
||||
const device_type M68HC05EG = &device_creator<m68hc05eg_device>;
|
||||
const device_type M68705 = &device_creator<m68705_device>;
|
||||
const device_type M68705_NEW = &device_creator<m68705_new_device>;
|
||||
const device_type HD63705 = &device_creator<hd63705_device>;
|
||||
|
@ -1,23 +1,19 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
/*** m6805: Portable 6805 emulator ******************************************/
|
||||
#ifndef MAME_CPU_M6805_M6805_H
|
||||
#define MAME_CPU_M6805_M6805_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __M6805_H__
|
||||
#define __M6805_H__
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class m6805_device;
|
||||
|
||||
// device type definition
|
||||
extern const device_type M6805;
|
||||
extern const device_type M68HC05EG;
|
||||
extern const device_type M68705;
|
||||
extern const device_type M68705_NEW;
|
||||
extern const device_type HD63705;
|
||||
|
||||
// ======================> m6805_base_device
|
||||
@ -28,9 +24,10 @@ class m6805_base_device : public cpu_device
|
||||
public:
|
||||
// construction/destruction
|
||||
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);
|
||||
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);
|
||||
|
||||
protected:
|
||||
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
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
@ -62,6 +59,16 @@ private:
|
||||
static const uint8_t m_cycles1[256];
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
M6805_PC = 1,
|
||||
M6805_S,
|
||||
M6805_CC,
|
||||
M6805_A,
|
||||
M6805_X,
|
||||
M6805_IRQ_STATE
|
||||
};
|
||||
|
||||
void rd_s_handler_b(uint8_t *b);
|
||||
void rd_s_handler_w(PAIR *p);
|
||||
void wr_s_handler_b(uint8_t *b);
|
||||
@ -290,6 +297,7 @@ protected:
|
||||
direct_read_data *m_direct;
|
||||
};
|
||||
|
||||
|
||||
// ======================> m6805_device
|
||||
|
||||
class m6805_device : public m6805_base_device
|
||||
@ -303,6 +311,7 @@ protected:
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
};
|
||||
|
||||
|
||||
// ======================> m68hc05eg_device
|
||||
|
||||
class m68hc05eg_device : public m6805_base_device
|
||||
@ -321,159 +330,6 @@ protected:
|
||||
virtual void interrupt_vector() override;
|
||||
};
|
||||
|
||||
// ======================> m68705_device
|
||||
|
||||
class m68705_device : public m6805_base_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: m6805_base_device(mconfig, tag, owner, clock, M68705, "M68705", 12, "m68705", __FILE__) { }
|
||||
|
||||
m68705_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)
|
||||
: m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source) { }
|
||||
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
virtual void interrupt() override;
|
||||
};
|
||||
|
||||
// ======================> m68705_new_device
|
||||
|
||||
|
||||
#define MCFG_M68705_PORTA_W_CB(_devcb) \
|
||||
devcb = &m68705_new_device::set_portA_cb_w(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_M68705_PORTB_W_CB(_devcb) \
|
||||
devcb = &m68705_new_device::set_portB_cb_w(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_M68705_PORTC_W_CB(_devcb) \
|
||||
devcb = &m68705_new_device::set_portC_cb_w(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_M68705_PORTA_R_CB(_devcb) \
|
||||
devcb = &m68705_new_device::set_portA_cb_r(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_M68705_PORTB_R_CB(_devcb) \
|
||||
devcb = &m68705_new_device::set_portB_cb_r(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_M68705_PORTC_R_CB(_devcb) \
|
||||
devcb = &m68705_new_device::set_portC_cb_r(*device, DEVCB_##_devcb);
|
||||
|
||||
|
||||
class m68705_new_device : public m68705_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
m68705_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: m68705_device(mconfig, tag, owner, clock, M68705_NEW, "M68705 (NEW)", 11, address_map_delegate(FUNC(m68705_new_device::internal_map), this), "m68705_new", __FILE__),
|
||||
m_portA_in(0),
|
||||
m_portB_in(0),
|
||||
m_portC_in(0),
|
||||
m_portA_out(0),
|
||||
m_portB_out(0),
|
||||
m_portC_out(0),
|
||||
m_ddrA(0),
|
||||
m_ddrB(0),
|
||||
m_ddrC(0),
|
||||
m_portA_cb_w(*this),
|
||||
m_portB_cb_w(*this),
|
||||
m_portC_cb_w(*this),
|
||||
m_portA_cb_r(*this),
|
||||
m_portB_cb_r(*this),
|
||||
m_portC_cb_r(*this)
|
||||
{ }
|
||||
|
||||
// static configuration helpers
|
||||
template<class _Object> static devcb_base &set_portA_cb_w(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portA_cb_w.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_portB_cb_w(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portB_cb_w.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_portC_cb_w(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portC_cb_w.set_callback(object); }
|
||||
|
||||
template<class _Object> static devcb_base &set_portA_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portA_cb_r.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_portB_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portB_cb_r.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_portC_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portC_cb_r.set_callback(object); }
|
||||
|
||||
DECLARE_READ8_MEMBER(pa_r);
|
||||
DECLARE_READ8_MEMBER(pb_r);
|
||||
DECLARE_READ8_MEMBER(pc_r);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(pa_w);
|
||||
DECLARE_WRITE8_MEMBER(pb_w);
|
||||
DECLARE_WRITE8_MEMBER(pc_w);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
TIMER_68705_PRESCALER_EXPIRED,
|
||||
};
|
||||
|
||||
DECLARE_ADDRESS_MAP(internal_map, 8);
|
||||
|
||||
DECLARE_READ8_MEMBER(internal_portA_r);
|
||||
DECLARE_READ8_MEMBER(internal_portB_r);
|
||||
DECLARE_READ8_MEMBER(internal_portC_r);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(internal_portA_w);
|
||||
DECLARE_WRITE8_MEMBER(internal_portB_w);
|
||||
DECLARE_WRITE8_MEMBER(internal_portC_w);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(internal_ddrA_w);
|
||||
DECLARE_WRITE8_MEMBER(internal_ddrB_w);
|
||||
DECLARE_WRITE8_MEMBER(internal_ddrC_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(internal_68705_tdr_r);
|
||||
DECLARE_WRITE8_MEMBER(internal_68705_tdr_w);
|
||||
DECLARE_READ8_MEMBER(internal_68705_tcr_r);
|
||||
DECLARE_WRITE8_MEMBER(internal_68705_tcr_w);
|
||||
|
||||
void update_portA_state();
|
||||
void update_portB_state();
|
||||
void update_portC_state();
|
||||
|
||||
u8 m_portA_in;
|
||||
u8 m_portB_in;
|
||||
u8 m_portC_in;
|
||||
|
||||
u8 m_portA_out;
|
||||
u8 m_portB_out;
|
||||
u8 m_portC_out;
|
||||
|
||||
u8 m_ddrA;
|
||||
u8 m_ddrB;
|
||||
u8 m_ddrC;
|
||||
|
||||
u8 m_tdr;
|
||||
u8 m_tcr;
|
||||
|
||||
/* Callbacks */
|
||||
devcb_write8 m_portA_cb_w;
|
||||
devcb_write8 m_portB_cb_w;
|
||||
devcb_write8 m_portC_cb_w;
|
||||
|
||||
devcb_read8 m_portA_cb_r;
|
||||
devcb_read8 m_portB_cb_r;
|
||||
devcb_read8 m_portC_cb_r;
|
||||
|
||||
/* Timers */
|
||||
emu_timer *m_68705_timer;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(timer_68705_increment);
|
||||
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
// virtual void interrupt() override;
|
||||
};
|
||||
|
||||
// ======================> hd63705_device
|
||||
|
||||
class hd63705_device : public m6805_base_device
|
||||
@ -497,8 +353,6 @@ protected:
|
||||
virtual void swi() override;
|
||||
};
|
||||
|
||||
enum { M6805_PC=1, M6805_S, M6805_CC, M6805_A, M6805_X, M6805_IRQ_STATE };
|
||||
|
||||
#define M6805_IRQ_LINE 0
|
||||
|
||||
/****************************************************************************
|
||||
@ -509,21 +363,6 @@ enum { M6805_PC=1, M6805_S, M6805_CC, M6805_A, M6805_X, M6805_IRQ_STATE };
|
||||
#define M68HC05EG_INT_TIMER (M6805_IRQ_LINE+1)
|
||||
#define M68HC05EG_INT_CPI (M6805_IRQ_LINE+2)
|
||||
|
||||
/****************************************************************************
|
||||
* 68705 section
|
||||
****************************************************************************/
|
||||
|
||||
#define M68705_A M6805_A
|
||||
#define M68705_PC M6805_PC
|
||||
#define M68705_S M6805_S
|
||||
#define M68705_X M6805_X
|
||||
#define M68705_CC M6805_CC
|
||||
#define M68705_IRQ_STATE M6805_IRQ_STATE
|
||||
|
||||
#define M68705_INT_MASK 0x03
|
||||
#define M68705_IRQ_LINE M6805_IRQ_LINE
|
||||
#define M68705_INT_TIMER 0x01
|
||||
|
||||
/****************************************************************************
|
||||
* HD63705 section
|
||||
****************************************************************************/
|
||||
@ -552,4 +391,4 @@ enum { M6805_PC=1, M6805_S, M6805_CC, M6805_A, M6805_X, M6805_IRQ_STATE };
|
||||
|
||||
CPU_DISASSEMBLE( m6805 );
|
||||
|
||||
#endif /* __M6805_H__ */
|
||||
#endif // MAME_CPU_M6805_M6805_H
|
||||
|
131
src/devices/cpu/m6805/m6805defs.h
Normal file
131
src/devices/cpu/m6805/m6805defs.h
Normal file
@ -0,0 +1,131 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
#ifndef MAME_CPU_M6805_M6805DEFS_H
|
||||
#define MAME_CPU_M6805_M6805DEFS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
/****************************************************************************/
|
||||
/* Read a byte from given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDMEM(addr) ((unsigned)m_program->read_byte(addr))
|
||||
|
||||
/****************************************************************************/
|
||||
/* Write a byte to given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_WRMEM(addr, value) (m_program->write_byte(addr, value))
|
||||
|
||||
/****************************************************************************/
|
||||
/* 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)
|
||||
|
||||
/* 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 )
|
||||
|
||||
/* macros to access memory */
|
||||
#define IMMBYTE(b) {b = M_RDOP_ARG(PC++);}
|
||||
#define IMMWORD(w) {w.d = 0; w.b.h = M_RDOP_ARG(PC); w.b.l = M_RDOP_ARG(PC+1); PC+=2;}
|
||||
#define SKIPBYTE() {M_RDOP_ARG(PC++);}
|
||||
|
||||
#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);}
|
||||
|
||||
/* 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 EAD=0; IMMBYTE(m_ea.b.l)
|
||||
#define IMM8 EA = PC++
|
||||
#define EXTENDED IMMWORD(m_ea)
|
||||
#define INDEXED EA = X
|
||||
#define INDEXED1 {EAD = 0; IMMBYTE(m_ea.b.l); EA += X;}
|
||||
#define INDEXED2 {IMMWORD(m_ea); EA += X;}
|
||||
|
||||
/* macros to set status flags */
|
||||
#if defined(SEC)
|
||||
#undef SEC
|
||||
#endif
|
||||
#define SEC CC |= CFLAG
|
||||
#define CLC CC &=~ CFLAG
|
||||
#define SEZ CC |= ZFLAG
|
||||
#define CLZ CC &=~ ZFLAG
|
||||
#define SEN CC |= NFLAG
|
||||
#define CLN CC &=~ NFLAG
|
||||
#define SEH CC |= HFLAG
|
||||
#define CLH CC &=~ HFLAG
|
||||
#define SEI CC |= IFLAG
|
||||
#define CLI CC &=~ IFLAG
|
||||
|
||||
/* macros for convenience */
|
||||
#define DIRBYTE(b) {DIRECT; b = RM(EAD);}
|
||||
#define EXTBYTE(b) {EXTENDED; b = RM(EAD);}
|
||||
#define IDXBYTE(b) {INDEXED; b = RM(EAD);}
|
||||
#define IDX1BYTE(b) {INDEXED1; b = RM(EAD);}
|
||||
#define IDX2BYTE(b) {INDEXED2; b = RM(EAD);}
|
||||
/* Macros for branch instructions */
|
||||
#define BRANCH(f) { uint8_t t; IMMBYTE(t); if(f) { PC += SIGNED(t); } }
|
||||
|
||||
/* pre-clear a PAIR union; clearing h2 and h3 only might be faster? */
|
||||
#define CLEAR_PAIR(p) p->d = 0
|
||||
|
||||
#endif // MAME_CPU_M6805_M6805DEFS_H
|
555
src/devices/cpu/m6805/m68705.cpp
Normal file
555
src/devices/cpu/m6805/m68705.cpp
Normal file
@ -0,0 +1,555 @@
|
||||
#include "emu.h"
|
||||
#include "m68705.h"
|
||||
#include "m6805defs.h"
|
||||
|
||||
namespace {
|
||||
|
||||
ROM_START( m68705p3 )
|
||||
ROM_REGION(0x0073, "bootstrap", 0)
|
||||
ROM_LOAD("bootstrap.bin", 0x0000, 0x0073, CRC(696e1383) SHA1(45104fe1dbd683d251ed2b9411b1f4befbb5aff4))
|
||||
ROM_END
|
||||
|
||||
ROM_START( m68705p5 )
|
||||
ROM_REGION(0x0073, "bootstrap", 0)
|
||||
ROM_LOAD("bootstrap.bin", 0x0000, 0x0073, CRC(f70a8620) SHA1(c154f78c23f10bb903a531cb19e99121d5f7c19c))
|
||||
ROM_END
|
||||
|
||||
ROM_START( m68705u3 )
|
||||
ROM_REGION(0x0078, "bootstrap", 0)
|
||||
ROM_LOAD("bootstrap.bin", 0x0000, 0x0073, CRC(5946479b) SHA1(834ea00aef5de12dbcd6421a6e21d5ea96cfbf37))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
device_type const M68705 = &device_creator<m68705_device>;
|
||||
device_type const M68705P3 = &device_creator<m68705p3_device>;
|
||||
device_type const M68705P5 = &device_creator<m68705p5_device>;
|
||||
device_type const M68705U3 = &device_creator<m68705u3_device>;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* M68705 device (no peripherals)
|
||||
****************************************************************************/
|
||||
|
||||
m68705_device::m68705_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: m6805_base_device(mconfig, tag, owner, clock, M68705, "M68705", 12, "m68705", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
m68705_device::m68705_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock,
|
||||
device_type type,
|
||||
char const *name,
|
||||
u32 addr_width,
|
||||
address_map_delegate internal_map,
|
||||
char const *shortname,
|
||||
char const *source)
|
||||
: m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source)
|
||||
{
|
||||
}
|
||||
|
||||
/* Generate interrupt - m68705 version */
|
||||
void m68705_device::interrupt()
|
||||
{
|
||||
if ((m_pending_interrupts & ((1 << M6805_IRQ_LINE) | M68705_INT_MASK)) != 0 )
|
||||
{
|
||||
if ((CC & IFLAG) == 0)
|
||||
{
|
||||
PUSHWORD(m_pc);
|
||||
PUSHBYTE(m_x);
|
||||
PUSHBYTE(m_a);
|
||||
PUSHBYTE(m_cc);
|
||||
SEI;
|
||||
standard_irq_callback(0);
|
||||
|
||||
if ((m_pending_interrupts & (1 << M68705_IRQ_LINE)) != 0 )
|
||||
{
|
||||
m_pending_interrupts &= ~(1 << M68705_IRQ_LINE);
|
||||
RM16(0xfffa, &m_pc);
|
||||
}
|
||||
else if ((m_pending_interrupts & (1 << M68705_INT_TIMER)) != 0)
|
||||
{
|
||||
m_pending_interrupts &= ~(1 << M68705_INT_TIMER);
|
||||
RM16(0xfff8, &m_pc);
|
||||
}
|
||||
}
|
||||
m_icount -= 11;
|
||||
}
|
||||
}
|
||||
|
||||
void m68705_device::device_reset()
|
||||
{
|
||||
m6805_base_device::device_reset();
|
||||
|
||||
RM16(0xfffe, &m_pc);
|
||||
}
|
||||
|
||||
void m68705_device::execute_set_input(int inputnum, int state)
|
||||
{
|
||||
if (m_irq_state[inputnum] != state)
|
||||
{
|
||||
m_irq_state[inputnum] = state;
|
||||
|
||||
if (state != CLEAR_LINE)
|
||||
{
|
||||
m_pending_interrupts |= 1 << inputnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* M68705 "new" device
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
The 68(7)05 peripheral memory map:
|
||||
Common for Px, Rx, Ux parts:
|
||||
0x00: Port A data (RW)
|
||||
0x01: Port B data (RW)
|
||||
0x02: Port C data (RW) [top 4 bits do nothing (read as 1s) on Px parts, work as expected on Rx, Ux parts]
|
||||
0x03: [Port D data (Read only), only on Rx, Ux parts]
|
||||
0x04: Port A DDR (Write only, reads as 0xFF)
|
||||
0x05: Port B DDR (Write only, reads as 0xFF)
|
||||
0x06: Port C DDR (Write only, reads as 0xFF) [top 4 bits do nothing on Px parts, work as expected on Rx, Ux parts]
|
||||
0x07: Unused (reads as 0xFF?)
|
||||
0x08: Timer Data Register (RW; acts as ram when timer isn't counting, otherwise decrements once per prescaler expiry)
|
||||
0x09: Timer Control Register (RW; on certain mask part and when MOR bit 6 is not set, all bits are RW except bit 3 which
|
||||
always reads as zero. when MOR bit 6 is set and on all mask parts except one listed in errata in the 6805 daatsheet,
|
||||
the top two bits are RW, bottom 6 always read as 1 and writes do nothing; on the errata chip, bit 3 is writable and
|
||||
clears the prescaler, reads as zero)
|
||||
0x0A: [Miscellaneous Register, only on Rx, Sx, Ux parts]
|
||||
0x0B: [Eprom parts: Programming Control Register (write only?, low 3 bits; reads as 0xFF?); Unused (reads as 0xFF?) on
|
||||
Mask parts]
|
||||
0x0C: Unused (reads as 0xFF?)
|
||||
0x0D: Unused (reads as 0xFF?)
|
||||
0x0E: [A/D control register, only on Rx, Sx parts]
|
||||
0x0F: [A/D result register, only on Rx, Sx parts]
|
||||
0x10-0x7f: internal ram; SP can only point to 0x60-0x7F. U2/R2 parts have an unused hole from 0x10-0x3F (reads as 0xFF?)
|
||||
0x80-0xFF: Page 0 user rom
|
||||
The remainder of the memory map differs here between parts, see appropriate datasheet for each part.
|
||||
The four vectors are always stored in big endian form as the last 8 bytes of the address space.
|
||||
|
||||
Sx specific differences:
|
||||
0x02: Port C data (RW) [top 6 bits do nothing (read as 1s) on Sx parts]
|
||||
0x06: Port C DDR (Write only, reads as 0xFF) [top 6 bits do nothing on Sx parts]
|
||||
0x0B: Timer 2 Data Register MSB
|
||||
0x0C: Timer 2 Data Register LSB
|
||||
0x0D: Timer 2 Control Register
|
||||
0x10: SPI Data Register
|
||||
0x11: SPI Control Register
|
||||
0x12-0x3F: Unused (reads as 0xFF?)
|
||||
|
||||
Port A has internal pull-ups (about 10kΩ), and can sink 1.6mA at 0.4V
|
||||
making it capable of driving CMOS or one TTL load directly.
|
||||
|
||||
Port B has a true high-Z state (maximum 20µA for Px parts or 10µA for
|
||||
Rx/Ux parts), and can sink 10mA at 1V (LED drive) or 3.2mA at 0.4V (two
|
||||
TTL loads). It requires external pull-ups to drive CMOS.
|
||||
|
||||
Port C has a true high-Z state (maximum 20µA for Px parts or 10µA for
|
||||
Rx/Ux parts), and can sink 1.6mA at 0.4V (one TTL load). It requires
|
||||
external pull-ups to drive CMOS.
|
||||
|
||||
MOR ADDRESS: Mask Option Register; does not exist on R2 and several other but not all mask parts, located at 0x784 on Px parts
|
||||
|
||||
Px Parts:
|
||||
* 28 pins
|
||||
* address space is 0x000-0x7ff
|
||||
* has Ports A-C
|
||||
* port C is just 4 bits
|
||||
* EPROM parts have MOR at 0x784 and bootstrap ROM at 0x785-0x7f7
|
||||
* mask parts have a selftest rom at similar area
|
||||
|
||||
Rx Parts:
|
||||
* 40 pins
|
||||
* address space is 0x000-0xfff with an unused hole at 0xf39-0xf7f
|
||||
* R2 parts have an unused hole at 0x10-0x3f and at 0x100-0x7bF
|
||||
* has A/D converter, Ports A-D
|
||||
* mask parts lack programmable prescaler
|
||||
* EPROM parts have MOR at 0xf38 and bootstrap ROM at 0xf80-0xff7
|
||||
* mask parts have selftest ROM at 0xf38-0xff7
|
||||
* selftest ROMs differ between the U2 and U3 versions
|
||||
|
||||
Sx Parts:
|
||||
* 40 pins
|
||||
* address space is 0x000-0xfff with an unused hole at 0x12-0x3f and at 0x100-0x9BF
|
||||
* has A/D converter, SPI serial
|
||||
* port C is just two bits
|
||||
* has an extra 16-bit timer compared to Ux/Rx
|
||||
* selftest rom at 0xF00-0xFF7
|
||||
|
||||
Ux Parts:
|
||||
* 40 pins
|
||||
* address space is 0x000-0xfff with an unused hole at 0xf39-0xf7f
|
||||
* U2 parts have an unused hole at 0x10-0x3f and at 0x100-0x7bF
|
||||
* has Ports A-D
|
||||
* EPROM parts have MOR at 0xf38 and bootstrap ROM at 0xf80-0xff7
|
||||
* mask parts have selftest ROM at 0xf38-0xff7
|
||||
* selftest ROMs differ between the U2 and U3 versions
|
||||
|
||||
*/
|
||||
|
||||
m68705_new_device::m68705_new_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock,
|
||||
device_type type,
|
||||
char const *name,
|
||||
u32 addr_width,
|
||||
address_map_delegate internal_map,
|
||||
char const *shortname,
|
||||
char const *source)
|
||||
: m68705_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source)
|
||||
, m_user_rom(*this, DEVICE_SELF, u32(1) << addr_width)
|
||||
, m_port_open_drain{ false, false, false, false }
|
||||
, m_port_mask{ 0x00, 0x00, 0x00, 0x00 }
|
||||
, m_port_input{ 0xff, 0xff, 0xff, 0xff }
|
||||
, m_port_latch{ 0xff, 0xff, 0xff, 0xff }
|
||||
, m_port_ddr{ 0x00, 0x00, 0x00, 0x00 }
|
||||
, m_port_cb_r{ { *this }, { *this }, { *this }, { *this } }
|
||||
, m_port_cb_w{ { *this }, { *this }, { *this }, { *this } }
|
||||
, m_pcr(0xff)
|
||||
{
|
||||
}
|
||||
|
||||
template <offs_t B> READ8_MEMBER(m68705_new_device::eprom_r)
|
||||
{
|
||||
// read locked out when /VPON and /PLE are asserted
|
||||
return (BIT(m_pcr, 2) || BIT(m_pcr, 0)) ? m_user_rom[B + offset] : 0xff;
|
||||
}
|
||||
|
||||
template <offs_t B> WRITE8_MEMBER(m68705_new_device::eprom_w)
|
||||
{
|
||||
// programming latch enabled when /VPON and /PLE are asserted
|
||||
if (!BIT(m_pcr, 2) && !BIT(m_pcr, 0))
|
||||
{
|
||||
if (BIT(m_pcr, 1))
|
||||
{
|
||||
m_pl_data = data;
|
||||
m_pl_addr = B + offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this causes undefined behaviour, which is bad when EPROM programming is involved
|
||||
logerror("warning: write to EPROM when /PGE = 0 (%x = %x)\n", B + offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t N> void m68705_new_device::set_port_open_drain(bool value)
|
||||
{
|
||||
m_port_open_drain[N] = value;
|
||||
}
|
||||
|
||||
template <std::size_t N> void m68705_new_device::set_port_mask(u8 mask)
|
||||
{
|
||||
m_port_mask[N] = mask;
|
||||
}
|
||||
|
||||
template <std::size_t N> READ8_MEMBER(m68705_new_device::port_r)
|
||||
{
|
||||
if (!m_port_cb_r[N].isnull()) m_port_input[N] = m_port_cb_r[N](space, 0, ~m_port_ddr[N]);
|
||||
return m_port_mask[N] | (m_port_latch[N] & m_port_ddr[N]) | (m_port_input[N] & ~m_port_ddr[N]);
|
||||
}
|
||||
|
||||
template <std::size_t N> WRITE8_MEMBER(m68705_new_device::port_latch_w)
|
||||
{
|
||||
data &= ~m_port_mask[N];
|
||||
u8 const diff = m_port_latch[N] ^ data;
|
||||
m_port_latch[N] = data;
|
||||
if (diff & m_port_ddr[N])
|
||||
port_cb_w<N>();
|
||||
}
|
||||
|
||||
template <std::size_t N> WRITE8_MEMBER(m68705_new_device::port_ddr_w)
|
||||
{
|
||||
data &= ~m_port_mask[N];
|
||||
if (data != m_port_ddr[N])
|
||||
{
|
||||
m_port_ddr[N] = data;
|
||||
port_cb_w<N>();
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t N> void m68705_new_device::port_cb_w()
|
||||
{
|
||||
u8 const data(m_port_open_drain[N]
|
||||
? m_port_latch[N] | ~m_port_ddr[N]
|
||||
: (m_port_latch[N] & m_port_ddr[N]) | (m_port_input[N] & ~m_port_ddr[N]));
|
||||
u8 const mask(m_port_open_drain[N] ? (~m_port_latch[N] & m_port_ddr[N]) : m_port_ddr[N]);
|
||||
m_port_cb_w[N](space(AS_PROGRAM), 0, data, mask);
|
||||
}
|
||||
|
||||
READ8_MEMBER(m68705_new_device::pcr_r)
|
||||
{
|
||||
return m_pcr;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::pcr_w)
|
||||
{
|
||||
data |= ((data & 0x01) << 1); // lock out /PGE if /PLE is not asserted
|
||||
if (!BIT(m_pcr, 2) && (0x20 & ((m_pcr ^ data) & ~data)))
|
||||
{
|
||||
logerror("warning: unimplemented EPROM write %x |= %x\n", m_pl_addr, m_pl_data);
|
||||
popmessage("%s: EPROM write", tag());
|
||||
}
|
||||
m_pcr = (m_pcr & 0xfc) | (data & 0x03);
|
||||
}
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_68705_tdr_r)
|
||||
{
|
||||
//logerror("internal_68705 TDR read, returning %02X\n", m_tdr);
|
||||
return m_tdr;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_68705_tdr_w)
|
||||
{
|
||||
//logerror("internal_68705 TDR written with %02X, was %02X\n", data, m_tdr);
|
||||
m_tdr = data;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(m68705_new_device::internal_68705_tcr_r)
|
||||
{
|
||||
//logerror("internal_68705 TCR read, returning %02X\n", (m_tcr&0xF7));
|
||||
return (m_tcr & 0xF7);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(m68705_new_device::internal_68705_tcr_w)
|
||||
{
|
||||
/*
|
||||
logerror("internal_68705 TCR written with %02X\n", data);
|
||||
if (data&0x80) logerror(" TIR=1, Timer Interrupt state is set\n"); else logerror(" TIR=0; Timer Interrupt state is cleared\n");
|
||||
if (data&0x40) logerror(" TIM=1, Timer Interrupt is now masked\n"); else logerror(" TIM=0, Timer Interrupt is now unmasked\n");
|
||||
if (data&0x20) logerror(" TIN=1, Timer Clock source is set to external\n"); else logerror(" TIN=0, Timer Clock source is set to internal\n");
|
||||
if (data&0x10) logerror(" TIE=1, Timer External pin is enabled\n"); else logerror(" TIE=0, Timer External pin is disabled\n");
|
||||
if (data&0x08) logerror(" PSC=1, Prescaler counter cleared\n"); else logerror(" PSC=0, Prescaler counter left alone\n");
|
||||
logerror(" Prescaler: %d\n", (1<<(data&0x7)));
|
||||
*/
|
||||
// if timer was enabled but now isn't, shut it off.
|
||||
// below is a hack assuming the TIMER pin isn't going anywhere except tied to +5v, so basically TIN is acting as an active-low timer enable, and TIE is ignored even in the case where TIE=1, the timer will end up being 5v ANDED against the internal timer clock which == the internal timer clock.
|
||||
// Note this hack is incorrect; the timer pin actually does connect somewhere (vblank or maybe one of the V counter bits?), but the game never actually uses the timer pin in external clock mode, so the TIMER connection must be left over from development. We can apparently safely ignore it.
|
||||
if ((m_tcr^data)&0x20)// check if TIN state changed
|
||||
{
|
||||
/* logerror("timer enable state changed!\n"); */
|
||||
if (data&0x20) m_68705_timer->adjust(attotime::never, TIMER_68705_PRESCALER_EXPIRED);
|
||||
else m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
// prescaler check: if timer prescaler has changed, or the PSC bit is set, adjust the timer length for the prescaler expired timer, but only if the timer would be running
|
||||
if ( (((m_tcr&0x07)!=(data&0x07))||(data&0x08)) && ((data&0x20)==0) )
|
||||
{
|
||||
/* logerror("timer reset due to PSC or prescaler change!\n"); */
|
||||
m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
m_tcr = data;
|
||||
// if int state is set, and TIM is unmasked, assert an interrupt. otherwise clear it.
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(m68705_new_device::timer_68705_increment)
|
||||
{
|
||||
m_tdr++;
|
||||
if (m_tdr == 0x00) m_tcr |= 0x80; // if we overflowed, set the int bit
|
||||
if ((m_tcr&0xC0) == 0x80)
|
||||
set_input_line(M68705_INT_TIMER, ASSERT_LINE);
|
||||
else
|
||||
set_input_line(M68705_INT_TIMER, CLEAR_LINE);
|
||||
m_68705_timer->adjust(attotime::from_hz((clock() / 4) / (1 << (m_tcr & 0x07))), TIMER_68705_PRESCALER_EXPIRED);
|
||||
}
|
||||
|
||||
void m68705_new_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_68705_PRESCALER_EXPIRED:
|
||||
timer_68705_increment(ptr, param);
|
||||
break;
|
||||
default:
|
||||
m68705_device::device_timer(timer, id, param, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void m68705_new_device::device_start()
|
||||
{
|
||||
m68705_device::device_start();
|
||||
|
||||
save_item(NAME(m_tdr));
|
||||
save_item(NAME(m_tcr));
|
||||
|
||||
save_item(NAME(m_port_input));
|
||||
save_item(NAME(m_port_latch));
|
||||
save_item(NAME(m_port_ddr));
|
||||
|
||||
save_item(NAME(m_pcr));
|
||||
save_item(NAME(m_pl_data));
|
||||
save_item(NAME(m_pl_addr));
|
||||
|
||||
for (u8 &input : m_port_input) input = 0xff;
|
||||
for (devcb_read8 &cb : m_port_cb_r) cb.resolve_safe(0xff);
|
||||
for (devcb_write8 &cb : m_port_cb_w) cb.resolve_safe();
|
||||
|
||||
m_pcr = 0xff;
|
||||
m_pl_data = 0xff;
|
||||
m_pl_addr = 0xffff;
|
||||
|
||||
// allocate the MCU timer, and set it to fire NEVER.
|
||||
m_68705_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m68705_new_device::timer_68705_increment),this));
|
||||
m_68705_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
void m68705_new_device::device_reset()
|
||||
{
|
||||
m68705_device::device_reset();
|
||||
|
||||
port_ddr_w<0>(space(AS_PROGRAM), 0, 0x00, 0xff);
|
||||
port_ddr_w<1>(space(AS_PROGRAM), 0, 0x00, 0xff);
|
||||
port_ddr_w<2>(space(AS_PROGRAM), 0, 0x00, 0xff);
|
||||
port_ddr_w<3>(space(AS_PROGRAM), 0, 0x00, 0xff);
|
||||
|
||||
m_pcr |= 0xfb; // b2 (/VPON) is driven by external input and hence unaffected by reset
|
||||
|
||||
m_tdr = 0xff;
|
||||
m_tcr = 0xff;
|
||||
|
||||
//set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
|
||||
m_68705_timer->adjust(attotime::from_hz((clock() / 4) / (1 << 7)));
|
||||
}
|
||||
|
||||
void m68705_new_device::execute_set_input(int inputnum, int state)
|
||||
{
|
||||
switch (inputnum)
|
||||
{
|
||||
case M68705_VPP_LINE:
|
||||
if (ASSERT_LINE == state)
|
||||
m_pcr &= 0xfb;
|
||||
else
|
||||
m_pcr |= 0x40;
|
||||
break;
|
||||
default:
|
||||
m68705_device::execute_set_input(inputnum, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* M68705P3x family
|
||||
****************************************************************************/
|
||||
|
||||
DEVICE_ADDRESS_MAP_START( p_map, 8, m68705p_device )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x07ff)
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
|
||||
AM_RANGE(0x0000, 0x0000) AM_READWRITE(port_r<0>, port_latch_w<0>)
|
||||
AM_RANGE(0x0001, 0x0001) AM_READWRITE(port_r<1>, port_latch_w<1>)
|
||||
AM_RANGE(0x0002, 0x0002) AM_READWRITE(port_r<2>, port_latch_w<2>)
|
||||
// 0x0003 not used (no port D)
|
||||
AM_RANGE(0x0004, 0x0004) AM_WRITE(port_ddr_w<0>)
|
||||
AM_RANGE(0x0005, 0x0005) AM_WRITE(port_ddr_w<1>)
|
||||
AM_RANGE(0x0006, 0x0006) AM_WRITE(port_ddr_w<2>)
|
||||
// 0x0007 not used (no port D)
|
||||
AM_RANGE(0x0008, 0x0008) AM_READWRITE(internal_68705_tdr_r, internal_68705_tdr_w)
|
||||
AM_RANGE(0x0009, 0x0009) AM_READWRITE(internal_68705_tcr_r, internal_68705_tcr_w)
|
||||
// 0x000a not used
|
||||
AM_RANGE(0x000b, 0x000b) AM_READWRITE(pcr_r, pcr_w)
|
||||
// 0x000c-0x000f not used
|
||||
AM_RANGE(0x0010, 0x007f) AM_RAM
|
||||
AM_RANGE(0x0080, 0x0784) AM_READWRITE(eprom_r<0x0080>, eprom_w<0x0080>) // User EPROM
|
||||
AM_RANGE(0x0785, 0x07f7) AM_ROM AM_REGION("bootstrap", 0)
|
||||
AM_RANGE(0x07f8, 0x07ff) AM_READWRITE(eprom_r<0x07f8>, eprom_w<0x07f8>) // Interrupt vectors
|
||||
ADDRESS_MAP_END
|
||||
|
||||
m68705p_device::m68705p_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock,
|
||||
device_type type,
|
||||
char const *name,
|
||||
char const *shortname,
|
||||
char const *source)
|
||||
: m68705_new_device(mconfig, tag, owner, clock, type, name, 11, address_map_delegate(FUNC(m68705p_device::p_map), this), shortname, source)
|
||||
{
|
||||
set_port_open_drain<0>(true); // Port A is open drain with internal pull-ups
|
||||
set_port_mask<2>(0xf0); // Port C is four bits wide
|
||||
set_port_mask<3>(0xff); // Port D isn't present
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* M68705P3 device
|
||||
****************************************************************************/
|
||||
|
||||
m68705p3_device::m68705p3_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
|
||||
: m68705p_device(mconfig, tag, owner, clock, M68705P3, "MC68705P3", "m68705p3", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
tiny_rom_entry const *m68705p3_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(m68705p3);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* M68705P5 device
|
||||
****************************************************************************/
|
||||
|
||||
m68705p5_device::m68705p5_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
|
||||
: m68705p_device(mconfig, tag, owner, clock, M68705P3, "MC68705P5", "m68705p5", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
tiny_rom_entry const *m68705p5_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(m68705p5);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* M68705U3 device
|
||||
****************************************************************************/
|
||||
|
||||
DEVICE_ADDRESS_MAP_START( u_map, 8, m68705u3_device )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x0fff)
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
|
||||
AM_RANGE(0x0000, 0x0000) AM_READWRITE(port_r<0>, port_latch_w<0>)
|
||||
AM_RANGE(0x0001, 0x0001) AM_READWRITE(port_r<1>, port_latch_w<1>)
|
||||
AM_RANGE(0x0002, 0x0002) AM_READWRITE(port_r<2>, port_latch_w<2>)
|
||||
AM_RANGE(0x0003, 0x0003) AM_READWRITE(port_r<3>, port_latch_w<3>)
|
||||
AM_RANGE(0x0004, 0x0004) AM_WRITE(port_ddr_w<0>)
|
||||
AM_RANGE(0x0005, 0x0005) AM_WRITE(port_ddr_w<1>)
|
||||
AM_RANGE(0x0006, 0x0006) AM_WRITE(port_ddr_w<2>)
|
||||
// 0x0007 not used (port D is input only)
|
||||
AM_RANGE(0x0008, 0x0008) AM_READWRITE(internal_68705_tdr_r, internal_68705_tdr_w)
|
||||
AM_RANGE(0x0009, 0x0009) AM_READWRITE(internal_68705_tcr_r, internal_68705_tcr_w)
|
||||
// 0x000a TODO: miscellaneous register
|
||||
AM_RANGE(0x000b, 0x000b) AM_READWRITE(pcr_r, pcr_w)
|
||||
// 0x000c-0x000f not used
|
||||
AM_RANGE(0x0010, 0x007f) AM_RAM
|
||||
AM_RANGE(0x0080, 0x0f38) AM_READWRITE(eprom_r<0x0080>, eprom_w<0x0080>) // User EPROM
|
||||
// 0x0f39-0x0f7f not used
|
||||
AM_RANGE(0x0f80, 0x0ff7) AM_ROM AM_REGION("bootstrap", 0)
|
||||
AM_RANGE(0x0ff8, 0x0fff) AM_READWRITE(eprom_r<0x0ff8>, eprom_w<0x0ff8>) // Interrupt vectors
|
||||
ADDRESS_MAP_END
|
||||
|
||||
m68705u3_device::m68705u3_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
|
||||
: m68705_new_device(mconfig, tag, owner, clock, M68705U3, "MC68705U3", 11, address_map_delegate(FUNC(m68705u3_device::u_map), this), "m68705u3", __FILE__)
|
||||
{
|
||||
set_port_open_drain<0>(true); // Port A is open drain with internal pull-ups
|
||||
}
|
||||
|
||||
tiny_rom_entry const *m68705u3_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(m68705u3);
|
||||
}
|
243
src/devices/cpu/m6805/m68705.h
Normal file
243
src/devices/cpu/m6805/m68705.h
Normal file
@ -0,0 +1,243 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
#ifndef MAME_CPU_M6805_M68705_H
|
||||
#define MAME_CPU_M6805_M68705_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "m6805.h"
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
extern device_type const M68705;
|
||||
extern device_type const M68705P3;
|
||||
extern device_type const M68705P5;
|
||||
extern device_type const M68705U3;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DECLARATIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> m68705_device
|
||||
|
||||
class m68705_device : public m6805_base_device
|
||||
{
|
||||
public:
|
||||
m68705_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
M68705_A = M6805_A,
|
||||
M68705_PC = M6805_PC,
|
||||
M68705_S = M6805_S,
|
||||
M68705_X = M6805_X,
|
||||
M68705_CC = M6805_CC,
|
||||
M68705_IRQ_STATE = M6805_IRQ_STATE
|
||||
};
|
||||
|
||||
m68705_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock,
|
||||
device_type type,
|
||||
char const *name,
|
||||
u32 addr_width,
|
||||
address_map_delegate internal_map,
|
||||
char const *shortname,
|
||||
char const *source);
|
||||
|
||||
virtual void device_reset() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
virtual void interrupt() override;
|
||||
};
|
||||
|
||||
|
||||
// ======================> m68705_new_device
|
||||
|
||||
#define MCFG_M68705_PORTA_R_CB(obj) \
|
||||
devcb = &m68705_new_device::set_port_cb_r<0>(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_M68705_PORTB_R_CB(obj) \
|
||||
devcb = &m68705_new_device::set_port_cb_r<1>(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_M68705_PORTC_R_CB(obj) \
|
||||
devcb = &m68705_new_device::set_port_cb_r<2>(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_M68705_PORTD_R_CB(obj) \
|
||||
devcb = &m68705_new_device::set_port_cb_r<3>(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_M68705_PORTA_W_CB(obj) \
|
||||
devcb = &m68705_new_device::set_port_cb_w<0>(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_M68705_PORTB_W_CB(obj) \
|
||||
devcb = &m68705_new_device::set_port_cb_w<1>(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_M68705_PORTC_W_CB(obj) \
|
||||
devcb = &m68705_new_device::set_port_cb_w<2>(*device, DEVCB_##obj);
|
||||
|
||||
|
||||
class m68705_new_device : public m68705_device
|
||||
{
|
||||
public:
|
||||
// static configuration helpers
|
||||
template<std::size_t N, typename Object> static devcb_base &set_port_cb_r(device_t &device, Object &&obj)
|
||||
{ return downcast<m68705_new_device &>(device).m_port_cb_r[N].set_callback(std::forward<Object>(obj)); }
|
||||
template<std::size_t N, typename Object> static devcb_base &set_port_cb_w(device_t &device, Object &&obj)
|
||||
{ return downcast<m68705_new_device &>(device).m_port_cb_w[N].set_callback(std::forward<Object>(obj)); }
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
PORT_COUNT = 4
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TIMER_68705_PRESCALER_EXPIRED,
|
||||
};
|
||||
|
||||
m68705_new_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock,
|
||||
device_type type,
|
||||
char const *name,
|
||||
u32 addr_width,
|
||||
address_map_delegate internal_map,
|
||||
char const *shortname,
|
||||
char const *source);
|
||||
|
||||
template <offs_t B> DECLARE_READ8_MEMBER(eprom_r);
|
||||
template <offs_t B> DECLARE_WRITE8_MEMBER(eprom_w);
|
||||
|
||||
template <std::size_t N> void set_port_open_drain(bool value);
|
||||
template <std::size_t N> void set_port_mask(u8 mask);
|
||||
template <std::size_t N> DECLARE_WRITE8_MEMBER(port_input_w) { m_port_input[N] = data & ~m_port_mask[N]; }
|
||||
template <std::size_t N> DECLARE_READ8_MEMBER(port_r);
|
||||
template <std::size_t N> DECLARE_WRITE8_MEMBER(port_latch_w);
|
||||
template <std::size_t N> DECLARE_WRITE8_MEMBER(port_ddr_w);
|
||||
template <std::size_t N> void port_cb_w();
|
||||
|
||||
DECLARE_READ8_MEMBER(internal_68705_tdr_r);
|
||||
DECLARE_WRITE8_MEMBER(internal_68705_tdr_w);
|
||||
DECLARE_READ8_MEMBER(internal_68705_tcr_r);
|
||||
DECLARE_WRITE8_MEMBER(internal_68705_tcr_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(pcr_r);
|
||||
DECLARE_WRITE8_MEMBER(pcr_w);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(timer_68705_increment);
|
||||
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
u8 m_tdr;
|
||||
u8 m_tcr;
|
||||
|
||||
/* Timers */
|
||||
emu_timer *m_68705_timer;
|
||||
|
||||
private:
|
||||
required_region_ptr<u8> m_user_rom;
|
||||
|
||||
bool m_port_open_drain[PORT_COUNT];
|
||||
u8 m_port_mask[PORT_COUNT];
|
||||
u8 m_port_input[PORT_COUNT];
|
||||
u8 m_port_latch[PORT_COUNT];
|
||||
u8 m_port_ddr[PORT_COUNT];
|
||||
devcb_read8 m_port_cb_r[PORT_COUNT];
|
||||
devcb_write8 m_port_cb_w[PORT_COUNT];
|
||||
|
||||
u8 m_pcr;
|
||||
u8 m_pl_data;
|
||||
u16 m_pl_addr;
|
||||
};
|
||||
|
||||
|
||||
// ======================> m68705p_device
|
||||
|
||||
class m68705p_device : public m68705_new_device
|
||||
{
|
||||
public:
|
||||
DECLARE_WRITE8_MEMBER(pa_w) { port_input_w<0>(space, offset, data, mem_mask); }
|
||||
DECLARE_WRITE8_MEMBER(pb_w) { port_input_w<1>(space, offset, data, mem_mask); }
|
||||
DECLARE_WRITE8_MEMBER(pc_w) { port_input_w<2>(space, offset, data, mem_mask); }
|
||||
|
||||
protected:
|
||||
DECLARE_ADDRESS_MAP(p_map, 8);
|
||||
|
||||
m68705p_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
u32 clock,
|
||||
device_type type,
|
||||
char const *name,
|
||||
char const *shortname,
|
||||
char const *source);
|
||||
};
|
||||
|
||||
|
||||
// ======================> m68705p3_device
|
||||
|
||||
class m68705p3_device : public m68705p_device
|
||||
{
|
||||
public:
|
||||
m68705p3_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
virtual tiny_rom_entry const *device_rom_region() const override;
|
||||
};
|
||||
|
||||
|
||||
// ======================> m68705p5_device
|
||||
|
||||
class m68705p5_device : public m68705p_device
|
||||
{
|
||||
public:
|
||||
m68705p5_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
virtual tiny_rom_entry const *device_rom_region() const override;
|
||||
};
|
||||
|
||||
|
||||
// ======================> m68705u3_device
|
||||
|
||||
class m68705u3_device : public m68705_new_device
|
||||
{
|
||||
public:
|
||||
m68705u3_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(pa_w) { port_input_w<0>(space, offset, data, mem_mask); }
|
||||
DECLARE_WRITE8_MEMBER(pb_w) { port_input_w<1>(space, offset, data, mem_mask); }
|
||||
DECLARE_WRITE8_MEMBER(pc_w) { port_input_w<2>(space, offset, data, mem_mask); }
|
||||
DECLARE_WRITE8_MEMBER(pd_w) { port_input_w<3>(space, offset, data, mem_mask); } // TODO: PD6 is also /INT2
|
||||
|
||||
protected:
|
||||
DECLARE_ADDRESS_MAP(u_map, 8);
|
||||
|
||||
virtual tiny_rom_entry const *device_rom_region() const override;
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* 68705 section
|
||||
****************************************************************************/
|
||||
|
||||
#define M68705_INT_MASK 0x03
|
||||
#define M68705_IRQ_LINE (M6805_IRQ_LINE + 0)
|
||||
#define M68705_INT_TIMER (M6805_IRQ_LINE + 1)
|
||||
#define M68705_VPP_LINE (M6805_IRQ_LINE + 2)
|
||||
|
||||
#endif // MAME_CPU_M6805_M68705_H
|
@ -787,7 +787,6 @@ DIP locations verified for:
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "includes/arkanoid.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "machine/watchdog.h"
|
||||
|
||||
/***************************************************************************/
|
||||
@ -1322,7 +1321,7 @@ static MACHINE_CONFIG_START( arkanoid, arkanoid_state )
|
||||
|
||||
MCFG_WATCHDOG_ADD("watchdog")
|
||||
|
||||
MCFG_CPU_ADD("mcu", M68705_NEW, XTAL_12MHz/4) /* verified on pcb */
|
||||
MCFG_CPU_ADD("mcu", M68705P5, XTAL_12MHz/4) /* verified on pcb */
|
||||
MCFG_M68705_PORTA_R_CB(READ8(arkanoid_state, mcu_porta_r))
|
||||
MCFG_M68705_PORTA_W_CB(WRITE8(arkanoid_state, mcu_porta_w))
|
||||
MCFG_M68705_PORTB_R_CB(READ8(arkanoid_state, mcu_portb_r))
|
||||
|
@ -279,7 +279,7 @@ TODO:
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/2203intf.h"
|
||||
#include "sound/3526intf.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "includes/bublbobl.h"
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@ Tomasz Slanina
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "includes/changela.h"
|
||||
|
@ -55,7 +55,7 @@ Dip locations verified with manual for ddragon & ddragon2
|
||||
#include "emu.h"
|
||||
#include "cpu/m6809/hd6309.h"
|
||||
#include "cpu/m6800/m6800.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "sound/ym2151.h"
|
||||
|
@ -604,7 +604,7 @@ ROM_START( lkage )
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
|
||||
ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) )
|
||||
|
||||
ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) )
|
||||
|
||||
ROM_REGION( 0x4000, "user1", 0 ) /* data */
|
||||
@ -634,7 +634,7 @@ ROM_START( lkageo )
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
|
||||
ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) )
|
||||
|
||||
ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) )
|
||||
|
||||
ROM_REGION( 0x4000, "user1", 0 ) /* data */
|
||||
@ -664,7 +664,7 @@ ROM_START( lkageoo )
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
|
||||
ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) )
|
||||
|
||||
ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) )
|
||||
|
||||
ROM_REGION( 0x4000, "user1", 0 ) /* data */
|
||||
@ -847,7 +847,7 @@ ROM_START( bygone )
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
|
||||
ROM_LOAD( "a53_07.ic54", 0x0000, 0x8000, CRC(72f69a77) SHA1(dfc1050a4123b3c83ae733ece1b6fe2836beb901) )
|
||||
|
||||
ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */
|
||||
ROM_LOAD( "a51_09.ic53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) ) /* the same as lkage */
|
||||
|
||||
ROM_REGION( 0x4000, "user1", 0 ) /* data */
|
||||
|
@ -27,7 +27,7 @@ ToDo:
|
||||
******************************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
|
||||
|
||||
class m6805evs_state : public driver_device
|
||||
|
@ -35,7 +35,7 @@ The driver has been updated accordingly.
|
||||
#include "includes/matmania.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "sound/3526intf.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "sound/dac.h"
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "includes/atari400.h"
|
||||
#include "sound/speaker.h"
|
||||
#include "sound/pokey.h"
|
||||
|
@ -51,7 +51,7 @@ PS4 J8635 PS4 J8541 PS4 J8648
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "sound/2203intf.h"
|
||||
#include "includes/mexico86.h"
|
||||
|
||||
|
@ -71,7 +71,7 @@ Stephh's notes (based on the games Z80 code and some tests) :
|
||||
#include "sound/2203intf.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "cpu/z80/z80daisy.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
|
||||
|
||||
class pipeline_state : public driver_device
|
||||
|
@ -67,7 +67,7 @@ K1000233A
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
@ -230,7 +230,7 @@ Interrupts:
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "rendlay.h"
|
||||
#include "includes/qix.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
|
@ -83,7 +83,7 @@ Notes:
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "sound/2203intf.h"
|
||||
|
@ -105,7 +105,7 @@ $8000 - $ffff ROM
|
||||
#include "emu.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "sound/3526intf.h"
|
||||
#include "includes/renegade.h"
|
||||
|
||||
|
@ -32,7 +32,7 @@ Notes:
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/sn76496.h"
|
||||
#include "includes/retofinv.h"
|
||||
|
@ -257,7 +257,7 @@ TODO:
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "sound/2203intf.h"
|
||||
#include "includes/stfight.h"
|
||||
|
||||
|
@ -168,7 +168,7 @@ code at z80:0093:
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "sound/samples.h"
|
||||
|
@ -33,7 +33,7 @@ TODO:
|
||||
- plgirls doesn't work without a kludge because of an interrupt issue. This
|
||||
happens because the program enables interrupts before setting IM2, so the
|
||||
interrupt vector is interpreted as IM0, which is obviously bogus.
|
||||
- The puzznic protection is worked around, but I'm not happy with it
|
||||
- The puzznic protection is worked around, but I'm not happy with it
|
||||
(the 68705-returned values are wrong, I'm sure of that).
|
||||
- A bunch of control registers are simply ignored
|
||||
- The source of irqs 0 and 1 is unknown, while 2 is vblank (0 is
|
||||
@ -55,31 +55,37 @@ puzznici note
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/taito_l.h"
|
||||
#include "includes/taitoipt.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
|
||||
#include "audio/taitosnd.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
|
||||
#include "sound/2203intf.h"
|
||||
#include "sound/2610intf.h"
|
||||
#include "sound/msm5205.h"
|
||||
#include "includes/taito_l.h"
|
||||
|
||||
static const char * const bankname[] = { "bank2", "bank3", "bank4", "bank5" };
|
||||
|
||||
static const struct
|
||||
namespace {
|
||||
|
||||
char const *const bankname[] = { "bank2", "bank3", "bank4", "bank5" };
|
||||
|
||||
struct
|
||||
{
|
||||
void (taitol_state::*notifier)(int);
|
||||
uint32_t offset;
|
||||
} rambank_modify_notifiers[12] =
|
||||
u32 offset;
|
||||
} const rambank_modify_notifiers[12] =
|
||||
{
|
||||
{ &taitol_state::taitol_chardef14_m, 0x0000 }, // 14
|
||||
{ &taitol_state::taitol_chardef15_m, 0x1000 }, // 15
|
||||
{ &taitol_state::taitol_chardef16_m, 0x2000 }, // 16
|
||||
{ &taitol_state::taitol_chardef17_m, 0x3000 }, // 17
|
||||
|
||||
{ &taitol_state::taitol_bg18_m, 0x8000 }, // 18
|
||||
{ &taitol_state::taitol_bg19_m, 0x9000 }, // 19
|
||||
{ &taitol_state::taitol_char1a_m, 0xa000 }, // 1a
|
||||
{ &taitol_state::taitol_obj1b_m, 0xb000 }, // 1b
|
||||
{ &taitol_state::taitol_bg18_m, 0x8000 }, // 18
|
||||
{ &taitol_state::taitol_bg19_m, 0x9000 }, // 19
|
||||
{ &taitol_state::taitol_char1a_m, 0xa000 }, // 1a
|
||||
{ &taitol_state::taitol_obj1b_m, 0xb000 }, // 1b
|
||||
|
||||
{ &taitol_state::taitol_chardef1c_m, 0x4000 }, // 1c
|
||||
{ &taitol_state::taitol_chardef1d_m, 0x5000 }, // 1d
|
||||
@ -87,29 +93,26 @@ static const struct
|
||||
{ &taitol_state::taitol_chardef1f_m, 0x7000 }, // 1f
|
||||
};
|
||||
|
||||
u8 const puzznic_mcu_reply[] = { 0x50, 0x1f, 0xb6, 0xba, 0x06, 0x03, 0x47, 0x05, 0x00 };
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
void taitol_state::palette_notifier(int addr)
|
||||
{
|
||||
uint8_t *p = m_palette_ram + (addr & ~1);
|
||||
uint8_t byte0 = *p++;
|
||||
uint8_t byte1 = *p;
|
||||
u8 const *const p = m_palette_ram + (addr & ~1);
|
||||
u8 const byte0 = p[0];
|
||||
u8 const byte1 = p[1];
|
||||
|
||||
// addr &= 0x1ff;
|
||||
|
||||
if (addr > 0x200)
|
||||
{
|
||||
logerror("%s:Large palette ? %03x\n", machine().describe_context(), addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// r = g = b = ((addr & 0x1e) != 0)*255;
|
||||
m_palette->set_pen_color(addr / 2, pal4bit(byte0), pal4bit(byte0 >> 4), pal4bit(byte1));
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t puzznic_mcu_reply[] = { 0x50, 0x1f, 0xb6, 0xba, 0x06, 0x03, 0x47, 0x05, 0x00 };
|
||||
|
||||
void taitol_state::state_register( )
|
||||
void taitol_state::state_register()
|
||||
{
|
||||
save_item(NAME(m_irq_adr_table));
|
||||
save_item(NAME(m_irq_enable));
|
||||
@ -139,7 +142,7 @@ void taitol_state::state_register( )
|
||||
save_item(NAME(m_flipscreen));
|
||||
}
|
||||
|
||||
MACHINE_START_MEMBER(taitol_state,taito_l)
|
||||
MACHINE_START_MEMBER(taitol_state, taito_l)
|
||||
{
|
||||
save_item(NAME(m_rambanks));
|
||||
save_item(NAME(m_palette_ram));
|
||||
@ -150,14 +153,12 @@ MACHINE_START_MEMBER(taitol_state,taito_l)
|
||||
|
||||
void taitol_state::taito_machine_reset()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
m_irq_adr_table[i] = 0;
|
||||
|
||||
m_irq_enable = 0;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_cur_rambank[i] = 0x80;
|
||||
m_current_notifier[i] = &taitol_state::palette_notifier;
|
||||
@ -421,7 +422,7 @@ READ8_MEMBER(taitol_state::rambankswitch_r)
|
||||
return m_cur_rambank[offset];
|
||||
}
|
||||
|
||||
void taitol_state::bank_w(address_space &space, offs_t offset, uint8_t data, int banknum )
|
||||
void taitol_state::bank_w(address_space &space, offs_t offset, u8 data, int banknum )
|
||||
{
|
||||
if (m_current_base[banknum][offset] != data)
|
||||
{
|
||||
@ -702,7 +703,7 @@ ADDRESS_MAP_END
|
||||
|
||||
WRITE8_MEMBER(taitol_state::sound_bankswitch_w)
|
||||
{
|
||||
uint8_t *RAM = memregion("audiocpu")->base();
|
||||
u8 *RAM = memregion("audiocpu")->base();
|
||||
int banknum = data & 0x03;
|
||||
|
||||
membank ("bank7")->set_base (&RAM [(banknum * 0x4000)]);
|
||||
@ -1715,7 +1716,7 @@ WRITE8_MEMBER(taitol_state::portA_w)
|
||||
if (m_cur_bank != (data & 0x03))
|
||||
{
|
||||
int bankaddress;
|
||||
uint8_t *RAM = memregion("audiocpu")->base();
|
||||
u8 *RAM = memregion("audiocpu")->base();
|
||||
|
||||
m_cur_bank = data & 0x03;
|
||||
bankaddress = m_cur_bank * 0x4000;
|
||||
@ -2561,8 +2562,8 @@ ROM_END
|
||||
// bits 7..0 => bits 0..7
|
||||
DRIVER_INIT_MEMBER(taitol_state,plottinga)
|
||||
{
|
||||
uint8_t tab[256];
|
||||
uint8_t *p;
|
||||
u8 tab[256];
|
||||
u8 *p;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
|
@ -168,7 +168,7 @@ TODO:
|
||||
#include "emu.h"
|
||||
#include "includes/taitosj.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "machine/watchdog.h"
|
||||
|
||||
|
||||
|
@ -141,7 +141,7 @@ Updates by Bryan McPhail, 12/12/2004:
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "sound/2203intf.h"
|
||||
#include "includes/xain.h"
|
||||
|
||||
|
@ -56,7 +56,7 @@ ToDo:
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/6821pia.h"
|
||||
#include "machine/z80dma.h"
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "cpu/m6805/m68705.h"
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Brad Oliver,Stephane Humbert
|
||||
/* This it the best way to allow game specific kludges until the system is fully understood */
|
||||
@ -67,7 +69,7 @@ public:
|
||||
|
||||
/* devices */
|
||||
required_device<cpu_device> m_maincpu;
|
||||
optional_device<cpu_device> m_mcu;
|
||||
optional_device<m68705p_device> m_mcu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "sound/msm5205.h"
|
||||
#include "sound/2203intf.h"
|
||||
|
||||
#define TAITOL_SPRITERAM_SIZE 0x400
|
||||
|
||||
class taitol_state : public driver_device
|
||||
{
|
||||
@ -18,14 +17,16 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static constexpr size_t SPRITERAM_SIZE = 0x400;
|
||||
|
||||
/* memory pointers */
|
||||
uint8_t * m_shared_ram;
|
||||
u8 * m_shared_ram;
|
||||
|
||||
/* video-related */
|
||||
tilemap_t *m_bg18_tilemap;
|
||||
tilemap_t *m_bg19_tilemap;
|
||||
tilemap_t *m_ch1a_tilemap;
|
||||
uint8_t m_buff_spriteram[TAITOL_SPRITERAM_SIZE];
|
||||
u8 m_buff_spriteram[SPRITERAM_SIZE];
|
||||
int m_cur_ctrl;
|
||||
int m_horshoes_gfxbank;
|
||||
int m_bankc[4];
|
||||
@ -33,7 +34,7 @@ public:
|
||||
|
||||
/* misc */
|
||||
void (taitol_state::*m_current_notifier[4])(int);
|
||||
uint8_t *m_current_base[4];
|
||||
u8 *m_current_base[4];
|
||||
|
||||
int m_cur_rombank;
|
||||
int m_cur_rombank2;
|
||||
@ -53,7 +54,7 @@ public:
|
||||
int m_last_data;
|
||||
int m_cur_bank;
|
||||
|
||||
const uint8_t *m_mcu_reply;
|
||||
const u8 *m_mcu_reply;
|
||||
int m_mcu_pos;
|
||||
int m_mcu_reply_len;
|
||||
|
||||
@ -70,9 +71,9 @@ public:
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
/* memory buffers */
|
||||
uint8_t m_rambanks[0x1000 * 12];
|
||||
uint8_t m_palette_ram[0x1000];
|
||||
uint8_t m_empty_ram[0x1000];
|
||||
u8 m_rambanks[0x1000 * 12];
|
||||
u8 m_palette_ram[0x1000];
|
||||
u8 m_empty_ram[0x1000];
|
||||
DECLARE_WRITE8_MEMBER(irq_adr_w);
|
||||
DECLARE_READ8_MEMBER(irq_adr_r);
|
||||
DECLARE_WRITE8_MEMBER(irq_enable_w);
|
||||
@ -132,26 +133,26 @@ public:
|
||||
DECLARE_MACHINE_RESET(horshoes);
|
||||
DECLARE_MACHINE_RESET(palamed);
|
||||
DECLARE_MACHINE_RESET(cachat);
|
||||
uint32_t screen_update_taitol(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
u32 screen_update_taitol(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void screen_eof_taitol(screen_device &screen, bool state);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(vbl_interrupt);
|
||||
IRQ_CALLBACK_MEMBER(irq_callback);
|
||||
void taitol_chardef14_m( int offset );
|
||||
void taitol_chardef15_m( int offset );
|
||||
void taitol_chardef16_m( int offset );
|
||||
void taitol_chardef17_m( int offset );
|
||||
void taitol_chardef1c_m( int offset );
|
||||
void taitol_chardef1d_m( int offset );
|
||||
void taitol_chardef1e_m( int offset );
|
||||
void taitol_chardef1f_m( int offset );
|
||||
void taitol_bg18_m( int offset );
|
||||
void taitol_bg19_m( int offset );
|
||||
void taitol_char1a_m( int offset );
|
||||
void taitol_obj1b_m( int offset );
|
||||
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
|
||||
void taitol_chardef14_m(int offset);
|
||||
void taitol_chardef15_m(int offset);
|
||||
void taitol_chardef16_m(int offset);
|
||||
void taitol_chardef17_m(int offset);
|
||||
void taitol_chardef1c_m(int offset);
|
||||
void taitol_chardef1d_m(int offset);
|
||||
void taitol_chardef1e_m(int offset);
|
||||
void taitol_chardef1f_m(int offset);
|
||||
void taitol_bg18_m(int offset);
|
||||
void taitol_bg19_m(int offset);
|
||||
void taitol_char1a_m(int offset);
|
||||
void taitol_obj1b_m(int offset);
|
||||
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void palette_notifier(int addr);
|
||||
void state_register( );
|
||||
void state_register();
|
||||
void taito_machine_reset();
|
||||
void bank_w(address_space &space, offs_t offset, uint8_t data, int banknum );
|
||||
void bank_w(address_space &space, offs_t offset, u8 data, int banknum);
|
||||
DECLARE_WRITE_LINE_MEMBER(champwr_msm5205_vck);
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "machine/gen_latch.h"
|
||||
#include "sound/2203intf.h"
|
||||
#include "sound/msm5205.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "video/tigeroad_spr.h"
|
||||
|
||||
class tigeroad_state : public driver_device
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/arkanoid.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
|
||||
|
||||
/* To log specific reads and writes of the bootlegs */
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6800/m6800.h"
|
||||
#include "cpu/m6805/m6805.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "includes/qix.h"
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ernesto Corvi, Nicola Salmoria, David Haywood
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/taito68705interface.h"
|
||||
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
|
||||
/*
|
||||
Most Taito 68705s share a similar (often identical) hookup.
|
||||
This file encapsulates that.
|
||||
@ -79,7 +81,7 @@ taito68705_mcu_device::taito68705_mcu_device(const machine_config &mconfig, devi
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( taito68705 )
|
||||
MCFG_CPU_ADD("mcu", M68705_NEW, DERIVED_CLOCK(1,1))
|
||||
MCFG_CPU_ADD("mcu", M68705P5, DERIVED_CLOCK(1,1))
|
||||
MCFG_M68705_PORTA_R_CB(READ8(taito68705_mcu_device, mcu_porta_r))
|
||||
MCFG_M68705_PORTA_W_CB(WRITE8(taito68705_mcu_device, mcu_porta_w))
|
||||
MCFG_M68705_PORTB_W_CB(WRITE8(taito68705_mcu_device, mcu_portb_w))
|
||||
|
@ -1,8 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ernesto Corvi, Nicola Salmoria, David Haywood
|
||||
|
||||
#include "cpu/m6805/m6805.h"
|
||||
|
||||
class taito68705_mcu_device : public device_t
|
||||
{
|
||||
public:
|
||||
|
@ -231,7 +231,7 @@ void taitol_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
int offs;
|
||||
|
||||
/* at spriteram + 0x3f0 and 03f8 are the tilemap control registers; spriteram + 0x3e8 seems to be unused */
|
||||
for (offs = 0; offs < TAITOL_SPRITERAM_SIZE - 3 * 8; offs += 8)
|
||||
for (offs = 0; offs < SPRITERAM_SIZE - 3 * 8; offs += 8)
|
||||
{
|
||||
int code, color, sx, sy, flipx, flipy;
|
||||
|
||||
@ -315,6 +315,6 @@ void taitol_state::screen_eof_taitol(screen_device &screen, bool state)
|
||||
{
|
||||
uint8_t *spriteram = m_rambanks + 0xb000;
|
||||
|
||||
memcpy(m_buff_spriteram, spriteram, TAITOL_SPRITERAM_SIZE);
|
||||
memcpy(m_buff_spriteram, spriteram, SPRITERAM_SIZE);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user