Converted ASAP CPU core from a legacy CPU core to a modern device.

Renamed device_execute_interface::m_icount to m_icountptr to avoid
commonly-named device values of m_icount.
This commit is contained in:
Aaron Giles 2010-09-07 00:32:49 +00:00
parent a8c12bd3df
commit 2dbd6f67f8
7 changed files with 1369 additions and 1180 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,40 @@
/***************************************************************************
asap.h
Interface file for the portable Atari ASAP emulator.
Written by Aaron Giles
Core implementation for the portable ASAP emulator.
ASAP = Atari Simplified Architecture Processor
****************************************************************************
Copyright Aaron Giles
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@ -12,31 +44,291 @@
#define __ASAP_H__
/***************************************************************************
REGISTER ENUMERATION
***************************************************************************/
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
enum
// ======================> asap_device_config
class asap_device_config : public cpu_device_config
{
ASAP_PC=1,ASAP_PS,
ASAP_R0,ASAP_R1,ASAP_R2,ASAP_R3,ASAP_R4,ASAP_R5,ASAP_R6,ASAP_R7,
ASAP_R8,ASAP_R9,ASAP_R10,ASAP_R11,ASAP_R12,ASAP_R13,ASAP_R14,ASAP_R15,
ASAP_R16,ASAP_R17,ASAP_R18,ASAP_R19,ASAP_R20,ASAP_R21,ASAP_R22,ASAP_R23,
ASAP_R24,ASAP_R25,ASAP_R26,ASAP_R27,ASAP_R28,ASAP_R29,ASAP_R30,ASAP_R31
friend class asap_device;
// construction/destruction
asap_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
public:
// allocators
static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
virtual device_t *alloc_device(running_machine &machine) const;
// inline configuration helpers
static void static_set_pin7(device_config *device, int pin7);
protected:
// device_config_execute_interface overrides
virtual UINT32 execute_min_cycles() const;
virtual UINT32 execute_max_cycles() const;
virtual UINT32 execute_input_lines() const;
// device_config_memory_interface overrides
virtual const address_space_config *memory_space_config(int spacenum = 0) const;
// device_config_disasm_interface overrides
virtual UINT32 disasm_min_opcode_bytes() const;
virtual UINT32 disasm_max_opcode_bytes() const;
// inline data
const address_space_config m_program_config;
};
/***************************************************************************
INTERRUPT CONSTANTS
***************************************************************************/
#define ASAP_IRQ0 0 /* IRQ0 */
// ======================> asap_device
class asap_device : public cpu_device
{
friend class asap_device_config;
// construction/destruction
asap_device(running_machine &_machine, const asap_device_config &config);
public:
// public interfaces
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// device_execute_interface overrides
virtual void execute_run();
virtual void execute_set_input(int inputnum, int state);
// device_state_interface overrides
virtual void state_import(const device_state_entry &entry);
virtual void state_export(const device_state_entry &entry);
virtual void state_string_export(const device_state_entry &entry, astring &string);
// device_disasm_interface overrides
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
// helpers
inline UINT32 readop(offs_t pc);
inline UINT8 readbyte(offs_t address);
inline UINT16 readword(offs_t address);
inline UINT32 readlong(offs_t address);
inline void writebyte(offs_t address, UINT8 data);
inline void writeword(offs_t address, UINT16 data);
inline void writelong(offs_t address, UINT32 data);
inline void generate_exception(int exception);
inline void check_irqs();
inline void fetch_instruction();
inline void fetch_instruction_debug();
inline void execute_instruction();
// condition handlers
void bsp();
void bmz();
void bgt();
void ble();
void bge();
void blt();
void bhi();
void bls();
void bcc();
void bcs();
void bpl();
void bmi();
void bne();
void beq();
void bvc();
void bvs();
// opcode handlers
void noop();
void trap0();
void bsr();
void bsr_0();
void lea();
void lea_c();
void lea_c0();
void leah();
void leah_c();
void leah_c0();
void subr();
void subr_c();
void subr_c0();
void xor_();
void xor_c();
void xor_c0();
void xorn();
void xorn_c();
void xorn_c0();
void add();
void add_c();
void add_c0();
void sub();
void sub_c();
void sub_c0();
void addc();
void addc_c();
void addc_c0();
void subc();
void subc_c();
void subc_c0();
void and_();
void and_c();
void and_c0();
void andn();
void andn_c();
void andn_c0();
void or_();
void or_c();
void or_c0();
void orn();
void orn_c();
void orn_c0();
void ld();
void ld_0();
void ld_c();
void ld_c0();
void ldh();
void ldh_0();
void ldh_c();
void ldh_c0();
void lduh();
void lduh_0();
void lduh_c();
void lduh_c0();
void sth();
void sth_0();
void sth_c();
void sth_c0();
void st();
void st_0();
void st_c();
void st_c0();
void ldb();
void ldb_0();
void ldb_c();
void ldb_c0();
void ldub();
void ldub_0();
void ldub_c();
void ldub_c0();
void stb();
void stb_0();
void stb_c();
void stb_c0();
void ashr();
void ashr_c();
void ashr_c0();
void lshr();
void lshr_c();
void lshr_c0();
void ashl();
void ashl_c();
void ashl_c0();
void rotl();
void rotl_c();
void rotl_c0();
void getps();
void putps();
void jsr();
void jsr_0();
void jsr_c();
void jsr_c0();
void trapf();
// internal state
UINT32 m_pc;
// expanded flags
UINT32 m_pflag;
UINT32 m_iflag;
UINT32 m_cflag;
UINT32 m_vflag;
UINT32 m_znflag;
UINT32 m_flagsio;
// internal stuff
UINT32 m_op;
UINT32 m_ppc;
UINT32 m_nextpc;
UINT8 m_irq_state;
int m_icount;
address_space * m_program;
direct_read_data * m_direct;
// src2val table, registers are at the end
UINT32 m_src2val[65536];
// opcode/condition tables
typedef void (asap_device::*ophandler)();
ophandler m_opcode[32 * 32 * 2];
static const ophandler s_opcodetable[32][4];
static const ophandler s_conditiontable[16];
};
/***************************************************************************
PUBLIC FUNCTIONS
***************************************************************************/
DECLARE_LEGACY_CPU_DEVICE(ASAP, asap);
//**************************************************************************
// ENUMERATIONS
//**************************************************************************
// registers
enum
{
ASAP_PC = 1,
ASAP_PS,
ASAP_R0,
ASAP_R1,
ASAP_R2,
ASAP_R3,
ASAP_R4,
ASAP_R5,
ASAP_R6,
ASAP_R7,
ASAP_R8,
ASAP_R9,
ASAP_R10,
ASAP_R11,
ASAP_R12,
ASAP_R13,
ASAP_R14,
ASAP_R15,
ASAP_R16,
ASAP_R17,
ASAP_R18,
ASAP_R19,
ASAP_R20,
ASAP_R21,
ASAP_R22,
ASAP_R23,
ASAP_R24,
ASAP_R25,
ASAP_R26,
ASAP_R27,
ASAP_R28,
ASAP_R29,
ASAP_R30,
ASAP_R31
};
// input lines
enum
{
ASAP_IRQ0
};
// device type definition
extern const device_type ASAP;
#endif /* __ASAP_H__ */

View File

@ -43,7 +43,7 @@ INLINE char *src2(UINT32 op, int scale)
return temp;
}
CPU_DISASSEMBLE( asap )
offs_t asap_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
{
UINT32 op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24);
int opcode = op >> 27;

View File

@ -301,9 +301,9 @@ void legacy_cpu_device::device_start()
}
// get our icount pointer
m_icount = reinterpret_cast<int *>(get_legacy_runtime_ptr(CPUINFO_PTR_INSTRUCTION_COUNTER));
assert(m_icount != 0);
*m_icount = 0;
m_icountptr = reinterpret_cast<int *>(get_legacy_runtime_ptr(CPUINFO_PTR_INSTRUCTION_COUNTER));
assert(m_icountptr != 0);
*m_icountptr = 0;
}

View File

@ -280,7 +280,7 @@ device_execute_interface::device_execute_interface(running_machine &machine, con
m_iloops(0),
m_partial_frame_timer(NULL),
m_profiler(PROFILER_IDLE),
m_icount(NULL),
m_icountptr(NULL),
m_cycles_running(0),
m_cycles_stolen(0),
m_suspend(0),
@ -326,7 +326,7 @@ bool device_execute_interface::executing() const
INT32 device_execute_interface::cycles_remaining() const
{
return executing() ? *m_icount : 0;
return executing() ? *m_icountptr : 0;
}
@ -342,9 +342,9 @@ void device_execute_interface::eat_cycles(int cycles)
return;
// clamp cycles to the icount and update
if (cycles > *m_icount)
cycles = *m_icount;
*m_icount -= cycles;
if (cycles > *m_icountptr)
cycles = *m_icountptr;
*m_icountptr -= cycles;
}
@ -360,7 +360,7 @@ void device_execute_interface::adjust_icount(int delta)
return;
// aply the delta directly
*m_icount += delta;
*m_icountptr += delta;
}
@ -377,12 +377,12 @@ void device_execute_interface::abort_timeslice()
return;
// swallow the remaining cycles
if (m_icount != NULL)
if (m_icountptr != NULL)
{
int delta = *m_icount;
int delta = *m_icountptr;
m_cycles_stolen += delta;
m_cycles_running -= delta;
*m_icount -= delta;
*m_icountptr -= delta;
}
}
@ -492,8 +492,8 @@ attotime device_execute_interface::local_time() const
attotime result = m_localtime;
if (executing())
{
assert(m_cycles_running >= *m_icount);
int cycles = m_cycles_running - *m_icount;
assert(m_cycles_running >= *m_icountptr);
int cycles = m_cycles_running - *m_icountptr;
result = attotime_add(result, cycles_to_attotime(cycles));
}
return result;
@ -509,8 +509,8 @@ UINT64 device_execute_interface::total_cycles() const
{
if (executing())
{
assert(m_cycles_running >= *m_icount);
return m_totalcycles + m_cycles_running - *m_icount;
assert(m_cycles_running >= *m_icountptr);
return m_totalcycles + m_cycles_running - *m_icountptr;
}
else
return m_totalcycles;
@ -584,7 +584,7 @@ void device_execute_interface::interface_pre_start()
void device_execute_interface::interface_post_start()
{
// make sure somebody set us up the icount
assert_always(m_icount != NULL, "m_icount never initialized!");
assert_always(m_icountptr != NULL, "m_icountptr never initialized!");
}

View File

@ -323,7 +323,7 @@ protected:
// cycle counting and executing
profile_type m_profiler; // profiler tag
int * m_icount; // pointer to the icount
int * m_icountptr; // pointer to the icount
int m_cycles_running; // number of cycles we are executing
int m_cycles_stolen; // number of cycles we artificially stole

View File

@ -187,7 +187,7 @@ if (TEMPLOG)
exec->m_cycles_stolen = 0;
if (TEMPLOG) printf("Executing %s for %d cycles\n", exec->device().tag(), ran);
m_executing_device = exec;
*exec->m_icount = exec->m_cycles_running;
*exec->m_icountptr = exec->m_cycles_running;
if (!call_debugger)
exec->execute_run();
else
@ -198,8 +198,8 @@ if (TEMPLOG) printf("Executing %s for %d cycles\n", exec->device().tag(), ran);
}
// adjust for any cycles we took back
assert(ran >= *exec->m_icount);
ran -= *exec->m_icount;
assert(ran >= *exec->m_icountptr);
ran -= *exec->m_icountptr;
assert(ran >= exec->m_cycles_stolen);
ran -= exec->m_cycles_stolen;
g_profiler.stop();