mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
cpu/hcd62121, casio/cfx9850.cpp: Various fixes: (#12137)
* cpu/hcd62121: Fixed register accesses from the debugger. * cpu/hcd62121: Implemented the TIME register. * cpu/hcd62121: Implemented more instructions tested on hardware. * cpu/hcd62121: Fixed swap flags - they are always cleared regardless of values. * cpu/hcd62121: Fixed timer so that it expires on KO enabled key input. * cpu/hcd62121: Added an infinite timer variant, (seems to be used with the low power-variant of timer_wait). * casio/cfx9850.cpp: Fixed CFX9850GB display RAM mapping - this one doesn't write to segment 0x60. * casio/cfx9850.cpp: Adjusted palette to better match screenshots in the manual.
This commit is contained in:
parent
9060f36ae8
commit
758a61efe2
@ -21,8 +21,11 @@ TODO:
|
||||
|
||||
#include "emu.h"
|
||||
#include "hcd62121.h"
|
||||
|
||||
#include "hcd62121d.h"
|
||||
|
||||
#include "multibyte.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
@ -39,7 +42,7 @@ enum
|
||||
HCD62121_R70, HCD62121_R74, HCD62121_R78, HCD62121_R7C
|
||||
};
|
||||
|
||||
|
||||
// TODO - Max value stored with "movb reg,f" is 0x3f, is bit 5 set in other instructions?
|
||||
constexpr u8 FLAG_CL = 0x10;
|
||||
constexpr u8 FLAG_Z = 0x08;
|
||||
constexpr u8 FLAG_C = 0x04;
|
||||
@ -62,6 +65,10 @@ hcd62121_cpu_device::hcd62121_cpu_device(const machine_config &mconfig, const ch
|
||||
, m_sseg(0)
|
||||
, m_f(0)
|
||||
, m_time(0)
|
||||
, m_time_op(0)
|
||||
, m_cycles_until_timeout(0)
|
||||
, m_is_timer_started(false)
|
||||
, m_is_infinite_timeout(false)
|
||||
, m_lar(0)
|
||||
, m_opt(0)
|
||||
, m_port(0)
|
||||
@ -83,6 +90,15 @@ device_memory_interface::space_config_vector hcd62121_cpu_device::memory_space_c
|
||||
};
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(hcd62121_cpu_device::timer_tick)
|
||||
{
|
||||
// TODO - Only stores seconds? How can it stop/reset?
|
||||
if (m_is_timer_started)
|
||||
{
|
||||
m_time = (m_time + 1) % 60;
|
||||
}
|
||||
}
|
||||
|
||||
u8 hcd62121_cpu_device::read_op()
|
||||
{
|
||||
u8 d = m_program->read_byte( ( m_cseg << 16 ) | m_ip );
|
||||
@ -137,6 +153,33 @@ void hcd62121_cpu_device::write_reg(int size, u8 op1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hcd62121_cpu_device::read_ireg(int size, u8 op1)
|
||||
{
|
||||
u16 ad = m_reg[(0x40 | op1) & 0x7f ] | (m_reg[(0x40 | (op1 + 1)) & 0x7f] << 8);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
m_temp1[i] = m_program->read_byte((m_dseg << 16) | ad);
|
||||
ad += (op1 & 0x40) ? -1 : 1;
|
||||
}
|
||||
m_lar = ad;
|
||||
}
|
||||
|
||||
|
||||
void hcd62121_cpu_device::write_ireg(int size, u8 op1)
|
||||
{
|
||||
u16 ad = m_reg[(0x40 | op1) & 0x7f] | (m_reg[(0x40 | (op1 + 1)) & 0x7f] << 8);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
m_program->write_byte((m_dseg << 16) | ad, m_temp1[i]);
|
||||
ad += (op1 & 0x40) ? -1 : 1;
|
||||
}
|
||||
m_lar = ad;
|
||||
}
|
||||
|
||||
|
||||
void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
@ -307,6 +350,9 @@ void hcd62121_cpu_device::device_start()
|
||||
{
|
||||
m_program = &space(AS_PROGRAM);
|
||||
|
||||
m_timer = timer_alloc(FUNC(hcd62121_cpu_device::timer_tick), this);
|
||||
m_timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(1));
|
||||
|
||||
save_item(NAME(m_prev_pc));
|
||||
save_item(NAME(m_sp));
|
||||
save_item(NAME(m_ip));
|
||||
@ -315,6 +361,10 @@ void hcd62121_cpu_device::device_start()
|
||||
save_item(NAME(m_dseg));
|
||||
save_item(NAME(m_sseg));
|
||||
save_item(NAME(m_f));
|
||||
save_item(NAME(m_time));
|
||||
save_item(NAME(m_time_op));
|
||||
save_item(NAME(m_is_timer_started));
|
||||
save_item(NAME(m_is_infinite_timeout));
|
||||
save_item(NAME(m_lar));
|
||||
save_item(NAME(m_reg));
|
||||
save_item(NAME(m_temp1));
|
||||
@ -336,51 +386,67 @@ void hcd62121_cpu_device::device_start()
|
||||
state_add(HCD62121_DSIZE, "DSIZE", m_dsize).callimport().callexport().formatstr("%02X");
|
||||
state_add(HCD62121_F, "F", m_f ).callimport().callexport().formatstr("%02X");
|
||||
|
||||
state_add(HCD62121_R00, "R00", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R04, "R04", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R08, "R08", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R0C, "R0C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R10, "R10", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R14, "R14", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R18, "R18", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R1C, "R1C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R20, "R20", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R24, "R24", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R28, "R28", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R2C, "R2C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R30, "R30", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R34, "R34", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R38, "R38", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R3C, "R3C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R40, "R40", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R44, "R44", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R48, "R48", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R4C, "R4C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R50, "R50", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R54, "R54", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R58, "R58", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R5C, "R5C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R60, "R60", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R64, "R64", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R68, "R68", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R6C, "R6C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R70, "R70", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R74, "R74", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R78, "R78", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R7C, "R7C", m_reg[0x00]).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R00, "R00", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R04, "R04", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R08, "R08", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R0C, "R0C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R10, "R10", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R14, "R14", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R18, "R18", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R1C, "R1C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R20, "R20", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R24, "R24", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R28, "R28", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R2C, "R2C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R30, "R30", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R34, "R34", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R38, "R38", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R3C, "R3C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R40, "R40", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R44, "R44", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R48, "R48", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R4C, "R4C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R50, "R50", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R54, "R54", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R58, "R58", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R5C, "R5C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R60, "R60", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R64, "R64", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R68, "R68", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R6C, "R6C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R70, "R70", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R74, "R74", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R78, "R78", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
state_add(HCD62121_R7C, "R7C", m_debugger_temp).callimport().callexport().formatstr("%8s");
|
||||
|
||||
set_icountptr(m_icount);
|
||||
}
|
||||
|
||||
|
||||
void hcd62121_cpu_device::state_import(const device_state_entry &entry)
|
||||
{
|
||||
if ((entry.index() >= HCD62121_R00) && (entry.index() <= HCD62121_R7C))
|
||||
{
|
||||
put_u32be(&m_reg[(entry.index() - HCD62121_R00) * 4], m_debugger_temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hcd62121_cpu_device::state_export(const device_state_entry &entry)
|
||||
{
|
||||
switch (entry.index())
|
||||
if ((entry.index() >= HCD62121_R00) && (entry.index() <= HCD62121_R7C))
|
||||
{
|
||||
case STATE_GENPC:
|
||||
case STATE_GENPCBASE:
|
||||
m_rtemp = (m_cseg << 16) | m_ip;
|
||||
break;
|
||||
m_debugger_temp = get_u32be(&m_reg[(entry.index() - HCD62121_R00) * 4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (entry.index())
|
||||
{
|
||||
case STATE_GENPC:
|
||||
case STATE_GENPCBASE:
|
||||
m_rtemp = (m_cseg << 16) | m_ip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,9 +466,7 @@ void hcd62121_cpu_device::state_string_export(const device_state_entry &entry, s
|
||||
m_f & FLAG_CL ? "CL":"__",
|
||||
m_f & FLAG_ZL ? "ZL":"__",
|
||||
m_f & FLAG_C ? 'C':'_',
|
||||
m_f & FLAG_Z ? 'Z':'_'
|
||||
);
|
||||
|
||||
m_f & FLAG_Z ? 'Z':'_');
|
||||
break;
|
||||
|
||||
case HCD62121_R00:
|
||||
@ -514,6 +578,11 @@ void hcd62121_cpu_device::device_reset()
|
||||
m_sseg = 0;
|
||||
m_lar = 0;
|
||||
m_f = 0;
|
||||
m_time = 0;
|
||||
m_time_op = 0;
|
||||
m_cycles_until_timeout = 0;
|
||||
m_is_timer_started = false;
|
||||
m_is_infinite_timeout = false;
|
||||
m_dsize = 0;
|
||||
m_opt = 0;
|
||||
m_port = 0;
|
||||
@ -666,7 +735,8 @@ inline void hcd62121_cpu_device::op_add(int size)
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (i == size - 1) {
|
||||
if (i == size - 1)
|
||||
{
|
||||
set_cl_flag((m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry > 0x0f);
|
||||
}
|
||||
|
||||
@ -696,7 +766,8 @@ inline void hcd62121_cpu_device::op_addb(int size)
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (i == size - 1) {
|
||||
if (i == size - 1)
|
||||
{
|
||||
set_cl_flag((m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry > 9);
|
||||
}
|
||||
|
||||
@ -731,7 +802,8 @@ inline void hcd62121_cpu_device::op_subb(int size)
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (i == size - 1) {
|
||||
if (i == size - 1)
|
||||
{
|
||||
set_cl_flag((m_temp1[i] & 0x0f) - (m_temp2[i] & 0x0f) - carry < 0);
|
||||
}
|
||||
|
||||
@ -765,7 +837,8 @@ inline void hcd62121_cpu_device::op_sub(int size)
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (i == size - 1) {
|
||||
if (i == size - 1)
|
||||
{
|
||||
set_cl_flag((m_temp1[i] & 0x0f) - (m_temp2[i] & 0x0f) - carry < 0);
|
||||
}
|
||||
|
||||
@ -810,6 +883,26 @@ void hcd62121_cpu_device::execute_run()
|
||||
{
|
||||
do
|
||||
{
|
||||
if (m_ki_cb() != 0)
|
||||
{
|
||||
m_cycles_until_timeout = 0;
|
||||
m_is_infinite_timeout = false;
|
||||
}
|
||||
else if (m_is_infinite_timeout)
|
||||
{
|
||||
m_icount = 0;
|
||||
}
|
||||
else if (m_cycles_until_timeout > 0)
|
||||
{
|
||||
int cycles_to_consume = std::min(m_cycles_until_timeout, m_icount);
|
||||
m_cycles_until_timeout -= cycles_to_consume;
|
||||
m_icount -= cycles_to_consume;
|
||||
}
|
||||
if (m_icount <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
offs_t pc = (m_cseg << 16) | m_ip;
|
||||
|
||||
debugger_instruction_hook(pc);
|
||||
@ -830,9 +923,11 @@ void hcd62121_cpu_device::execute_run()
|
||||
u8 reg1 = read_op();
|
||||
|
||||
// TODO - read_reg should support reading this
|
||||
if (reg1 & 0x80) {
|
||||
if (reg1 & 0x80)
|
||||
{
|
||||
read_reg(size, (reg1 & 0x7f) - size + 1);
|
||||
for (int i=0; i < size - 1; i++) {
|
||||
for (int i=0; i < size - 1; i++)
|
||||
{
|
||||
m_temp1[i] = m_temp1[i + 1];
|
||||
}
|
||||
m_temp1[size-1] = 0;
|
||||
@ -841,7 +936,8 @@ void hcd62121_cpu_device::execute_run()
|
||||
else
|
||||
{
|
||||
read_reg(size, reg1);
|
||||
for (int i = size-1; i > 0; i--) {
|
||||
for (int i = size-1; i > 0; i--)
|
||||
{
|
||||
m_temp1[i] = m_temp1[i - 1];
|
||||
}
|
||||
m_temp1[0] = 0;
|
||||
@ -1152,6 +1248,90 @@ void hcd62121_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x40: /* shrb/shlb ir1,8 */
|
||||
case 0x41: /* shrw/shlw ir1,8 */
|
||||
case 0x42: /* shrq/shlq ir1,8 */
|
||||
case 0x43: /* shrt/shlt ir1,8 */
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg1 = read_op();
|
||||
|
||||
// TODO - read_ireg should support reading this
|
||||
if (reg1 & 0x80)
|
||||
{
|
||||
read_ireg(size, (reg1 & 0x7f) - size + 1);
|
||||
for (int i=0; i < size - 1; i++)
|
||||
{
|
||||
m_temp1[i] = m_temp1[i + 1];
|
||||
}
|
||||
m_temp1[size-1] = 0;
|
||||
write_ireg(size, (reg1 & 0x7f) - size + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
read_ireg(size, reg1);
|
||||
for (int i = size-1; i > 0; i--)
|
||||
{
|
||||
m_temp1[i] = m_temp1[i - 1];
|
||||
}
|
||||
m_temp1[0] = 0;
|
||||
write_ireg(size, reg1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x44: /* mskb ir1,r2 */
|
||||
case 0x45: /* mskw ir1,r2 */
|
||||
case 0x46: /* mskq ir1,r2 */
|
||||
case 0x47: /* mskt ir1,r2 */
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg1 = read_op();
|
||||
u8 reg2 = read_op();
|
||||
|
||||
read_iregreg(size, reg1, reg2, true);
|
||||
|
||||
op_msk(size);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x48: /* shrb/shlb ir1,4 */
|
||||
case 0x49: /* shrw/shlw ir1,4 */
|
||||
case 0x4A: /* shrq/shlq ir1,4 */
|
||||
case 0x4B: /* shrt/shlt ir1,4 */
|
||||
/* Nibble shift */
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg1 = read_op();
|
||||
u8 d1 = 0, d2 = 0;
|
||||
|
||||
read_ireg(size, reg1);
|
||||
|
||||
if (reg1 & 0x80)
|
||||
{
|
||||
// shift right
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
d1 = (m_temp1[i] & 0x0f) << 4;
|
||||
m_temp1[i] = (m_temp1[i] >> 4) | d2;
|
||||
d2 = d1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// shift left
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
d1 = (m_temp1[i] & 0xf0) >> 4;
|
||||
m_temp1[i] = (m_temp1[i] << 4) | d2;
|
||||
d2 = d1;
|
||||
}
|
||||
}
|
||||
|
||||
write_ireg(size, reg1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4C: /* testb ir1,r2 */
|
||||
case 0x4D: /* testw ir1,r2 */
|
||||
case 0x4E: /* testq ir1,r2 */
|
||||
@ -1232,6 +1412,41 @@ void hcd62121_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x60: /* shrb ir1,1 */
|
||||
case 0x61: /* shrw ir1,1 */
|
||||
case 0x62: /* shrq ir1,1 */
|
||||
case 0x63: /* shrt ir1,1 */
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg1 = read_op();
|
||||
u8 d1 = 0, d2 = 0;
|
||||
bool zero_high = true;
|
||||
bool zero_low = true;
|
||||
|
||||
read_ireg(size, reg1);
|
||||
|
||||
d2 = 0;
|
||||
set_cl_flag ((m_temp1[0] & (1U<<4)) != 0U);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
d1 = (m_temp1[i] & 0x01) << 7;
|
||||
m_temp1[i] = (m_temp1[i] >> 1) | d2;
|
||||
d2 = d1;
|
||||
if (m_temp1[i] & 0xf0)
|
||||
zero_high = false;
|
||||
if (m_temp1[i] & 0x0f)
|
||||
zero_low = false;
|
||||
}
|
||||
|
||||
write_ireg(size, reg1);
|
||||
|
||||
set_zero_flag(zero_high && zero_low);
|
||||
set_zh_flag(zero_high);
|
||||
set_zl_flag(zero_low);
|
||||
set_carry_flag (d2 != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x64: /* orb ir1,r2 */
|
||||
case 0x65: /* orb ir1,r2 */
|
||||
case 0x66: /* orb ir1,r2 */
|
||||
@ -1249,6 +1464,40 @@ void hcd62121_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x68: /* shlb ir1,1 */
|
||||
case 0x69: /* shlw ir1,1 */
|
||||
case 0x6A: /* shlq ir1,1 */
|
||||
case 0x6B: /* shlt ir1,1 */
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg1 = read_op();
|
||||
u8 d1 = 0, d2 = 0;
|
||||
bool zero_high = true;
|
||||
bool zero_low = true;
|
||||
|
||||
read_ireg(size, reg1);
|
||||
|
||||
set_cl_flag ((m_temp1[0] & (1U<<3)) != 0U);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
d1 = (m_temp1[i] & 0x80) >> 7;
|
||||
m_temp1[i] = (m_temp1[i] << 1) | d2;
|
||||
d2 = d1;
|
||||
|
||||
if (m_temp1[i] & 0xf0)
|
||||
zero_high = false;
|
||||
if (m_temp1[i] & 0x0f)
|
||||
zero_low = false;
|
||||
}
|
||||
|
||||
write_ireg(size, reg1);
|
||||
set_zero_flag(zero_high && zero_low);
|
||||
set_zh_flag(zero_high);
|
||||
set_zl_flag(zero_low);
|
||||
set_carry_flag (d2 != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x6C: /* andb ir1,r2 */
|
||||
case 0x6D: /* andw ir1,r2 */
|
||||
case 0x6E: /* andq ir1,r2 */
|
||||
@ -1266,6 +1515,23 @@ void hcd62121_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x70: /* subbb ir1,r2 */
|
||||
case 0x71: /* subbw ir1,r2 */
|
||||
case 0x72: /* subbq ir1,r2 */
|
||||
case 0x73: /* subbt ir1,r2 */
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg1 = read_op();
|
||||
u8 reg2 = read_op();
|
||||
|
||||
read_iregreg(size, reg1, reg2, false);
|
||||
|
||||
op_subb(size);
|
||||
|
||||
write_iregreg(size, reg1, reg2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x74: /* subb ir1,r2 */
|
||||
case 0x75: /* subw ir1,r2 */
|
||||
case 0x76: /* subq ir1,r2 */
|
||||
@ -1350,7 +1616,8 @@ void hcd62121_cpu_device::execute_run()
|
||||
case 0x8C: /* bstack_to_dmem */
|
||||
{
|
||||
int size = m_dsize + 1;
|
||||
for (int i=0; i < size; i++) {
|
||||
for (int i=0; i < size; i++)
|
||||
{
|
||||
u8 byte = m_program->read_byte((m_sseg << 16) | m_sp);
|
||||
m_program->write_byte((m_dseg << 16) | m_lar, byte);
|
||||
m_sp--;
|
||||
@ -1362,7 +1629,8 @@ void hcd62121_cpu_device::execute_run()
|
||||
case 0x8D: /* fstack_to_dmem */
|
||||
{
|
||||
int size = m_dsize + 1;
|
||||
for (int i=0; i < size; i++) {
|
||||
for (int i=0; i < size; i++)
|
||||
{
|
||||
u8 byte = m_program->read_byte((m_sseg << 16) | m_sp);
|
||||
m_program->write_byte((m_dseg << 16) | m_lar, byte);
|
||||
m_sp++;
|
||||
@ -1443,7 +1711,9 @@ void hcd62121_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xB0: /* unk_B0 reg/i8 */
|
||||
case 0xB1: /* unk_B1 reg/i8 - PORTx control/direction? */
|
||||
case 0xB2: /* unk_B2 reg/i8 */
|
||||
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
|
||||
read_op();
|
||||
break;
|
||||
@ -1452,7 +1722,8 @@ void hcd62121_cpu_device::execute_run()
|
||||
{
|
||||
u8 arg = read_op();
|
||||
|
||||
m_time = arg;
|
||||
m_time_op = arg;
|
||||
m_is_timer_started = true;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1478,7 +1749,6 @@ void hcd62121_cpu_device::execute_run()
|
||||
break;
|
||||
|
||||
case 0xBB: /* jmpcl a16 */
|
||||
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
|
||||
{
|
||||
u8 a1 = read_op();
|
||||
u8 a2 = read_op();
|
||||
@ -1489,7 +1759,6 @@ void hcd62121_cpu_device::execute_run()
|
||||
break;
|
||||
|
||||
case 0xBF: /* jmpncl a16 */
|
||||
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
|
||||
{
|
||||
u8 a1 = read_op();
|
||||
u8 a2 = read_op();
|
||||
@ -1499,10 +1768,17 @@ void hcd62121_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
//case 0xC0: /* movb reg,i8 */ // TODO - test
|
||||
/*
|
||||
These instructions do not modify any general purpose registers or memory,
|
||||
but might be implemented on other CPUs with the same instruction set.
|
||||
*/
|
||||
case 0xC0: /* nop reg,i8 */
|
||||
case 0xC2: /* nop reg,i8 */
|
||||
case 0xC3: /* nop reg,i8 */
|
||||
logerror("%02x:%04x: nop instruction %02x %02x,%02x\n", m_cseg, m_ip-1, op, read_op(), read_op());
|
||||
break;
|
||||
|
||||
case 0xC1: /* movw reg,i16 */
|
||||
//case 0xC2: /* movw reg,i64 */ // TODO - test
|
||||
//case 0xC3: /* movw reg,i80 */ // TODO - test
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg = read_op();
|
||||
@ -1554,7 +1830,8 @@ void hcd62121_cpu_device::execute_run()
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
m_lar += pre_inc;
|
||||
if (arg1 & 0x80) {
|
||||
if (arg1 & 0x80)
|
||||
{
|
||||
m_program->write_byte((m_dseg << 16) | m_lar, arg2);
|
||||
}
|
||||
else
|
||||
@ -1580,13 +1857,14 @@ void hcd62121_cpu_device::execute_run()
|
||||
case 0xCC: /* swapb ir1,r2 */
|
||||
case 0xCD: /* swapw ir1,r2 */
|
||||
case 0xCE: /* swapq ir1,r2 */
|
||||
case 0xCF: /* swapt ir1,r2? */
|
||||
case 0xCF: /* swapt ir1,r2 */
|
||||
{
|
||||
int size = datasize(op);
|
||||
u8 reg1 = read_op();
|
||||
u8 reg2 = read_op();
|
||||
|
||||
if (reg1 & 0x80) {
|
||||
if (reg1 & 0x80)
|
||||
{
|
||||
fatalerror("%02x:%04x: unimplemented swap with immediate encountered\n", m_cseg, m_ip-1);
|
||||
}
|
||||
|
||||
@ -1601,7 +1879,8 @@ void hcd62121_cpu_device::execute_run()
|
||||
|
||||
write_iregreg(size, reg1, reg2);
|
||||
write_iregreg2(size, reg1, reg2);
|
||||
// TODO - are flags affected?
|
||||
|
||||
m_f = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1705,6 +1984,10 @@ void hcd62121_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE5: /* movb reg,TIME */
|
||||
m_reg[read_op() & 0x7f] = m_time;
|
||||
break;
|
||||
|
||||
case 0xE6: /* movb reg,PORT */
|
||||
m_reg[read_op() & 0x7f] = m_port;
|
||||
break;
|
||||
@ -1761,18 +2044,20 @@ void hcd62121_cpu_device::execute_run()
|
||||
case 0xF1: /* unk_F1 reg/i8 (out?) */
|
||||
case 0xF3: /* unk_F3 reg/i8 (out?) */
|
||||
case 0xF5: /* unk_F5 reg/i8 (out?) */
|
||||
case 0xF6: /* unk_F6 reg/i8 (out?) */
|
||||
case 0xF7: /* timer_ctrl i8 */
|
||||
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
|
||||
read_op();
|
||||
break;
|
||||
|
||||
case 0xFC: /* unk_FC - disable interrupts/stop timer?? */
|
||||
case 0xFD: /* unk_FD */
|
||||
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
|
||||
break;
|
||||
|
||||
case 0xFD: /* timer_wait_low (no X1 clock, address or data bus activity) */
|
||||
case 0xFE: /* timer_wait */
|
||||
if (m_time & 0x01) {
|
||||
if (m_time_op & 0x01)
|
||||
{
|
||||
/*
|
||||
When timer control is set with operand 0xC0, the CPU periodically reads
|
||||
from external RAM (address range 0x7c00..0x7fff) at an interval of
|
||||
@ -1787,8 +2072,13 @@ void hcd62121_cpu_device::execute_run()
|
||||
the timer wait execution.
|
||||
*/
|
||||
const u64 TIMER_STATE_READ_CYCLES = 832 + 64;
|
||||
u64 cycles_until_timeout = 0;
|
||||
switch (m_time) {
|
||||
switch (m_time_op)
|
||||
{
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
// Likely only timeouts on KO enabled input.
|
||||
m_is_infinite_timeout = true;
|
||||
break;
|
||||
case 0x11:
|
||||
case 0x13:
|
||||
case 0x15:
|
||||
@ -1846,7 +2136,7 @@ void hcd62121_cpu_device::execute_run()
|
||||
case 0xdd:
|
||||
case 0xdf:
|
||||
// Approximately 814.32us
|
||||
cycles_until_timeout = 0x4 * TIMER_STATE_READ_CYCLES;
|
||||
m_cycles_until_timeout = 0x4 * TIMER_STATE_READ_CYCLES;
|
||||
break;
|
||||
case 0x21:
|
||||
case 0x23:
|
||||
@ -1873,7 +2163,7 @@ void hcd62121_cpu_device::execute_run()
|
||||
case 0xad:
|
||||
case 0xaf:
|
||||
// Approximately 1.63ms
|
||||
cycles_until_timeout = 0x8 * TIMER_STATE_READ_CYCLES;
|
||||
m_cycles_until_timeout = 0x8 * TIMER_STATE_READ_CYCLES;
|
||||
break;
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
@ -1888,34 +2178,35 @@ void hcd62121_cpu_device::execute_run()
|
||||
case 0xcd:
|
||||
case 0xcf:
|
||||
// Approximately 209.34ms
|
||||
cycles_until_timeout = 0x400 * TIMER_STATE_READ_CYCLES;
|
||||
m_cycles_until_timeout = 0x400 * TIMER_STATE_READ_CYCLES;
|
||||
break;
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
case 0xc9:
|
||||
case 0xcb:
|
||||
// Approximately 837.61ms
|
||||
cycles_until_timeout = 0x1000 * TIMER_STATE_READ_CYCLES;
|
||||
m_cycles_until_timeout = 0x1000 * TIMER_STATE_READ_CYCLES;
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x43:
|
||||
case 0xc1:
|
||||
case 0xc3:
|
||||
// Approximately 1.68s
|
||||
cycles_until_timeout = 0x2000 * TIMER_STATE_READ_CYCLES;
|
||||
m_cycles_until_timeout = 0x2000 * TIMER_STATE_READ_CYCLES;
|
||||
break;
|
||||
case 0x81:
|
||||
case 0x83:
|
||||
// Approximately 100.58s
|
||||
cycles_until_timeout = 0x7a800 * TIMER_STATE_READ_CYCLES;
|
||||
m_cycles_until_timeout = 0x7a800 * TIMER_STATE_READ_CYCLES;
|
||||
break;
|
||||
default:
|
||||
logerror("%02x:%04x: unimplemented timer value %02x encountered\n", m_cseg, m_ip-1, m_time);
|
||||
logerror("%02x:%04x: unimplemented timer value %02x encountered\n", m_cseg, m_ip-1, m_time_op);
|
||||
break;
|
||||
}
|
||||
m_icount -= cycles_until_timeout;
|
||||
} else {
|
||||
logerror("%02x:%04x: wait for disabled timer? value %02x\n", m_cseg, m_ip-1, m_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("%02x:%04x: wait for disabled timer? value %02x\n", m_cseg, m_ip-1, m_time_op);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -48,6 +48,7 @@ protected:
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
// device_state_interface overrides
|
||||
virtual void state_import(const device_state_entry &entry) override;
|
||||
virtual void state_export(const device_state_entry &entry) override;
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
@ -55,10 +56,13 @@ protected:
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
private:
|
||||
TIMER_CALLBACK_MEMBER(timer_tick);
|
||||
u8 read_op();
|
||||
u8 datasize(u8 op);
|
||||
void read_reg(int size, u8 op1);
|
||||
void write_reg(int size, u8 op1);
|
||||
void read_ireg(int size, u8 op1);
|
||||
void write_ireg(int size, u8 op1);
|
||||
void read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate);
|
||||
void write_regreg(int size, u8 op1, u8 op2);
|
||||
void read_iregreg(int size, u8 op1, u8 op2, bool copy_extend_immediate);
|
||||
@ -92,6 +96,11 @@ private:
|
||||
u8 m_sseg;
|
||||
u8 m_f;
|
||||
u8 m_time;
|
||||
u8 m_time_op;
|
||||
s32 m_cycles_until_timeout;
|
||||
bool m_is_timer_started;
|
||||
bool m_is_infinite_timeout;
|
||||
emu_timer *m_timer;
|
||||
u16 m_lar;
|
||||
u8 m_reg[0x80];
|
||||
|
||||
@ -105,6 +114,8 @@ private:
|
||||
u8 m_temp2[0x10];
|
||||
u32 m_rtemp;
|
||||
|
||||
u32 m_debugger_temp;
|
||||
|
||||
address_space *m_program;
|
||||
|
||||
int m_icount;
|
||||
|
@ -117,18 +117,18 @@ const hcd62121_disassembler::dasm hcd62121_disassembler::ops[256] =
|
||||
{ "callnc", ARG_A16, ARG_NONE }, { "callnz", ARG_A16, ARG_NONE },
|
||||
|
||||
/* 0xb0 */
|
||||
{ "unB0?", ARG_NONE, ARG_NONE }, { "unB1?", ARG_I8, ARG_NONE },
|
||||
{ "unB2?", ARG_NONE, ARG_NONE }, { "unB3?", ARG_I8, ARG_NONE },
|
||||
{ "out", ARG_KHI, ARG_REG }, { "out", ARG_KHI, ARG_I8 },
|
||||
{ "out", ARG_KLO, ARG_REG }, { "out", ARG_KLO, ARG_I8 },
|
||||
{ "unB8?", ARG_NONE, ARG_NONE }, { "unB9?", ARG_I8, ARG_NONE },
|
||||
{ "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE },
|
||||
{ "unBC?", ARG_I8, ARG_NONE }, { "unBD?", ARG_NONE, ARG_NONE },
|
||||
{ "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl", ARG_A16, ARG_NONE },
|
||||
{ "unB0?", ARG_I8, ARG_NONE }, { "unB1?", ARG_I8, ARG_NONE },
|
||||
{ "unB2?", ARG_I8, ARG_NONE }, { "timer_set", ARG_I8, ARG_NONE },
|
||||
{ "out", ARG_KHI, ARG_REG }, { "out", ARG_KHI, ARG_I8 },
|
||||
{ "out", ARG_KLO, ARG_REG }, { "out", ARG_KLO, ARG_I8 },
|
||||
{ "unB8?", ARG_NONE, ARG_NONE }, { "unB9?", ARG_I8, ARG_NONE },
|
||||
{ "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE },
|
||||
{ "unBC?", ARG_I8, ARG_NONE }, { "unBD?", ARG_NONE, ARG_NONE },
|
||||
{ "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl", ARG_A16, ARG_NONE },
|
||||
|
||||
/* 0xc0 */
|
||||
{ "movb", ARG_REG, ARG_I8 }, { "movw", ARG_REG, ARG_I16 },
|
||||
{ "movq", ARG_REG, ARG_I64 }, { "movt", ARG_REG, ARG_I80 },
|
||||
{ "movq", ARG_REG, ARG_I8 }, { "movt", ARG_REG, ARG_I8 },
|
||||
{ "movb", ARG_ILR, ARG_ILR }, { "movw", ARG_ILR, ARG_ILR },
|
||||
{ "movq", ARG_ILR, ARG_ILR }, { "movt", ARG_ILR, ARG_ILR },
|
||||
{ "unC8?", ARG_NONE, ARG_NONE }, { "unC9?", ARG_NONE, ARG_NONE },
|
||||
@ -149,7 +149,7 @@ const hcd62121_disassembler::dasm hcd62121_disassembler::ops[256] =
|
||||
/* 0xe0 */
|
||||
{ "in0", ARG_REG, ARG_NONE }, { "movb", ARG_REG, ARG_OPT },
|
||||
{ "in", ARG_REG, ARG_KI }, { "movb", ARG_REG, ARG_DSZ },
|
||||
{ "movb", ARG_REG, ARG_F }, { "unE5?", ARG_I8, ARG_NONE },
|
||||
{ "movb", ARG_REG, ARG_F }, { "movb", ARG_REG, ARG_TIME },
|
||||
{ "movb", ARG_REG, ARG_PORT }, { "unE7?", ARG_I8, ARG_NONE },
|
||||
{ "movw", ARG_REG, ARG_LAR }, { "movw?", ARG_REG, ARG_LAR },
|
||||
{ "movw", ARG_REG, ARG_PC }, { "movw", ARG_REG, ARG_SP },
|
||||
@ -157,14 +157,14 @@ const hcd62121_disassembler::dasm hcd62121_disassembler::ops[256] =
|
||||
{ "movb", ARG_REG, ARG_CS }, { "movb", ARG_REG, ARG_SS },
|
||||
|
||||
/* 0xf0 */
|
||||
{ "movb", ARG_OPT, ARG_REG }, { "unF1?", ARG_I8, ARG_NONE },
|
||||
{ "movb", ARG_PORT, ARG_REG }, { "unF3?", ARG_I8, ARG_NONE },
|
||||
{ "unF4?", ARG_I8, ARG_NONE }, { "unF5?", ARG_I8, ARG_NONE },
|
||||
{ "unF6?", ARG_I8, ARG_NONE }, { "unF7?", ARG_I8, ARG_NONE },
|
||||
{ "unF8?", ARG_NONE, ARG_NONE }, { "unF9?", ARG_NONE, ARG_NONE },
|
||||
{ "unFA?", ARG_NONE, ARG_NONE }, { "unFb?", ARG_NONE, ARG_NONE },
|
||||
{ "unFC?", ARG_NONE, ARG_NONE }, { "unFD?", ARG_NONE, ARG_NONE },
|
||||
{ "unFE?", ARG_NONE, ARG_NONE }, { "nop", ARG_NONE, ARG_NONE }
|
||||
{ "movb", ARG_OPT, ARG_REG }, { "unF1?", ARG_I8, ARG_NONE },
|
||||
{ "movb", ARG_PORT, ARG_REG }, { "unF3?", ARG_I8, ARG_NONE },
|
||||
{ "unF4?", ARG_I8, ARG_NONE }, { "unF5?", ARG_I8, ARG_NONE },
|
||||
{ "unF6?", ARG_I8, ARG_NONE }, { "timer_ctrl", ARG_I8, ARG_NONE },
|
||||
{ "unF8?", ARG_NONE, ARG_NONE }, { "unF9?", ARG_NONE, ARG_NONE },
|
||||
{ "unFA?", ARG_NONE, ARG_NONE }, { "unFb?", ARG_NONE, ARG_NONE },
|
||||
{ "unFC?", ARG_NONE, ARG_NONE }, { "timer_wait_low", ARG_NONE, ARG_NONE },
|
||||
{ "timer_wait", ARG_NONE, ARG_NONE }, { "nop", ARG_NONE, ARG_NONE }
|
||||
};
|
||||
|
||||
u32 hcd62121_disassembler::opcode_alignment() const
|
||||
@ -186,9 +186,9 @@ offs_t hcd62121_disassembler::disassemble(std::ostream &stream, offs_t pc, const
|
||||
|
||||
/* Special cases for shift and rotate instructions */
|
||||
if (inst->arg2 == ARG_S4 || inst->arg2 == ARG_S8)
|
||||
util::stream_format(stream, "%c%c%c%c ", inst->str[0], inst->str[1], (opcodes.r8(pc) & 0x80) ? 'r' : 'l', inst->str[3]);
|
||||
util::stream_format(stream, "%c%c%c%c ", inst->str[0], inst->str[1], (opcodes.r8(pc) & 0x80) ? 'r' : 'l', inst->str[3]);
|
||||
else
|
||||
util::stream_format(stream, "%-8s", inst->str);
|
||||
util::stream_format(stream, "%-12s", inst->str);
|
||||
|
||||
switch(inst->arg1)
|
||||
{
|
||||
@ -318,8 +318,8 @@ offs_t hcd62121_disassembler::disassemble(std::ostream &stream, offs_t pc, const
|
||||
case ARG_PORT:
|
||||
util::stream_format(stream, "PORT");
|
||||
break;
|
||||
case ARG_TIM:
|
||||
util::stream_format(stream, "TIM?");
|
||||
case ARG_TIME:
|
||||
util::stream_format(stream, "TIME");
|
||||
break;
|
||||
case ARG_KLO:
|
||||
util::stream_format(stream, "KOL");
|
||||
@ -408,8 +408,8 @@ offs_t hcd62121_disassembler::disassemble(std::ostream &stream, offs_t pc, const
|
||||
case ARG_PORT:
|
||||
util::stream_format(stream, ",PORT");
|
||||
break;
|
||||
case ARG_TIM:
|
||||
util::stream_format(stream, ",TIM?");
|
||||
case ARG_TIME:
|
||||
util::stream_format(stream, ",TIME");
|
||||
break;
|
||||
case ARG_KI:
|
||||
util::stream_format(stream, ",KI");
|
||||
|
@ -47,7 +47,7 @@ private:
|
||||
ARG_DSZ, /* dsize register? */
|
||||
ARG_OPT, /* OPTx (output) pins */
|
||||
ARG_PORT, /* PORTx (output) pins */
|
||||
ARG_TIM, /* timing related register? */
|
||||
ARG_TIME, /* timing related register */
|
||||
ARG_KLO, /* KO1 - KO8 output lines */
|
||||
ARG_KHI, /* KO9 - KO14(?) output lines */
|
||||
ARG_KI, /* K input lines */
|
||||
|
@ -38,10 +38,10 @@ class cfx9850_state : public driver_device
|
||||
public:
|
||||
cfx9850_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_video_ram(*this, "video_ram")
|
||||
, m_display_ram(*this, "display_ram")
|
||||
, m_ko_port(*this, "KO%u", 1)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_ko(0)
|
||||
, m_port(0)
|
||||
, m_opt(0)
|
||||
@ -49,11 +49,13 @@ public:
|
||||
|
||||
void cfx9850(machine_config &config);
|
||||
|
||||
protected:
|
||||
required_device<hcd62121_cpu_device> m_maincpu;
|
||||
|
||||
private:
|
||||
required_shared_ptr<u8> m_video_ram;
|
||||
required_shared_ptr<u8> m_display_ram;
|
||||
required_ioport_array<12> m_ko_port;
|
||||
required_device<hcd62121_cpu_device> m_maincpu;
|
||||
|
||||
u16 m_ko; // KO lines KO1 - KO14
|
||||
u8 m_port; // PORT lines PORT0 - PORT7 (serial I/O)
|
||||
@ -74,7 +76,7 @@ private:
|
||||
|
||||
void cfx9850_state::cfx9850_mem(address_map &map)
|
||||
{
|
||||
map(0x000000, 0x007fff).rom();
|
||||
map(0x000000, 0x007fff).mirror(0x008000).rom();
|
||||
map(0x080000, 0x0807ff).ram().share("video_ram");
|
||||
// map(0x100000, 0x10ffff) // some memory mapped i/o???
|
||||
// map(0x110000, 0x11ffff) // some memory mapped i/o???
|
||||
@ -251,10 +253,11 @@ INPUT_PORTS_END
|
||||
|
||||
void cfx9850_state::cfx9850_palette(palette_device &palette) const
|
||||
{
|
||||
palette.set_pen_color(0, 0xff, 0xff, 0xff);
|
||||
palette.set_pen_color(1, 0x00, 0x00, 0xff);
|
||||
palette.set_pen_color(2, 0x00, 0xff, 0x00);
|
||||
palette.set_pen_color(3, 0xff, 0x00, 0x00);
|
||||
// Referenced from screenshots in "fx-9750G PLUS User's Guide"
|
||||
palette.set_pen_color(0, 0xbb, 0xdd, 0xaa);
|
||||
palette.set_pen_color(1, 0x22, 0x55, 0xaa);
|
||||
palette.set_pen_color(2, 0x22, 0xaa, 0x55);
|
||||
palette.set_pen_color(3, 0xff, 0x55, 0x22);
|
||||
}
|
||||
|
||||
|
||||
@ -308,6 +311,38 @@ void cfx9850_state::cfx9850(machine_config &config)
|
||||
PALETTE(config, "palette", FUNC(cfx9850_state::cfx9850_palette), 4);
|
||||
}
|
||||
|
||||
|
||||
class cfx9850gb_state : public cfx9850_state
|
||||
{
|
||||
public:
|
||||
cfx9850gb_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: cfx9850_state(mconfig, type, tag)
|
||||
{ }
|
||||
|
||||
void cfx9850gb(machine_config &config);
|
||||
void cfx9850gb_mem(address_map &map);
|
||||
};
|
||||
|
||||
void cfx9850gb_state::cfx9850gb_mem(address_map &map)
|
||||
{
|
||||
map(0x000000, 0x007fff).mirror(0x008000).rom();
|
||||
map(0x080000, 0x0807ff).ram().share("video_ram");
|
||||
// map(0x100000, 0x10ffff) // some memory mapped i/o???
|
||||
// map(0x110000, 0x11ffff) // some memory mapped i/o???
|
||||
map(0x200000, 0x2fffff).rom().region("bios", 0);
|
||||
map(0x400000, 0x40f7ff).ram();
|
||||
map(0x40f800, 0x40ffff).ram().share("display_ram");
|
||||
map(0x410000, 0x41ffff).ram();
|
||||
// map(0xe10000, 0xe1ffff) // some memory mapped i/o???
|
||||
}
|
||||
|
||||
void cfx9850gb_state::cfx9850gb(machine_config &config)
|
||||
{
|
||||
cfx9850(config);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &cfx9850gb_state::cfx9850gb_mem);
|
||||
}
|
||||
|
||||
|
||||
#define ROM_MAINCPU \
|
||||
ROM_REGION(0x8000, "maincpu", 0) \
|
||||
ROM_LOAD("hcd62121.bin", 0x0000, 0x8000, CRC(e72075f8) SHA1(f50d176e1c225dab69abfc67702c9dfb296b6a78))
|
||||
@ -336,5 +371,5 @@ ROM_END
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
COMP(1996, cfx9850, 0, 0, cfx9850, cfx9850, cfx9850_state, empty_init, "Casio", "CFX-9850G", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
|
||||
COMP(1996, cfx9850gb, cfx9850, 0, cfx9850, cfx9850, cfx9850_state, empty_init, "Casio", "CFX-9850GB Plus", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
|
||||
COMP(1996, cfx9850, 0, 0, cfx9850, cfx9850, cfx9850_state, empty_init, "Casio", "CFX-9850G", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
|
||||
COMP(1996, cfx9850gb, cfx9850, 0, cfx9850gb, cfx9850, cfx9850gb_state, empty_init, "Casio", "CFX-9850GB Plus", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
|
||||
|
Loading…
Reference in New Issue
Block a user