summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m6800/m6800.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m6800/m6800.cpp')
-rw-r--r--src/devices/cpu/m6800/m6800.cpp130
1 files changed, 57 insertions, 73 deletions
diff --git a/src/devices/cpu/m6800/m6800.cpp b/src/devices/cpu/m6800/m6800.cpp
index 7eab9292599..17e9cfbd5d4 100644
--- a/src/devices/cpu/m6800/m6800.cpp
+++ b/src/devices/cpu/m6800/m6800.cpp
@@ -1,55 +1,36 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
-/*** m6800: Portable 6800 class emulator *************************************
+/*** m6800: Portable 6800 class emulator *************************************
- m68xx.c
+m68xx.cpp
- References:
+References:
- 6809 Simulator V09, By L.C. Benschop, Eindhoven The Netherlands.
+ 6809 Simulator V09, By L.C. Benschop, Eindhoven The Netherlands.
- m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from
- the 6809 Simulator V09)
+ m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from
+ the 6809 Simulator V09)
- 6809 Microcomputer Programming & Interfacing with Experiments"
- by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc.
+ 6809 Microcomputer Programming & Interfacing with Experiments"
+ by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc.
- System dependencies: uint16_t must be 16 bit unsigned int
- uint8_t must be 8 bit unsigned int
- uint32_t must be more than 16 bits
- arrays up to 65536 bytes must be supported
- machine must be twos complement
+System dependencies: uint16_t must be 16 bit unsigned int
+ uint8_t must be 8 bit unsigned int
+ uint32_t must be more than 16 bits
+ arrays up to 65536 bytes must be supported
+ machine must be twos complement
-History
-991031 ZV
- Added NSC-8105 support
-
-990319 HJB
- Fixed wrong LSB/MSB order for push/pull word.
- Subtract .extra_cycles at the beginning/end of the exectution loops.
-
-990316 HJB
- Renamed to 6800, since that's the basic CPU.
- Added different cycle count tables for M6800/2/8, M6801/3 and m68xx.
-
-990314 HJB
- Also added the M6800 subtype.
-
-990311 HJB
- Added _info functions. Now uses static m6808_Regs struct instead
- of single statics. Changed the 16 bit registers to use the generic
- PAIR union. Registers defined using macros. Split the core into
- four execution loops for M6802, M6803, M6808 and HD63701.
- TST, TSTA and TSTB opcodes reset carry flag.
TODO:
- Verify invalid opcodes for the different CPU types.
- Add proper credits to _info functions.
- Integrate m6808_Flags into the registers (multiple m6808 type CPUs?)
-
-990301 HJB
- Modified the interrupt handling. No more pending interrupt checks.
- WAI opcode saves state, when an interrupt is taken (IRQ or OCI),
- the state is only saved if not already done by WAI.
+- verify invalid opcodes for the different CPU types
+- cleanups (difficult to do maintenance work right now)
+- improve 6801 and derivatives:
+ * make internal I/O map really internal
+ * RAM control register (eg. nvram)
+ * IS3 interrupt for 6801 port 3 handshake (already implemented for 6301Y)
+ * finish 6301Y port 6 handshake, share implementation with p3csr?
+ * 6301Y sci_trcsr2_r/w
+ * add 6801U4 extra timer registers (bublbobl, kikikai, though they seem
+ to work fine without)
*****************************************************************************/
@@ -453,7 +434,7 @@ nsc8105_cpu_device::nsc8105_cpu_device(const machine_config &mconfig, const char
device_memory_interface::space_config_vector m6800_cpu_device::memory_space_config() const
{
- if(has_configured_map(AS_OPCODES))
+ if (has_configured_map(AS_OPCODES))
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config),
std::make_pair(AS_OPCODES, &m_decrypted_opcodes_config)
@@ -467,24 +448,26 @@ device_memory_interface::space_config_vector m6800_cpu_device::memory_space_conf
uint32_t m6800_cpu_device::RM16(uint32_t Addr )
{
uint32_t result = RM(Addr) << 8;
- return result | RM((Addr+1)&0xffff);
+ return result | RM((Addr+1) & 0xffff);
}
void m6800_cpu_device::WM16(uint32_t Addr, PAIR *p )
{
- WM( Addr, p->b.h );
- WM( (Addr+1)&0xffff, p->b.l );
+ WM(Addr, p->b.h);
+ WM((Addr+1) & 0xffff, p->b.l);
}
/* IRQ enter */
void m6800_cpu_device::enter_interrupt(const char *message,uint16_t irq_vector)
{
+ int cycles_to_eat = 0;
+
LOG((message));
- if( m_wai_state & (M6800_WAI|M6800_SLP) )
+ if (m_wai_state & (M6800_WAI | M6800_SLP))
{
- if( m_wai_state & M6800_WAI )
- m_icount -= 4;
- m_wai_state &= ~(M6800_WAI|M6800_SLP);
+ if (m_wai_state & M6800_WAI)
+ cycles_to_eat = 4;
+ m_wai_state &= ~(M6800_WAI | M6800_SLP);
}
else
{
@@ -493,22 +476,23 @@ void m6800_cpu_device::enter_interrupt(const char *message,uint16_t irq_vector)
PUSHBYTE(A);
PUSHBYTE(B);
PUSHBYTE(CC);
- m_icount -= 12;
+ cycles_to_eat = 12;
}
SEI;
- PCD = RM16( irq_vector );
-}
-
+ PCD = RM16(irq_vector);
+ if (cycles_to_eat > 0)
+ increment_counter(cycles_to_eat);
+}
/* check the IRQ lines for pending interrupts */
-void m6800_cpu_device::CHECK_IRQ_LINES()
+void m6800_cpu_device::check_irq_lines()
{
// TODO: IS3 interrupt
if (m_nmi_pending)
{
- if(m_wai_state & M6800_SLP)
+ if (m_wai_state & M6800_SLP)
m_wai_state &= ~M6800_SLP;
m_nmi_pending = false;
@@ -516,19 +500,20 @@ void m6800_cpu_device::CHECK_IRQ_LINES()
}
else
{
- if( m_irq_state[M6800_IRQ_LINE] != CLEAR_LINE )
- { /* standard IRQ */
- if(m_wai_state & M6800_SLP)
+ if (m_irq_state[M6800_IRQ_LINE] != CLEAR_LINE)
+ {
+ /* standard IRQ */
+ if (m_wai_state & M6800_SLP)
m_wai_state &= ~M6800_SLP;
- if( !(CC & 0x10) )
+ if (!(CC & 0x10))
{
enter_interrupt("take IRQ1\n", 0xfff8);
standard_irq_callback(M6800_IRQ_LINE);
}
}
else
- if( !(CC & 0x10) )
+ if (!(CC & 0x10))
m6800_check_irq2();
}
}
@@ -538,9 +523,10 @@ void m6800_cpu_device::increment_counter(int amount)
m_icount -= amount;
}
-void m6800_cpu_device::EAT_CYCLES()
+void m6800_cpu_device::eat_cycles()
{
- increment_counter(m_icount);
+ if (m_icount > 0)
+ increment_counter(m_icount);
}
@@ -605,8 +591,8 @@ void m6800_cpu_device::state_string_export(const device_state_entry &entry, std:
void m6800_cpu_device::device_reset()
{
m_cc = 0xc0;
- SEI; /* IRQ disabled */
- PCD = RM16( 0xfffe );
+ SEI; /* IRQ disabled */
+ PCD = RM16(0xfffe);
m_wai_state = 0;
m_nmi_state = 0;
@@ -637,28 +623,26 @@ void m6800_cpu_device::execute_set_input(int irqline, int state)
****************************************************************************/
void m6800_cpu_device::execute_run()
{
- uint8_t ireg;
-
- CHECK_IRQ_LINES(); /* HJB 990417 */
+ check_irq_lines();
- CLEANUP_COUNTERS();
+ cleanup_counters();
do
{
- if( m_wai_state & (M6800_WAI|M6800_SLP) )
+ if (m_wai_state & (M6800_WAI | M6800_SLP))
{
- EAT_CYCLES();
+ eat_cycles();
}
else
{
pPPC = pPC;
debugger_instruction_hook(PCD);
- ireg=M_RDOP(PCD);
+ uint8_t ireg=M_RDOP(PCD);
PC++;
(this->*m_insn[ireg])();
increment_counter(m_cycles[ireg]);
}
- } while( m_icount>0 );
+ } while (m_icount > 0);
}
std::unique_ptr<util::disasm_interface> m6800_cpu_device::create_disassembler()