mirror of
https://github.com/holub/mame
synced 2025-05-29 00:53:09 +03:00
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:
parent
a8c12bd3df
commit
2dbd6f67f8
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,40 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
asap.h
|
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__
|
#define __ASAP_H__
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
//**************************************************************************
|
||||||
REGISTER ENUMERATION
|
// TYPE DEFINITIONS
|
||||||
***************************************************************************/
|
//**************************************************************************
|
||||||
|
|
||||||
enum
|
|
||||||
|
// ======================> asap_device_config
|
||||||
|
|
||||||
|
class asap_device_config : public cpu_device_config
|
||||||
{
|
{
|
||||||
ASAP_PC=1,ASAP_PS,
|
friend class asap_device;
|
||||||
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,
|
// construction/destruction
|
||||||
ASAP_R16,ASAP_R17,ASAP_R18,ASAP_R19,ASAP_R20,ASAP_R21,ASAP_R22,ASAP_R23,
|
asap_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||||
ASAP_R24,ASAP_R25,ASAP_R26,ASAP_R27,ASAP_R28,ASAP_R29,ASAP_R30,ASAP_R31
|
|
||||||
|
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__ */
|
#endif /* __ASAP_H__ */
|
||||||
|
@ -43,7 +43,7 @@ INLINE char *src2(UINT32 op, int scale)
|
|||||||
return temp;
|
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);
|
UINT32 op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24);
|
||||||
int opcode = op >> 27;
|
int opcode = op >> 27;
|
||||||
|
@ -301,9 +301,9 @@ void legacy_cpu_device::device_start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get our icount pointer
|
// get our icount pointer
|
||||||
m_icount = reinterpret_cast<int *>(get_legacy_runtime_ptr(CPUINFO_PTR_INSTRUCTION_COUNTER));
|
m_icountptr = reinterpret_cast<int *>(get_legacy_runtime_ptr(CPUINFO_PTR_INSTRUCTION_COUNTER));
|
||||||
assert(m_icount != 0);
|
assert(m_icountptr != 0);
|
||||||
*m_icount = 0;
|
*m_icountptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ device_execute_interface::device_execute_interface(running_machine &machine, con
|
|||||||
m_iloops(0),
|
m_iloops(0),
|
||||||
m_partial_frame_timer(NULL),
|
m_partial_frame_timer(NULL),
|
||||||
m_profiler(PROFILER_IDLE),
|
m_profiler(PROFILER_IDLE),
|
||||||
m_icount(NULL),
|
m_icountptr(NULL),
|
||||||
m_cycles_running(0),
|
m_cycles_running(0),
|
||||||
m_cycles_stolen(0),
|
m_cycles_stolen(0),
|
||||||
m_suspend(0),
|
m_suspend(0),
|
||||||
@ -326,7 +326,7 @@ bool device_execute_interface::executing() const
|
|||||||
|
|
||||||
INT32 device_execute_interface::cycles_remaining() 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;
|
return;
|
||||||
|
|
||||||
// clamp cycles to the icount and update
|
// clamp cycles to the icount and update
|
||||||
if (cycles > *m_icount)
|
if (cycles > *m_icountptr)
|
||||||
cycles = *m_icount;
|
cycles = *m_icountptr;
|
||||||
*m_icount -= cycles;
|
*m_icountptr -= cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -360,7 +360,7 @@ void device_execute_interface::adjust_icount(int delta)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// aply the delta directly
|
// aply the delta directly
|
||||||
*m_icount += delta;
|
*m_icountptr += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -377,12 +377,12 @@ void device_execute_interface::abort_timeslice()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// swallow the remaining cycles
|
// 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_stolen += delta;
|
||||||
m_cycles_running -= 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;
|
attotime result = m_localtime;
|
||||||
if (executing())
|
if (executing())
|
||||||
{
|
{
|
||||||
assert(m_cycles_running >= *m_icount);
|
assert(m_cycles_running >= *m_icountptr);
|
||||||
int cycles = m_cycles_running - *m_icount;
|
int cycles = m_cycles_running - *m_icountptr;
|
||||||
result = attotime_add(result, cycles_to_attotime(cycles));
|
result = attotime_add(result, cycles_to_attotime(cycles));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -509,8 +509,8 @@ UINT64 device_execute_interface::total_cycles() const
|
|||||||
{
|
{
|
||||||
if (executing())
|
if (executing())
|
||||||
{
|
{
|
||||||
assert(m_cycles_running >= *m_icount);
|
assert(m_cycles_running >= *m_icountptr);
|
||||||
return m_totalcycles + m_cycles_running - *m_icount;
|
return m_totalcycles + m_cycles_running - *m_icountptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return m_totalcycles;
|
return m_totalcycles;
|
||||||
@ -584,7 +584,7 @@ void device_execute_interface::interface_pre_start()
|
|||||||
void device_execute_interface::interface_post_start()
|
void device_execute_interface::interface_post_start()
|
||||||
{
|
{
|
||||||
// make sure somebody set us up the icount
|
// 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!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ protected:
|
|||||||
|
|
||||||
// cycle counting and executing
|
// cycle counting and executing
|
||||||
profile_type m_profiler; // profiler tag
|
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_running; // number of cycles we are executing
|
||||||
int m_cycles_stolen; // number of cycles we artificially stole
|
int m_cycles_stolen; // number of cycles we artificially stole
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ if (TEMPLOG)
|
|||||||
exec->m_cycles_stolen = 0;
|
exec->m_cycles_stolen = 0;
|
||||||
if (TEMPLOG) printf("Executing %s for %d cycles\n", exec->device().tag(), ran);
|
if (TEMPLOG) printf("Executing %s for %d cycles\n", exec->device().tag(), ran);
|
||||||
m_executing_device = exec;
|
m_executing_device = exec;
|
||||||
*exec->m_icount = exec->m_cycles_running;
|
*exec->m_icountptr = exec->m_cycles_running;
|
||||||
if (!call_debugger)
|
if (!call_debugger)
|
||||||
exec->execute_run();
|
exec->execute_run();
|
||||||
else
|
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
|
// adjust for any cycles we took back
|
||||||
assert(ran >= *exec->m_icount);
|
assert(ran >= *exec->m_icountptr);
|
||||||
ran -= *exec->m_icount;
|
ran -= *exec->m_icountptr;
|
||||||
assert(ran >= exec->m_cycles_stolen);
|
assert(ran >= exec->m_cycles_stolen);
|
||||||
ran -= exec->m_cycles_stolen;
|
ran -= exec->m_cycles_stolen;
|
||||||
g_profiler.stop();
|
g_profiler.stop();
|
||||||
|
Loading…
Reference in New Issue
Block a user