summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/drivers/testcpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/drivers/testcpu.c')
-rw-r--r--trunk/src/emu/drivers/testcpu.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/trunk/src/emu/drivers/testcpu.c b/trunk/src/emu/drivers/testcpu.c
new file mode 100644
index 00000000000..09c6f9d2971
--- /dev/null
+++ b/trunk/src/emu/drivers/testcpu.c
@@ -0,0 +1,247 @@
+/*************************************************************************
+
+ testcpu.c
+
+ Example driver for performing CPU stress tests.
+
+****************************************************************************
+
+ 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.
+
+**************************************************************************/
+
+
+#include "emu.h"
+#include "cpu/powerpc/ppc.h"
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define RAM_BASE 0x80000000
+
+
+
+//**************************************************************************
+// DRIVER STATE
+//**************************************************************************
+
+class testcpu_state : public driver_device
+{
+public:
+ // constructor
+ testcpu_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_cpu(*this, "maincpu"),
+ m_ram(*this, "ram")
+ {
+ }
+
+ // timer callback; used to wrest control of the system
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+ {
+ static const UINT32 sample_instructions[] =
+ {
+ 0x3d40f900, // li r10,0xf9000000
+ 0x394af000, // addi r10,r10,-0x1000
+ 0x38600146, // li r3,0x00000146
+ 0x38800004, // li r4,0x00000004
+ 0x7c64572c, // sthbrx r3,r4,r10
+ 0x38600000, // li r3,0x00000000
+ 0x986a0070 // stb r3,0x0070(r10)
+ };
+
+ // iterate over instructions
+ for (int instnum = 0; instnum < ARRAY_LENGTH(sample_instructions); instnum++)
+ {
+ // write the instruction to execute, followed by a BLR which will terminate the
+ // basic block in the DRC
+ m_space->write_dword(RAM_BASE, sample_instructions[instnum]);
+ m_space->write_dword(RAM_BASE + 4, 0x4e800020);
+
+ // initialize the register state
+ m_cpu->set_state(PPC_PC, RAM_BASE);
+ for (int regnum = 0; regnum < 32; regnum++)
+ m_cpu->set_state(PPC_R0 + regnum, regnum | (regnum << 8) | (regnum << 16) | (regnum << 24));
+ m_cpu->set_state(PPC_CR, 0);
+ m_cpu->set_state(PPC_LR, 0x12345678);
+ m_cpu->set_state(PPC_CTR, 0x1000);
+ m_cpu->set_state(PPC_XER, 0);
+ for (int regnum = 0; regnum < 32; regnum++)
+ {
+ double value = double(regnum | (regnum << 8) | (regnum << 16) | (regnum << 24));
+ m_cpu->set_state(PPC_F0 + regnum, d2u(value));
+ }
+
+ // output initial state
+ printf("==================================================\n");
+ printf("Initial state:\n");
+ dump_state(true);
+
+ // execute one instruction
+ *m_cpu->m_icountptr = 0;
+ m_cpu->run();
+
+ // dump the final register state
+ printf("Final state:\n");
+ dump_state(false);
+ }
+
+ // all done; just bail
+ throw emu_fatalerror(0, "All done");
+ }
+
+ // startup code; do basic configuration and set a timer to go off immediately
+ virtual void machine_start()
+ {
+ // find the CPU's address space
+ m_space = m_cpu->space(AS_PROGRAM);
+
+ // configure DRC in the most compatible mode
+ ppcdrc_set_options(m_cpu, PPCDRC_COMPATIBLE_OPTIONS);
+
+ // set a timer to go off right away
+ timer_set(attotime::zero);
+ }
+
+ // dump the current CPU state
+ void dump_state(bool disassemble)
+ {
+ char buffer[256];
+ UINT8 instruction[32];
+ buffer[0] = 0;
+ int bytes = 0;
+ if (disassemble)
+ {
+ // fill in an array of bytes in the CPU's natural order
+ int maxbytes = m_cpu->max_opcode_bytes();
+ for (int bytenum = 0; bytenum < maxbytes; bytenum++)
+ instruction[bytenum] = m_space->read_byte(RAM_BASE + bytenum);
+
+ // disassemble the current instruction
+ bytes = m_cpu->disassemble(buffer, RAM_BASE, instruction, instruction) & DASMFLAG_LENGTHMASK;
+ }
+
+ // output the registers
+ printf("PC : %08X", UINT32(m_cpu->state(PPC_PC)));
+ if (disassemble && bytes > 0)
+ {
+ printf(" => ");
+ for (int bytenum = 0; bytenum < bytes; bytenum++)
+ printf("%02X", instruction[bytenum]);
+ printf(" %s", buffer);
+ }
+ printf("\n");
+ for (int regnum = 0; regnum < 32; regnum++)
+ {
+ printf("R%-2d: %08X ", regnum, UINT32(m_cpu->state(PPC_R0 + regnum)));
+ if (regnum % 4 == 3) printf("\n");
+ }
+ printf("CR : %08X LR : %08X CTR: %08X XER: %08X\n",
+ UINT32(m_cpu->state(PPC_CR)), UINT32(m_cpu->state(PPC_LR)),
+ UINT32(m_cpu->state(PPC_CTR)), UINT32(m_cpu->state(PPC_XER)));
+ for (int regnum = 0; regnum < 32; regnum++)
+ {
+ printf("F%-2d: %10g ", regnum, u2d(m_cpu->state(PPC_F0 + regnum)));
+ if (regnum % 4 == 3) printf("\n");
+ }
+ }
+
+ // report reads from anywhere
+ READ64_MEMBER( general_r )
+ {
+ UINT64 fulloffs = offset;
+ UINT64 result = fulloffs + (fulloffs << 8) + (fulloffs << 16) + (fulloffs << 24) + (fulloffs << 32);
+ printf("Read from %08X & %016" I64FMT "X = %016" I64FMT "X\n", offset * 8, mem_mask, result);
+ return result;
+ }
+
+ // report writes to anywhere
+ WRITE64_MEMBER( general_w )
+ {
+ printf("Write to %08X & %016" I64FMT "X = %016" I64FMT "X\n", offset * 8, mem_mask, data);
+ }
+
+private:
+ // internal state
+ required_device<ppc603e_device> m_cpu;
+ required_shared_ptr<UINT64> m_ram;
+ address_space *m_space;
+};
+
+
+
+//**************************************************************************
+// ADDRESS MAPS
+//**************************************************************************
+
+static ADDRESS_MAP_START( ppc_mem, AS_PROGRAM, 64, testcpu_state )
+ AM_RANGE(RAM_BASE, RAM_BASE+7) AM_RAM AM_SHARE("ram")
+ AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE(general_r, general_w)
+ADDRESS_MAP_END
+
+
+
+//**************************************************************************
+// MACHINE DRIVERS
+//**************************************************************************
+
+static const powerpc_config ppc_config =
+{
+ // 603e, Stretch, 1.3
+ 66000000 // Multiplier 1, Bus = 66MHz, Core = 66MHz
+};
+
+static MACHINE_CONFIG_START( testcpu, testcpu_state )
+
+ // CPUs
+ MCFG_CPU_ADD("maincpu", PPC603E, 66000000)
+ MCFG_CPU_CONFIG(ppc_config)
+ MCFG_CPU_PROGRAM_MAP(ppc_mem)
+MACHINE_CONFIG_END
+
+
+
+//**************************************************************************
+// ROM DEFINITIONS
+//**************************************************************************
+
+ROM_START( testcpu )
+ ROM_REGION( 0x10, "user1", ROMREGION_ERASEFF )
+ROM_END
+
+
+
+//**************************************************************************
+// GAME DRIVERS
+//**************************************************************************
+
+GAME( 2012, testcpu, 0, testcpu, 0, 0, ROT0, "MAME", "CPU Tester", GAME_NO_SOUND )