mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
Casio CTK-551 [Daivn Acker]
* New machine marked as NOT_WORKING ---------------------------------- Casio CTK-551 [Devin Acker]
This commit is contained in:
parent
a15538b4ae
commit
8962638b77
@ -700,6 +700,8 @@ if CPUS["H8"] then
|
||||
MAME_DIR .. "src/devices/cpu/h8/h8_sci.h",
|
||||
MAME_DIR .. "src/devices/cpu/h8/h8_watchdog.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/h8/h8_watchdog.h",
|
||||
MAME_DIR .. "src/devices/cpu/h8/gt913.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/h8/gt913.h",
|
||||
}
|
||||
|
||||
dependency {
|
||||
@ -707,6 +709,7 @@ if CPUS["H8"] then
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/h8h.cpp", GEN_DIR .. "emu/cpu/h8/h8h.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/h8s2000.cpp", GEN_DIR .. "emu/cpu/h8/h8s2000.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/h8s2600.cpp", GEN_DIR .. "emu/cpu/h8/h8s2600.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/gt913.cpp", GEN_DIR .. "emu/cpu/h8/gt913.hxx" },
|
||||
}
|
||||
|
||||
custombuildtask {
|
||||
@ -714,19 +717,22 @@ if CPUS["H8"] then
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8h.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8-300H source file...", PYTHON .. " $(1) $(<) s h $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8s2000.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8S/2000 source file...", PYTHON .. " $(1) $(<) s s20 $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8s2600.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8S/2600 source file...", PYTHON .. " $(1) $(<) s s26 $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/h8/gt913.lst" , GEN_DIR .. "emu/cpu/h8/gt913.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating GT913 source file...", PYTHON .. " $(1) $(<) s g $(@)" }},
|
||||
}
|
||||
end
|
||||
|
||||
if opt_tool(CPUS, "H8") then
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8d.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8-300 disassembler source file...", PYTHON .. " $(1) $(<) d o $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8hd.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8-300H disassembler source file...", PYTHON .. " $(1) $(<) d h $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8s2000d.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8S/2000 disassembler source file...", PYTHON .. " $(1) $(<) d s20 $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8s2600d.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8S/2600 disassembler source file...", PYTHON .. " $(1) $(<) d s26 $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8d.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8-300 disassembler source file...", PYTHON .. " $(1) $(<) d o $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8hd.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8-300H disassembler source file...", PYTHON .. " $(1) $(<) d h $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8s2000d.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8S/2000 disassembler source file...", PYTHON .. " $(1) $(<) d s20 $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/h8.lst" , GEN_DIR .. "emu/cpu/h8/h8s2600d.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating H8S/2600 disassembler source file...", PYTHON .. " $(1) $(<) d s26 $(@)" }})
|
||||
table.insert(disasm_custombuildtask, { MAME_DIR .. "src/devices/cpu/h8/gt913.lst" , GEN_DIR .. "emu/cpu/h8/gt913d.hxx", { MAME_DIR .. "src/devices/cpu/h8/h8make.py" }, {"@echo Generating GT913 disassembler source file...", PYTHON .. " $(1) $(<) d g $(@)" }})
|
||||
|
||||
table.insert(disasm_dependency, { MAME_DIR .. "src/devices/cpu/h8/h8d.cpp", GEN_DIR .. "emu/cpu/h8/h8d.hxx" })
|
||||
table.insert(disasm_dependency, { MAME_DIR .. "src/devices/cpu/h8/h8hd.cpp", GEN_DIR .. "emu/cpu/h8/h8hd.hxx" })
|
||||
table.insert(disasm_dependency, { MAME_DIR .. "src/devices/cpu/h8/h8s2000d.cpp", GEN_DIR .. "emu/cpu/h8/h8s2000d.hxx" })
|
||||
table.insert(disasm_dependency, { MAME_DIR .. "src/devices/cpu/h8/h8s2600d.cpp", GEN_DIR .. "emu/cpu/h8/h8s2600d.hxx" })
|
||||
table.insert(disasm_dependency, { MAME_DIR .. "src/devices/cpu/h8/gt913d.cpp", GEN_DIR .. "emu/cpu/h8/gt913d.hxx" })
|
||||
|
||||
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/h8d.cpp")
|
||||
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/h8d.h")
|
||||
@ -736,6 +742,8 @@ if opt_tool(CPUS, "H8") then
|
||||
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/h8s2000d.h")
|
||||
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/h8s2600d.cpp")
|
||||
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/h8s2600d.h")
|
||||
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/gt913d.cpp")
|
||||
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/gt913d.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
|
@ -1391,6 +1391,22 @@ if (MACHINES["FGA002"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/gt913.h,MACHINES["GT913"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["GT913"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/gt913_io.cpp",
|
||||
MAME_DIR .. "src/devices/machine/gt913_io.h",
|
||||
MAME_DIR .. "src/devices/machine/gt913_kbd.cpp",
|
||||
MAME_DIR .. "src/devices/machine/gt913_kbd.h",
|
||||
MAME_DIR .. "src/devices/machine/gt913_snd.cpp",
|
||||
MAME_DIR .. "src/devices/machine/gt913_snd.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/hd63450.h,MACHINES["HD63450"] = true
|
||||
|
@ -530,6 +530,7 @@ MACHINES["ER2055"] = true
|
||||
MACHINES["EXORTERM"] = true
|
||||
MACHINES["F3853"] = true
|
||||
MACHINES["F4702"] = true
|
||||
MACHINES["GT913"] = true
|
||||
MACHINES["HD63450"] = true
|
||||
MACHINES["HD64610"] = true
|
||||
MACHINES["HP_DC100_TAPE"] = true
|
||||
@ -2024,6 +2025,7 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/fp6000.cpp",
|
||||
MAME_DIR .. "src/mame/machine/fp6000_kbd.cpp",
|
||||
MAME_DIR .. "src/mame/machine/fp6000_kbd.h",
|
||||
MAME_DIR .. "src/mame/drivers/ctk551.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/ht6000.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/pb1000.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/pv1000.cpp",
|
||||
|
170
src/devices/cpu/h8/gt913.cpp
Normal file
170
src/devices/cpu/h8/gt913.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/***************************************************************************
|
||||
Casio GT913
|
||||
|
||||
This chip powers several late-90s/early-2000s Casio keyboards.
|
||||
It's based on the H8/300 instruction set, but with different encoding
|
||||
for many opcodes, as well as:
|
||||
|
||||
- Dedicated bank switching instructions (20-bit external address bus)
|
||||
- Two timers, three 8-bit ports, two 8-bit ADCs
|
||||
- Keyboard controller w/ key velocity detection
|
||||
- MIDI UART
|
||||
- 24-voice PCM sound (currently not emulated / fully understood)
|
||||
|
||||
Earlier and later Casio keyboard models contain "uPD912" and "uPD914" chips,
|
||||
which are presumably similar.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "gt913.h"
|
||||
#include "gt913d.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(GT913, gt913_device, "gt913", "Casio GT913F")
|
||||
|
||||
gt913_device::gt913_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
h8_device(mconfig, GT913, tag, owner, clock, address_map_constructor(FUNC(gt913_device::map), this)),
|
||||
m_rom(*this, DEVICE_SELF),
|
||||
m_bank(*this, "bank"),
|
||||
m_intc(*this, "intc"),
|
||||
m_sound(*this, "gt_sound"),
|
||||
m_kbd(*this, "kbd"),
|
||||
m_io_hle(*this, "io_hle"),
|
||||
m_sci(*this, "sci"),
|
||||
m_port(*this, "port%u", 1)
|
||||
{
|
||||
has_hc = false;
|
||||
}
|
||||
|
||||
std::unique_ptr<util::disasm_interface> gt913_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<gt913_disassembler>();
|
||||
}
|
||||
|
||||
void gt913_device::map(address_map &map)
|
||||
{
|
||||
// map.unmap_value_high();
|
||||
|
||||
map(0x0000, 0x7fff).rom();
|
||||
map(0x8000, 0xbfff).bankr("bank");
|
||||
map(0xfac0, 0xffbf).ram(); // CTK-551 zeroes out this range at $0418
|
||||
|
||||
/* ffc0-ffcb: sound */
|
||||
map(0xffc0, 0xffc5).rw(m_sound, FUNC(gt913_sound_hle_device::data_r), FUNC(gt913_sound_hle_device::data_w));
|
||||
map(0xffc6, 0xffc7).w(m_sound, FUNC(gt913_sound_hle_device::command_w));
|
||||
map(0xffca, 0xffcb).r(m_sound, FUNC(gt913_sound_hle_device::status_r));
|
||||
|
||||
/* ffd0-ffd5: key controller */
|
||||
map(0xffd0, 0xffd1).r(m_kbd, FUNC(gt913_kbd_hle_device::read));
|
||||
map(0xffd2, 0xffd3).rw(m_kbd, FUNC(gt913_kbd_hle_device::status_r), FUNC(gt913_kbd_hle_device::status_w));
|
||||
|
||||
/* ffd8-ffdf: timers */
|
||||
map(0xffd8, 0xffd9).rw(m_io_hle, FUNC(gt913_io_hle_device::timer_control_r), FUNC(gt913_io_hle_device::timer_control_w));
|
||||
map(0xffdc, 0xffdd).w(m_io_hle, FUNC(gt913_io_hle_device::timer_rate0_w));
|
||||
map(0xffdf, 0xffdf).w(m_io_hle, FUNC(gt913_io_hle_device::timer_rate1_w));
|
||||
|
||||
/* ffe0-ffe3: serial */
|
||||
map(0xffe0, 0xffe0).w(FUNC(gt913_device::uart_rate_w));
|
||||
map(0xffe1, 0xffe1).w(m_sci, FUNC(h8_sci_device::tdr_w));
|
||||
map(0xffe2, 0xffe2).rw(FUNC(gt913_device::uart_control_r), FUNC(gt913_device::uart_control_w));
|
||||
map(0xffe3, 0xffe3).r(m_sci, FUNC(h8_sci_device::rdr_r));
|
||||
|
||||
/* ffe9-ffea: ADC */
|
||||
map(0xffe9, 0xffe9).rw(m_io_hle, FUNC(gt913_io_hle_device::adc_control_r), FUNC(gt913_io_hle_device::adc_control_w));
|
||||
map(0xffea, 0xffea).r(m_io_hle, FUNC(gt913_io_hle_device::adc_data_r));
|
||||
|
||||
/* fff0-fff5: I/O ports */
|
||||
map(0xfff0, 0xfff0).rw(m_port[0], FUNC(h8_port_device::ddr_r), FUNC(h8_port_device::ddr_w));
|
||||
map(0xfff1, 0xfff1).rw(m_port[1], FUNC(h8_port_device::ddr_r), FUNC(h8_port_device::ddr_w));
|
||||
map(0xfff2, 0xfff2).rw(m_port[0], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
|
||||
map(0xfff3, 0xfff3).rw(m_port[1], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
|
||||
// map(0xfff4, 0xfff4).nopw(); probably not port 3 DDR - ctk551 writes 0x00 but uses port 3 for output only
|
||||
map(0xfff5, 0xfff5).rw(m_port[2], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
|
||||
}
|
||||
|
||||
void gt913_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
GT913_INTC(config, "intc");
|
||||
|
||||
GT913_SOUND_HLE(config, m_sound, 0);
|
||||
GT913_KBD_HLE(config, m_kbd, "intc", 5);
|
||||
GT913_IO_HLE(config, m_io_hle, "intc", 6, 7);
|
||||
H8_SCI(config, m_sci, "intc", 8, 9, 10, 0);
|
||||
|
||||
H8_PORT(config, m_port[0], h8_device::PORT_1, 0xff, 0x00);
|
||||
H8_PORT(config, m_port[1], h8_device::PORT_2, 0xff, 0x00);
|
||||
H8_PORT(config, m_port[2], h8_device::PORT_3, 0xff, 0x00);
|
||||
}
|
||||
|
||||
|
||||
void gt913_device::uart_rate_w(uint8_t data)
|
||||
{
|
||||
m_sci->brr_w(data >> 1);
|
||||
}
|
||||
|
||||
void gt913_device::uart_control_w(uint8_t data)
|
||||
{
|
||||
/*
|
||||
upper 4 bits seem to correspond to the upper bits of SSR (Tx/Rx/error status)
|
||||
lower 4 bits seem to correspond to the upper bits of SCR (Tx/Rx IRQ enable, Tx/Rx enable(?))
|
||||
*/
|
||||
m_sci->ssr_w(data & 0xf0);
|
||||
m_sci->scr_w((data & 0x0f) << 4);
|
||||
}
|
||||
|
||||
uint8_t gt913_device::uart_control_r()
|
||||
{
|
||||
return (m_sci->ssr_r() & 0xf0) | (m_sci->scr_r() >> 4);
|
||||
}
|
||||
|
||||
void gt913_device::irq_setup()
|
||||
{
|
||||
CCR |= F_H;
|
||||
}
|
||||
|
||||
void gt913_device::update_irq_filter()
|
||||
{
|
||||
if (CCR & F_H)
|
||||
m_intc->set_filter(2, -1);
|
||||
else
|
||||
m_intc->set_filter(0, -1);
|
||||
}
|
||||
|
||||
void gt913_device::interrupt_taken()
|
||||
{
|
||||
standard_irq_callback(m_intc->interrupt_taken(taken_irq_vector));
|
||||
}
|
||||
|
||||
void gt913_device::internal_update(uint64_t current_time)
|
||||
{
|
||||
uint64_t event_time = 0;
|
||||
|
||||
add_event(event_time, m_sci->internal_update(current_time));
|
||||
|
||||
recompute_bcount(event_time);
|
||||
}
|
||||
|
||||
void gt913_device::execute_set_input(int inputnum, int state)
|
||||
{
|
||||
m_intc->set_input(inputnum, state);
|
||||
}
|
||||
|
||||
void gt913_device::device_start()
|
||||
{
|
||||
h8_device::device_start();
|
||||
|
||||
m_bank->configure_entries(0, m_rom->bytes() >> 12, m_rom->base(), 1 << 12);
|
||||
|
||||
save_item(NAME(m_banknum));
|
||||
}
|
||||
|
||||
void gt913_device::device_reset()
|
||||
{
|
||||
h8_device::device_reset();
|
||||
|
||||
m_banknum = 0;
|
||||
}
|
||||
|
||||
#include "cpu/h8/gt913.hxx"
|
82
src/devices/cpu/h8/gt913.h
Normal file
82
src/devices/cpu/h8/gt913.h
Normal file
@ -0,0 +1,82 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/***************************************************************************
|
||||
|
||||
gt913.h
|
||||
|
||||
Casio GT913
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_H8_GT913_H
|
||||
#define MAME_CPU_H8_GT913_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h8.h"
|
||||
#include "h8_intc.h"
|
||||
#include "h8_port.h"
|
||||
#include "h8_sci.h"
|
||||
#include "machine/gt913_io.h"
|
||||
#include "machine/gt913_kbd.h"
|
||||
#include "machine/gt913_snd.h"
|
||||
|
||||
class gt913_device : public h8_device {
|
||||
public:
|
||||
gt913_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
void uart_rate_w(uint8_t data);
|
||||
void uart_control_w(uint8_t data);
|
||||
uint8_t uart_control_r();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void update_irq_filter() override;
|
||||
virtual void interrupt_taken() override;
|
||||
virtual void internal_update(uint64_t current_time) override;
|
||||
virtual void irq_setup() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
void map(address_map &map);
|
||||
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual void do_exec_full() override;
|
||||
virtual void do_exec_partial() override;
|
||||
|
||||
#define O(o) void o ## _full(); void o ## _partial()
|
||||
O(ldbank_imm2l_bankl); O(ldbank_imm4l_bankh); O(ldbank_r8l_bankl); O(ldbank_r8l_bankh);
|
||||
|
||||
O(dispatch_6600); O(dispatch_7000); O(dispatch_7200);
|
||||
#undef O
|
||||
|
||||
required_memory_region m_rom;
|
||||
|
||||
required_memory_bank m_bank;
|
||||
uint16_t m_banknum;
|
||||
|
||||
required_device<gt913_intc_device> m_intc;
|
||||
|
||||
/* sound */
|
||||
required_device<gt913_sound_hle_device> m_sound;
|
||||
|
||||
/* key controller */
|
||||
required_device<gt913_kbd_hle_device> m_kbd;
|
||||
|
||||
/* misc. I/O (timers, ADCs) */
|
||||
required_device<gt913_io_hle_device> m_io_hle;
|
||||
|
||||
/* serial port */
|
||||
required_device<h8_sci_device> m_sci;
|
||||
|
||||
/* 3x 8-bit I/O ports */
|
||||
required_device_array<h8_port_device, 3> m_port;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(GT913, gt913_device)
|
||||
|
||||
#endif // MAME_CPU_H8_GT913_H
|
140
src/devices/cpu/h8/gt913.lst
Normal file
140
src/devices/cpu/h8/gt913.lst
Normal file
@ -0,0 +1,140 @@
|
||||
# license:BSD-3-Clause
|
||||
# copyright-holders:Olivier Galibert, Devin Acker
|
||||
|
||||
10000 reset
|
||||
10001 irq
|
||||
|
||||
0000 ffff 0 nop - -
|
||||
0100 ffff 0 sleep - -
|
||||
0240 fff0 0 stc ccr r8l
|
||||
0340 fff0 0 ldc r8l ccr
|
||||
|
||||
0380 fff0 0 ldbank r8l bankh g
|
||||
TMP1 = r8_r(IR[0]);
|
||||
m_banknum = (TMP1 << 2) | (m_banknum & 0x3);
|
||||
m_bank->set_entry(m_banknum);
|
||||
prefetch();
|
||||
|
||||
03c0 fff0 0 ldbank r8l bankl g
|
||||
TMP1 = r8_r(IR[0]);
|
||||
m_banknum = (m_banknum & 0xfffc) | (TMP1 & 0x3);
|
||||
m_bank->set_entry(m_banknum);
|
||||
prefetch();
|
||||
|
||||
0400 ff00 0 orc imm8 ccr
|
||||
0500 ff00 0 xorc imm8 ccr
|
||||
0600 ff00 0 andc imm8 ccr
|
||||
|
||||
0780 fff0 0 ldbank imm4l bankh g
|
||||
m_banknum = ((IR[0] & 0xf) << 2) | (m_banknum & 0x3);
|
||||
m_bank->set_entry(m_banknum);
|
||||
prefetch();
|
||||
|
||||
07c0 fff0 0 ldbank imm2l bankl g
|
||||
m_banknum = (m_banknum & 0xfffc) | (IR[0] & 0x3);
|
||||
m_bank->set_entry(m_banknum);
|
||||
prefetch();
|
||||
|
||||
0800 ff00 0 add.b r8h r8l
|
||||
0900 ff00 0 add.w r16h r16l
|
||||
0a00 fff0 0 inc.b one r8l
|
||||
0b00 fff8 0 adds.l one r16l
|
||||
0b80 fff8 0 adds.l two r16l
|
||||
0c00 ff00 0 mov.b r8h r8l
|
||||
0d00 ff00 0 mov.w r16h r16l
|
||||
0e00 ff00 0 addx.b r8h r8l
|
||||
0f00 ff00 0 mulxu.b r8h r16l
|
||||
|
||||
1000 fff0 0 shll.b r8l -
|
||||
1080 fff0 0 shal.b r8l -
|
||||
1100 fff0 0 shlr.b r8l -
|
||||
1180 fff0 0 shar.b r8l -
|
||||
1200 fff0 0 rotxl.b r8l -
|
||||
1280 fff0 0 rotl.b r8l -
|
||||
1300 fff0 0 rotxr.b r8l -
|
||||
1380 fff0 0 rotr.b r8l -
|
||||
1400 ff00 0 or.b r8h r8l
|
||||
1500 ff00 0 xor.b r8h r8l
|
||||
1600 ff00 0 and.b r8h r8l
|
||||
1700 fff0 0 not.b r8l -
|
||||
1780 fff0 0 neg.b r8l -
|
||||
1800 ff00 0 sub.b r8h r8l
|
||||
1900 ff00 0 sub.w r16h r16l
|
||||
1a00 fff0 0 dec.b one r8l
|
||||
# yes, this is the correct order for subs.l - one and two are swapped for some reason
|
||||
1b00 fff8 0 subs.l two r16l
|
||||
1b80 fff8 0 subs.l one r16l
|
||||
1c00 ff00 0 cmp.b r8h r8l
|
||||
1d00 ff00 0 cmp.w r16h r16l
|
||||
1e00 ff00 0 subx.b r8h r8l
|
||||
1f00 ff00 0 divxu.b r8h r16l
|
||||
|
||||
2000 f000 0 mov.b abs8 r8u
|
||||
3000 f000 0 mov.b r8u abs8
|
||||
|
||||
4000 ff00 0 bt rel8 -
|
||||
4100 ff00 0 bf rel8 -
|
||||
4200 ff00 0 bhi rel8 -
|
||||
4300 ff00 0 bls rel8 -
|
||||
4400 ff00 0 bcc rel8 -
|
||||
4500 ff00 0 bcs rel8 -
|
||||
4600 ff00 0 bne rel8 -
|
||||
4700 ff00 0 beq rel8 -
|
||||
4800 ff00 0 bvc rel8 -
|
||||
4900 ff00 0 bvs rel8 -
|
||||
4a00 ff00 0 bpl rel8 -
|
||||
4b00 ff00 0 bmi rel8 -
|
||||
4c00 ff00 0 bge rel8 -
|
||||
4d00 ff00 0 blt rel8 -
|
||||
4e00 ff00 0 bgt rel8 -
|
||||
4f00 ff00 0 ble rel8 -
|
||||
|
||||
5000 ff80 0 bset imm3 r8l
|
||||
5100 ff00 0 bset r8h r8l
|
||||
5200 ff80 0 bclr imm3 r8l
|
||||
5300 ff00 0 bclr r8h r8l
|
||||
5400 ff80 0 bnot imm3 r8l
|
||||
5500 ff00 0 bnot r8h r8l
|
||||
5600 ff80 0 btst imm3 r8l
|
||||
5700 ff00 0 btst r8h r8l
|
||||
5800 ffff 0 rts - -
|
||||
5980 ffff 0 rte - -
|
||||
5a00 ff8f 0 jmp r16h -
|
||||
5a80 ffff 0 jmp abs16e -
|
||||
5b00 ff00 0 jmp abs8i -
|
||||
5c00 ff8f 0 jsr r16h -
|
||||
5c80 ffff 0 jsr abs16e -
|
||||
5e00 ff00 0 bsr rel8 -
|
||||
5f00 fff0 0 mov.w imm16 r16l
|
||||
|
||||
66000000 ff00ff8f 0 btst imm3 abs8
|
||||
|
||||
6800 ff80 0 mov.b r16ih r8l
|
||||
6900 ff88 0 mov.w r16ih r16l
|
||||
6a00 ff80 0 mov.b r16ph r8l
|
||||
6b00 ff88 0 mov.w r16ph r16l
|
||||
6c00 fff0 0 mov.b abs16 r8l
|
||||
6d00 fff0 0 mov.w abs16 r16l
|
||||
6e00 ff80 0 mov.b r16d16h r8l
|
||||
6f00 ff80 0 mov.w r16d16h r16l
|
||||
|
||||
70000000 ff00ff8f 0 bset imm3 abs8
|
||||
72000000 ff00ff8f 0 bclr imm3 abs8
|
||||
|
||||
7800 ff80 0 mov.b r8l r16ih
|
||||
7900 ff88 0 mov.w r16l r16ih
|
||||
7a00 ff80 0 mov.b r8l pr16h
|
||||
7b00 ff88 0 mov.w r16l pr16h
|
||||
7c00 fff0 0 mov.b r8l abs16
|
||||
7d00 fff0 0 mov.w r16l abs16
|
||||
7e00 ff80 0 mov.b r8l r16d16h
|
||||
7f00 ff80 0 mov.w r16l r16d16h
|
||||
|
||||
8000 f000 0 add.b imm8 r8u
|
||||
9000 f000 0 addx.b imm8 r8u
|
||||
a000 f000 0 cmp.b imm8 r8u
|
||||
b000 f000 0 subx.b imm8 r8u
|
||||
c000 f000 0 or.b imm8 r8u
|
||||
d000 f000 0 xor.b imm8 r8u
|
||||
e000 f000 0 and.b imm8 r8u
|
||||
f000 f000 0 mov.b imm8 r8u
|
17
src/devices/cpu/h8/gt913d.cpp
Normal file
17
src/devices/cpu/h8/gt913d.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/***************************************************************************
|
||||
|
||||
gt913d.cpp
|
||||
|
||||
GT913 base cpu emulation, disassembler
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "gt913d.h"
|
||||
#include "cpu/h8/gt913d.hxx"
|
||||
|
||||
gt913_disassembler::gt913_disassembler() : h8_disassembler(disasm_entries, false)
|
||||
{
|
||||
}
|
28
src/devices/cpu/h8/gt913d.h
Normal file
28
src/devices/cpu/h8/gt913d.h
Normal file
@ -0,0 +1,28 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/***************************************************************************
|
||||
|
||||
gt913d.h
|
||||
|
||||
GT913 base cpu emulation, disassembler
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_H8_GT913D_H
|
||||
#define MAME_CPU_H8_GT913D_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h8d.h"
|
||||
|
||||
class gt913_disassembler : public h8_disassembler
|
||||
{
|
||||
public:
|
||||
gt913_disassembler();
|
||||
virtual ~gt913_disassembler() = default;
|
||||
|
||||
protected:
|
||||
static const disasm_entry disasm_entries[];
|
||||
};
|
||||
|
||||
#endif
|
@ -28,6 +28,7 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char
|
||||
has_exr = false;
|
||||
mac_saturating = false;
|
||||
has_trace = false;
|
||||
has_hc = true;
|
||||
}
|
||||
|
||||
void h8_device::device_config_complete()
|
||||
@ -318,7 +319,7 @@ void h8_device::state_string_export(const device_state_entry &entry, std::string
|
||||
(CCR & F_Z) ? 'Z' : '-',
|
||||
(CCR & F_V) ? 'V' : '-',
|
||||
(CCR & F_C) ? 'C' : '-');
|
||||
else
|
||||
else if(has_hc)
|
||||
str = string_format("%c%c%c%c%c%c%c%c",
|
||||
(CCR & F_I) ? 'I' : '-',
|
||||
(CCR & F_UI) ? 'u' : '-',
|
||||
@ -328,6 +329,16 @@ void h8_device::state_string_export(const device_state_entry &entry, std::string
|
||||
(CCR & F_Z) ? 'Z' : '-',
|
||||
(CCR & F_V) ? 'V' : '-',
|
||||
(CCR & F_C) ? 'C' : '-');
|
||||
else
|
||||
str = string_format("%c%c%c%c%c%c%c%c",
|
||||
(CCR & F_I) ? '?' : '-',
|
||||
(CCR & F_UI) ? 'u' : '-',
|
||||
(CCR & F_H) ? 'I' : '-',
|
||||
(CCR & F_U) ? 'U' : '-',
|
||||
(CCR & F_N) ? 'N' : '-',
|
||||
(CCR & F_Z) ? 'Z' : '-',
|
||||
(CCR & F_V) ? 'V' : '-',
|
||||
(CCR & F_C) ? 'C' : '-');
|
||||
break;
|
||||
case H8_R0:
|
||||
case H8_R1:
|
||||
@ -449,9 +460,13 @@ int h8_device::trapa_setup()
|
||||
uint8_t h8_device::do_addx8(uint8_t v1, uint8_t v2)
|
||||
{
|
||||
uint16_t res = v1 + v2 + (CCR & F_C ? 1 : 0);
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xf) + (v2 & 0xf) + (CCR & F_C ? 1 : 0)) & 0x10)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if(((v1 & 0xf) + (v2 & 0xf) + (CCR & F_C ? 1 : 0)) & 0x10)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint8_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int8_t(res) < 0)
|
||||
@ -467,9 +482,13 @@ uint8_t h8_device::do_addx8(uint8_t v1, uint8_t v2)
|
||||
uint8_t h8_device::do_subx8(uint8_t v1, uint8_t v2)
|
||||
{
|
||||
uint16_t res = v1 - v2 - (CCR & F_C ? 1 : 0);
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xf) - (v2 & 0xf) - (CCR & F_C ? 1 : 0)) & 0x10)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if (((v1 & 0xf) - (v2 & 0xf) - (CCR & F_C ? 1 : 0)) & 0x10)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint8_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int8_t(res) < 0)
|
||||
@ -524,9 +543,13 @@ uint32_t h8_device::do_inc32(uint32_t v1, uint32_t v2)
|
||||
uint8_t h8_device::do_add8(uint8_t v1, uint8_t v2)
|
||||
{
|
||||
uint16_t res = v1 + v2;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xf) + (v2 & 0xf)) & 0x10)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if (((v1 & 0xf) + (v2 & 0xf)) & 0x10)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint8_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int8_t(res) < 0)
|
||||
@ -542,9 +565,13 @@ uint8_t h8_device::do_add8(uint8_t v1, uint8_t v2)
|
||||
uint16_t h8_device::do_add16(uint16_t v1, uint16_t v2)
|
||||
{
|
||||
uint32_t res = v1 + v2;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xfff) + (v2 & 0xffff)) & 0x1000)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if (((v1 & 0xfff) + (v2 & 0xffff)) & 0x1000)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint16_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int16_t(res) < 0)
|
||||
@ -560,9 +587,13 @@ uint16_t h8_device::do_add16(uint16_t v1, uint16_t v2)
|
||||
uint32_t h8_device::do_add32(uint32_t v1, uint32_t v2)
|
||||
{
|
||||
uint64_t res = uint64_t(v1) + uint64_t(v2);
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if (((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint32_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int32_t(res) < 0)
|
||||
@ -616,9 +647,13 @@ uint32_t h8_device::do_dec32(uint32_t v1, uint32_t v2)
|
||||
uint8_t h8_device::do_sub8(uint8_t v1, uint8_t v2)
|
||||
{
|
||||
uint16_t res = v1 - v2;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xf) - (v2 & 0xf)) & 0x10)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if (((v1 & 0xf) - (v2 & 0xf)) & 0x10)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint8_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int8_t(res) < 0)
|
||||
@ -634,9 +669,13 @@ uint8_t h8_device::do_sub8(uint8_t v1, uint8_t v2)
|
||||
uint16_t h8_device::do_sub16(uint16_t v1, uint16_t v2)
|
||||
{
|
||||
uint32_t res = v1 - v2;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xfff) - (v2 & 0xffff)) & 0x1000)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if (((v1 & 0xfff) - (v2 & 0xffff)) & 0x1000)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint16_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int16_t(res) < 0)
|
||||
@ -652,9 +691,13 @@ uint16_t h8_device::do_sub16(uint16_t v1, uint16_t v2)
|
||||
uint32_t h8_device::do_sub32(uint32_t v1, uint32_t v2)
|
||||
{
|
||||
uint64_t res = uint64_t(v1) - uint64_t(v2);
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
||||
if(((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000)
|
||||
CCR |= F_H;
|
||||
CCR &= ~(F_N|F_V|F_Z|F_C);
|
||||
if (has_hc)
|
||||
{
|
||||
CCR &= ~F_H;
|
||||
if (((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000)
|
||||
CCR |= F_H;
|
||||
}
|
||||
if(!uint32_t(res))
|
||||
CCR |= F_Z;
|
||||
else if(int32_t(res) < 0)
|
||||
|
@ -135,6 +135,7 @@ protected:
|
||||
uint32_t TMPR; /* For debugger ER register import */
|
||||
|
||||
bool has_exr, has_trace, supports_advanced, mode_advanced, mode_a20, mac_saturating;
|
||||
bool has_hc; // GT913's CCR bit 5 is I, not H
|
||||
|
||||
int inst_state, inst_substate, requested_state;
|
||||
int icount, bcount, count_before_instruction_step;
|
||||
@ -334,7 +335,7 @@ protected:
|
||||
O(divxu_b_r8h_r16l);
|
||||
O(eepmov_b);
|
||||
O(inc_b_one_r8l);
|
||||
O(jmp_abs8i); O(jmp_abs16e);
|
||||
O(jmp_abs8i); O(jmp_abs16e); O(jmp_r16h);
|
||||
O(jsr_abs8i); O(jsr_abs16e); O(jsr_r16h);
|
||||
O(ldc_imm8_ccr); O(ldc_r8l_ccr);
|
||||
O(mov_b_abs16_r8l); O(mov_b_abs8_r8u); O(mov_b_imm8_r8u); O(mov_b_r8h_r8l); O(mov_b_r8l_abs16); O(mov_b_r8u_abs8); O(mov_b_r16ih_r8l); O(mov_b_r8l_r16ih); O(mov_b_r16d16h_r8l); O(mov_b_r8l_r16d16h); O(mov_b_r16ph_r8l); O(mov_b_r8l_pr16h);
|
||||
|
@ -100,7 +100,7 @@ macro jsr32 %opc %spreg
|
||||
prefetch_done();
|
||||
|
||||
10000 reset
|
||||
CCR |= F_I;
|
||||
CCR |= (has_hc ? F_I : F_H);
|
||||
EXR = EXR_I | EXR_NC;
|
||||
if(mode_advanced) {
|
||||
IR[0] = read16i(0);
|
||||
@ -1007,7 +1007,7 @@ macro jsr32 %opc %spreg
|
||||
TMP1 = r8_r(IR[0]);
|
||||
TMP2 = 0;
|
||||
if(CCR & F_C) {
|
||||
if(CCR & F_H) {
|
||||
if(has_hc && (CCR & F_H)) {
|
||||
if((TMP1 & 0xf0) <= 0x30 && (TMP1 & 0x0f) <= 3)
|
||||
TMP2 = 0x66;
|
||||
} else {
|
||||
@ -1015,7 +1015,7 @@ macro jsr32 %opc %spreg
|
||||
TMP2 = (TMP1 & 0x0f) <= 9 ? 0x60 : 0x66;
|
||||
}
|
||||
} else {
|
||||
if(CCR & F_H) {
|
||||
if(has_hc && (CCR & F_H)) {
|
||||
if((TMP1 & 0x0f) <= 3)
|
||||
TMP2 = (TMP1 & 0xf0) <= 0x90 ? 0x06 : 0x66;
|
||||
} else {
|
||||
@ -1378,7 +1378,7 @@ macro jsr32 %opc %spreg
|
||||
TMP1 = r8_r(IR[0]);
|
||||
TMP2 = 0;
|
||||
if(CCR & F_C) {
|
||||
if(CCR & F_H) {
|
||||
if(has_hc && (CCR & F_H)) {
|
||||
if((TMP1 & 0xf0) >= 0x60 && (TMP1 & 0x0f) >= 6)
|
||||
TMP2 = 0x9a;
|
||||
} else {
|
||||
@ -1386,7 +1386,7 @@ macro jsr32 %opc %spreg
|
||||
TMP2 = 0xa0;
|
||||
}
|
||||
} else {
|
||||
if(CCR & F_H) {
|
||||
if(has_hc && (CCR & F_H)) {
|
||||
if((TMP1 & 0xf0) <= 0x80 && (TMP1 & 0x0f) >= 6)
|
||||
TMP2 = 0xfa;
|
||||
}
|
||||
@ -1647,6 +1647,11 @@ macro jsr32 %opc %spreg
|
||||
58f0 ffff 0 ble rel16 - h
|
||||
bxx_16 (CCR & F_Z) || (CCR & (F_N|F_V)) == F_N || (CCR & (F_N|F_V)) == F_V
|
||||
|
||||
5900 ff8f 0 jmp r16h - o
|
||||
fetch();
|
||||
PC = r16_r(IR[0] >> 4);
|
||||
prefetch();
|
||||
|
||||
5900 ff8f 0 jmp r32h - h
|
||||
fetch();
|
||||
PC = r32_r(IR[0] >> 4);
|
||||
|
@ -3,9 +3,10 @@
|
||||
#include "emu.h"
|
||||
#include "h8_intc.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(H8_INTC, h8_intc_device, "h8_intc", "H8 interrupt controller")
|
||||
DEFINE_DEVICE_TYPE(H8H_INTC, h8h_intc_device, "h8h_intc", "H8H interrupt controller")
|
||||
DEFINE_DEVICE_TYPE(H8S_INTC, h8s_intc_device, "h8s_intc", "H8S interrupt controller")
|
||||
DEFINE_DEVICE_TYPE(H8_INTC, h8_intc_device, "h8_intc", "H8 interrupt controller")
|
||||
DEFINE_DEVICE_TYPE(H8H_INTC, h8h_intc_device, "h8h_intc", "H8H interrupt controller")
|
||||
DEFINE_DEVICE_TYPE(H8S_INTC, h8s_intc_device, "h8s_intc", "H8S interrupt controller")
|
||||
DEFINE_DEVICE_TYPE(GT913_INTC, gt913_intc_device, "gt913_intc", "Casio GT913F interrupt controller")
|
||||
|
||||
h8_intc_device::h8_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
h8_intc_device(mconfig, H8_INTC, tag, owner, clock)
|
||||
@ -47,7 +48,7 @@ int h8_intc_device::interrupt_taken(int vector)
|
||||
if(0)
|
||||
logerror("taking internal interrupt %d\n", vector);
|
||||
pending_irqs[vector >> 5] &= ~(1 << (vector & 31));
|
||||
if(vector >= irq_vector_base && vector < irq_vector_base + 8) {
|
||||
if(irq_vector_base >= 0 && vector >= irq_vector_base && vector < irq_vector_base + 8) {
|
||||
int irq = vector - irq_vector_base;
|
||||
if(irq_type[irq] != IRQ_LEVEL || !(irq_input & (1 << irq)))
|
||||
isr &= ~(1 << irq);
|
||||
@ -159,8 +160,11 @@ void h8_intc_device::update_irq_types()
|
||||
|
||||
void h8_intc_device::update_irq_state()
|
||||
{
|
||||
pending_irqs[0] &= ~(255 << irq_vector_base);
|
||||
pending_irqs[0] |= (isr & ier) << irq_vector_base;
|
||||
if (irq_vector_base >= 0)
|
||||
{
|
||||
pending_irqs[0] &= ~(255 << irq_vector_base);
|
||||
pending_irqs[0] |= (isr & ier) << irq_vector_base;
|
||||
}
|
||||
|
||||
int cur_vector = 0;
|
||||
int cur_level = -1;
|
||||
@ -192,6 +196,19 @@ void h8_intc_device::get_priority(int vect, int &icr_pri, int &ipr_pri) const
|
||||
}
|
||||
|
||||
|
||||
gt913_intc_device::gt913_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
gt913_intc_device(mconfig, GT913_INTC, tag, owner, clock)
|
||||
{
|
||||
irq_vector_base = -1; // no external IRQs
|
||||
irq_vector_nmi = 3;
|
||||
}
|
||||
|
||||
gt913_intc_device::gt913_intc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
h8_intc_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
h8h_intc_device::h8h_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
h8h_intc_device(mconfig, H8H_INTC, tag, owner, clock)
|
||||
{
|
||||
|
@ -60,6 +60,14 @@ protected:
|
||||
void check_level_irqs(bool force_update = false);
|
||||
};
|
||||
|
||||
class gt913_intc_device : public h8_intc_device {
|
||||
public:
|
||||
gt913_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
|
||||
protected:
|
||||
gt913_intc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class h8h_intc_device : public h8_intc_device {
|
||||
public:
|
||||
h8h_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
@ -105,8 +113,9 @@ private:
|
||||
virtual void device_reset() override;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(H8_INTC, h8_intc_device)
|
||||
DECLARE_DEVICE_TYPE(H8H_INTC, h8h_intc_device)
|
||||
DECLARE_DEVICE_TYPE(H8S_INTC, h8s_intc_device)
|
||||
DECLARE_DEVICE_TYPE(H8_INTC, h8_intc_device)
|
||||
DECLARE_DEVICE_TYPE(H8H_INTC, h8h_intc_device)
|
||||
DECLARE_DEVICE_TYPE(H8S_INTC, h8s_intc_device)
|
||||
DECLARE_DEVICE_TYPE(GT913_INTC, gt913_intc_device)
|
||||
|
||||
#endif // MAME_CPU_H8_H8_INTC_H
|
||||
|
@ -25,6 +25,11 @@ void h8_port_device::ddr_w(uint8_t data)
|
||||
update_output();
|
||||
}
|
||||
|
||||
uint8_t h8_port_device::ddr_r()
|
||||
{
|
||||
return ddr;
|
||||
}
|
||||
|
||||
void h8_port_device::dr_w(uint8_t data)
|
||||
{
|
||||
// logerror("dr_w %02x\n", data);
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
void set_info(int address, uint8_t default_ddr, uint8_t mask);
|
||||
|
||||
void ddr_w(uint8_t data);
|
||||
uint8_t ddr_r();
|
||||
void dr_w(uint8_t data);
|
||||
uint8_t dr_r();
|
||||
uint8_t port_r();
|
||||
|
@ -213,10 +213,18 @@ void h8_disassembler::disassemble_am(std::ostream &stream, int am, offs_t pc, co
|
||||
util::stream_format(stream, "#%x", (opcode >> 4) & 3);
|
||||
break;
|
||||
|
||||
case DASM_imm2l:
|
||||
util::stream_format(stream, "#%x", opcode & 3);
|
||||
break;
|
||||
|
||||
case DASM_imm3:
|
||||
util::stream_format(stream, "#%x", (opcode >> 4) & 7);
|
||||
break;
|
||||
|
||||
case DASM_imm4l:
|
||||
util::stream_format(stream, "#%x", opcode & 15);
|
||||
break;
|
||||
|
||||
case DASM_imm8:
|
||||
util::stream_format(stream, "#h'%02x", opcodes.r8(epc-1));
|
||||
break;
|
||||
@ -237,6 +245,14 @@ void h8_disassembler::disassemble_am(std::ostream &stream, int am, offs_t pc, co
|
||||
util::stream_format(stream, "exr");
|
||||
break;
|
||||
|
||||
case DASM_bankl:
|
||||
util::stream_format(stream, "bankl");
|
||||
break;
|
||||
|
||||
case DASM_bankh:
|
||||
util::stream_format(stream, "bankh");
|
||||
break;
|
||||
|
||||
case DASM_macl:
|
||||
util::stream_format(stream, "macl");
|
||||
break;
|
||||
|
@ -80,13 +80,17 @@ protected:
|
||||
DASM_four, /* immediate value 4 */
|
||||
|
||||
DASM_imm2, /* 2-bit immediate in bits 4-5 (trapa) */
|
||||
DASM_imm2l, /* 2-bit immediate in bits 0-1 (GT913) */
|
||||
DASM_imm3, /* 3-bit immediate in bits 4-6 (bit selection */
|
||||
DASM_imm4l, /* 4-bit immediate in bits 0-3 (GT913) */
|
||||
DASM_imm8, /* 8-bit immediate at +1 */
|
||||
DASM_imm16, /* 16-bit immediate at +2 */
|
||||
DASM_imm32, /* 32-bit immediate at +2 */
|
||||
|
||||
DASM_ccr, /* internal register ccr */
|
||||
DASM_exr, /* internal register exr */
|
||||
DASM_bankl, /* internal register bankl (GT913) */
|
||||
DASM_bankh, /* internal register bankl (GT913) */
|
||||
DASM_macl, /* internal register macl */
|
||||
DASM_mach /* internal register mach */
|
||||
};
|
||||
|
@ -18,6 +18,8 @@ def name_to_type(name):
|
||||
return 2
|
||||
if name == "s26":
|
||||
return 3
|
||||
if name == "g":
|
||||
return 4
|
||||
sys.stderr.write("Unknown chip type name %s\n" % name)
|
||||
sys.exit(1)
|
||||
|
||||
@ -29,7 +31,9 @@ def type_to_device(dtype, mode):
|
||||
return "h8h_device"
|
||||
if dtype == 2:
|
||||
return "h8s2000_device"
|
||||
return "h8s2600_device"
|
||||
if dtype == 3:
|
||||
return "h8s2600_device"
|
||||
return "gt913_device"
|
||||
else:
|
||||
if dtype == 0:
|
||||
return "h8_disassembler"
|
||||
@ -37,7 +41,9 @@ def type_to_device(dtype, mode):
|
||||
return "h8h_disassembler"
|
||||
if dtype == 2:
|
||||
return "h8s2000_disassembler"
|
||||
return "h8s2600_disassembler"
|
||||
if dtype == 3:
|
||||
return "h8s2600_disassembler"
|
||||
return "gt913_disassembler"
|
||||
|
||||
def hexsplit(str):
|
||||
res = []
|
||||
@ -474,7 +480,7 @@ def main(argv):
|
||||
if mode == 's':
|
||||
opcodes.build_dispatch()
|
||||
opcodes.save_opcodes(f, dname)
|
||||
if dtype == 0:
|
||||
if dtype == 0 or dtype == 4:
|
||||
opcodes.save_dispatch(f, dname)
|
||||
opcodes.save_exec(f, dname, dtype, "full")
|
||||
opcodes.save_exec(f, dname, dtype, "partial")
|
||||
|
156
src/devices/machine/gt913_io.cpp
Normal file
156
src/devices/machine/gt913_io.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/***************************************************************************
|
||||
Casio GT913 I/O (HLE)
|
||||
|
||||
TODO:
|
||||
- timer behavior is unverified (see comment in timer_control_w and timer_adjust)
|
||||
- various other unemulated registers
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "gt913_io.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(GT913_IO_HLE, gt913_io_hle_device, "gt913_io_hle", "Casio GT913F I/O (HLE)")
|
||||
|
||||
gt913_io_hle_device::gt913_io_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, GT913_IO_HLE, tag, owner, clock),
|
||||
m_cpu(*this, DEVICE_SELF_OWNER),
|
||||
m_cpu_io(nullptr), m_intc(nullptr), m_intc_tag(nullptr)
|
||||
{
|
||||
m_timer_irq[0] = m_timer_irq[1] = 0;
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::device_start()
|
||||
{
|
||||
m_cpu_io = &m_cpu->space(AS_IO);
|
||||
m_intc = siblingdevice<h8_intc_device>(m_intc_tag);
|
||||
|
||||
m_timer[0] = timer_alloc(0);
|
||||
m_timer[1] = timer_alloc(1);
|
||||
|
||||
save_item(NAME(m_timer_control));
|
||||
save_item(NAME(m_timer_rate));
|
||||
save_item(NAME(m_timer_irq_pending));
|
||||
save_item(NAME(m_adc_enable));
|
||||
save_item(NAME(m_adc_channel));
|
||||
save_item(NAME(m_adc_data));
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::device_reset()
|
||||
{
|
||||
m_timer_control[0] = m_timer_control[1] = 0x00;
|
||||
m_timer_rate[0] = m_timer_rate[1] = 0;
|
||||
m_timer_irq_pending[0] = m_timer_irq_pending[1] = false;
|
||||
|
||||
m_adc_enable = false;
|
||||
m_adc_channel = false;
|
||||
m_adc_data[0] = m_adc_data[1] = 0;
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
m_timer_irq_pending[id] = true;
|
||||
timer_check_irq(id);
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::timer_control_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
assert(offset < 2);
|
||||
// TODO: ctk551 clears and sets bit 4 during the respective timer's IRQ, what should this do? pause/restart the timer?
|
||||
m_timer_control[offset] = data;
|
||||
timer_check_irq(offset);
|
||||
}
|
||||
|
||||
uint8_t gt913_io_hle_device::timer_control_r(offs_t offset)
|
||||
{
|
||||
assert(offset < 2);
|
||||
return m_timer_control[offset];
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::timer_rate0_w(uint16_t data)
|
||||
{
|
||||
m_timer_rate[0] = data;
|
||||
timer_adjust(0);
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::timer_rate1_w(uint8_t data)
|
||||
{
|
||||
m_timer_rate[1] = data;
|
||||
timer_adjust(1);
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::timer_adjust(offs_t num)
|
||||
{
|
||||
assert(num < 2);
|
||||
|
||||
/*
|
||||
On the CTK-551, this behavior provides the expected rate for timer 0, which is the MIDI PPQN timer.
|
||||
For timer 1, this is less certain, but it seems to provide an auto power off delay only a little
|
||||
longer than the "about six minutes" mentioned in the user manual.
|
||||
*/
|
||||
u64 clocks = m_timer_rate[num];
|
||||
if (!clocks)
|
||||
{
|
||||
m_timer[num]->adjust(attotime::never);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_timer_control[num] & 0x7)
|
||||
{
|
||||
default:
|
||||
logerror("unknown timer %u prescaler %u (pc = %04x)\n", num, m_timer_control[num] & 0x7, m_cpu->pc());
|
||||
[[fallthrough]];
|
||||
case 0:
|
||||
clocks <<= 1; break;
|
||||
case 2:
|
||||
clocks <<= 10; break;
|
||||
}
|
||||
|
||||
attotime period = m_cpu->clocks_to_attotime(clocks);
|
||||
m_timer[num]->adjust(period, 0, period);
|
||||
}
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::timer_check_irq(offs_t num)
|
||||
{
|
||||
assert(num < 2);
|
||||
|
||||
if (BIT(m_timer_control[num], 3) && m_timer_irq_pending[num])
|
||||
{
|
||||
m_intc->internal_interrupt(m_timer_irq[num]);
|
||||
m_timer_irq_pending[num] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void gt913_io_hle_device::adc_control_w(uint8_t data)
|
||||
{
|
||||
m_adc_enable = BIT(data, 2);
|
||||
m_adc_channel = BIT(data, 3);
|
||||
if (m_adc_enable && BIT(data, 0))
|
||||
{
|
||||
if (!m_adc_channel)
|
||||
m_adc_data[0] = m_cpu_io->read_word(h8_device::ADC_0);
|
||||
else
|
||||
m_adc_data[1] = m_cpu_io->read_word(h8_device::ADC_1);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t gt913_io_hle_device::adc_control_r()
|
||||
{
|
||||
return (m_adc_enable << 2) | (m_adc_channel << 3);
|
||||
}
|
||||
|
||||
uint8_t gt913_io_hle_device::adc_data_r()
|
||||
{
|
||||
if (!m_adc_channel)
|
||||
return m_adc_data[0];
|
||||
else
|
||||
return m_adc_data[1];
|
||||
}
|
74
src/devices/machine/gt913_io.h
Normal file
74
src/devices/machine/gt913_io.h
Normal file
@ -0,0 +1,74 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders: Devin Acker
|
||||
/***************************************************************************
|
||||
Casio GT913 I/O (HLE)
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_GT913_IO_H
|
||||
#define MAME_MACHINE_GT913_IO_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/h8/h8_intc.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> gt913_kbd_hle_device
|
||||
|
||||
class gt913_io_hle_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
gt913_io_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
gt913_io_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *intc, int t0irq, int t1irq)
|
||||
: gt913_io_hle_device(mconfig, tag, owner, 0)
|
||||
{
|
||||
m_intc_tag = intc;
|
||||
m_timer_irq[0] = t0irq;
|
||||
m_timer_irq[1] = t1irq;
|
||||
}
|
||||
|
||||
void timer_control_w(offs_t offset, uint8_t data);
|
||||
uint8_t timer_control_r(offs_t offset);
|
||||
void timer_rate0_w(uint16_t data);
|
||||
void timer_rate1_w(uint8_t data);
|
||||
|
||||
void adc_control_w(uint8_t data);
|
||||
uint8_t adc_control_r();
|
||||
uint8_t adc_data_r();
|
||||
|
||||
protected:
|
||||
void timer_adjust(offs_t num);
|
||||
void timer_check_irq(offs_t num);
|
||||
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
private:
|
||||
required_device<cpu_device> m_cpu;
|
||||
address_space *m_cpu_io;
|
||||
h8_intc_device *m_intc;
|
||||
const char *m_intc_tag;
|
||||
|
||||
/* timers */
|
||||
uint8_t m_timer_control[2];
|
||||
uint16_t m_timer_rate[2];
|
||||
int m_timer_irq[2];
|
||||
bool m_timer_irq_pending[2];
|
||||
emu_timer *m_timer[2];
|
||||
|
||||
/* 2x ADC */
|
||||
bool m_adc_enable, m_adc_channel;
|
||||
uint8_t m_adc_data[2];
|
||||
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(GT913_IO_HLE, gt913_io_hle_device)
|
||||
|
||||
#endif // MAME_MACHINE_GT913_IO_H
|
104
src/devices/machine/gt913_kbd.cpp
Normal file
104
src/devices/machine/gt913_kbd.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/***************************************************************************
|
||||
Casio GT913 keyboard controller (HLE)
|
||||
|
||||
This is the keyboard controller portion of the GT913.
|
||||
The actual keyboard keys (as opposed to console buttons) have two
|
||||
contacts per key, which allows the controller to detect the velocity
|
||||
of the keypress. The detected velocity is read as a 7-bit value
|
||||
from the data port, along with the actual key scan code.
|
||||
|
||||
Right now, velocity is just simulated using an (optional) analog
|
||||
control. The keyboard FIFO size is also basically a guess based on
|
||||
the CTK-551's 16-key polyphony.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "gt913_kbd.h"
|
||||
#include "keyboard.ipp"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(GT913_KBD_HLE, gt913_kbd_hle_device, "gt913_kbd_hle", "Casio GT913F keyboard controller (HLE)")
|
||||
|
||||
gt913_kbd_hle_device::gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, GT913_KBD_HLE, tag, owner, clock),
|
||||
device_matrix_keyboard_interface(mconfig, *this, "KO0", "KO1", "KO2", "KO3", "KO4", "KO5", "KO6", "KO7", "KO8", "KO9", "KO10", "KO11", "KO12"),
|
||||
m_intc(nullptr), m_intc_tag(nullptr), m_irq(0),
|
||||
m_velocity(*this, "VELOCITY")
|
||||
{
|
||||
}
|
||||
|
||||
void gt913_kbd_hle_device::device_start()
|
||||
{
|
||||
m_intc = siblingdevice<h8_intc_device>(m_intc_tag);
|
||||
|
||||
save_item(NAME(m_status));
|
||||
save_item(NAME(m_fifo));
|
||||
save_item(NAME(m_fifo_read));
|
||||
save_item(NAME(m_fifo_write));
|
||||
}
|
||||
|
||||
void gt913_kbd_hle_device::device_reset()
|
||||
{
|
||||
m_status = 0x0000;
|
||||
std::memset(m_fifo, 0xff, sizeof(m_fifo));
|
||||
m_fifo_read = m_fifo_write = 0;
|
||||
|
||||
reset_key_state();
|
||||
start_processing(attotime::from_hz(1200));
|
||||
}
|
||||
|
||||
void gt913_kbd_hle_device::key_add(uint8_t row, uint8_t column, int state)
|
||||
{
|
||||
m_fifo[m_fifo_write] = (row << 3) | (column & 7);
|
||||
if (state)
|
||||
m_fifo[m_fifo_write] |= 0x80;
|
||||
|
||||
if (((m_fifo_write + 1) & 15) != m_fifo_read)
|
||||
{
|
||||
(++m_fifo_write) &= 15;
|
||||
update_status();
|
||||
}
|
||||
}
|
||||
|
||||
void gt913_kbd_hle_device::update_status()
|
||||
{
|
||||
if (m_fifo_read == m_fifo_write)
|
||||
m_status &= 0x7fff;
|
||||
else
|
||||
m_status |= 0x8000;
|
||||
|
||||
if (BIT(m_status, 15) && BIT(m_status, 14))
|
||||
m_intc->internal_interrupt(m_irq);
|
||||
}
|
||||
|
||||
uint16_t gt913_kbd_hle_device::read()
|
||||
{
|
||||
if (m_fifo_read == m_fifo_write)
|
||||
return 0xff00;
|
||||
|
||||
uint16_t data = (m_fifo[m_fifo_read] << 8) | m_velocity.read_safe(0x7f);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_fifo_read != m_fifo_write)
|
||||
{
|
||||
(++m_fifo_read) &= 15;
|
||||
update_status();
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void gt913_kbd_hle_device::status_w(uint16_t data)
|
||||
{
|
||||
m_status = data;
|
||||
update_status();
|
||||
}
|
62
src/devices/machine/gt913_kbd.h
Normal file
62
src/devices/machine/gt913_kbd.h
Normal file
@ -0,0 +1,62 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders: Devin Acker
|
||||
/***************************************************************************
|
||||
Casio GT913 keyboard controller (HLE)
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_GT913_KBD_H
|
||||
#define MAME_MACHINE_GT913_KBD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/h8/h8_intc.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> gt913_kbd_hle_device
|
||||
|
||||
class gt913_kbd_hle_device : public device_t, protected device_matrix_keyboard_interface<13>
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *intc, int irq)
|
||||
: gt913_kbd_hle_device(mconfig, tag, owner, 0)
|
||||
{
|
||||
m_intc_tag = intc;
|
||||
m_irq = irq;
|
||||
}
|
||||
|
||||
uint16_t read();
|
||||
void status_w(uint16_t data);
|
||||
uint16_t status_r() { return m_status; }
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_matrix_keyboard_interface overrides
|
||||
virtual void key_make(uint8_t row, uint8_t column) override { key_add(row, column, 0); }
|
||||
virtual void key_break(uint8_t row, uint8_t column) override { key_add(row, column, 1); }
|
||||
|
||||
void key_add(uint8_t row, uint8_t column, int state);
|
||||
void update_status();
|
||||
private:
|
||||
h8_intc_device *m_intc;
|
||||
const char *m_intc_tag;
|
||||
int m_irq;
|
||||
optional_ioport m_velocity;
|
||||
|
||||
uint16_t m_status;
|
||||
uint8_t m_fifo[16];
|
||||
uint8_t m_fifo_read, m_fifo_write;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(GT913_KBD_HLE, gt913_kbd_hle_device)
|
||||
|
||||
#endif // MAME_MACHINE_GT913_KBD_H
|
167
src/devices/machine/gt913_snd.cpp
Normal file
167
src/devices/machine/gt913_snd.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/***************************************************************************
|
||||
Casio GT913 sound (HLE)
|
||||
|
||||
This is the sound portion of the GT913.
|
||||
Up to 24 voices can be mixed into a 16-bit stereo serial bitstream,
|
||||
which is then input to either a serial DAC or a HG51B-based DSP,
|
||||
depending on the model of keyboard.
|
||||
|
||||
Currently, the actual sample format in ROM is unknown.
|
||||
The serial output is twos-complement 16-bit PCM, but the data in ROM
|
||||
doesn't seem to be - reading it as such produces sounds that are
|
||||
somewhat recognizable, but highly distorted.
|
||||
|
||||
For now, all known (and unknown) register writes are just logged
|
||||
without generating any sound.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "gt913_snd.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(GT913_SOUND_HLE, gt913_sound_hle_device, "gt913_sound_hle", "Casio GT913F sound (HLE)")
|
||||
|
||||
gt913_sound_hle_device::gt913_sound_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, GT913_SOUND_HLE, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void gt913_sound_hle_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_gain));
|
||||
save_item(NAME(m_data));
|
||||
|
||||
save_item(NAME(m_volume_target));
|
||||
save_item(NAME(m_volume_rate));
|
||||
}
|
||||
|
||||
void gt913_sound_hle_device::device_reset()
|
||||
{
|
||||
m_gain = 0;
|
||||
std::memset(m_data, 0, sizeof(m_data));
|
||||
std::memset(m_volume_target, 0, sizeof(m_volume_target));
|
||||
std::memset(m_volume_rate, 0, sizeof(m_volume_rate));
|
||||
}
|
||||
|
||||
void gt913_sound_hle_device::data_w(offs_t offset, uint16_t data)
|
||||
{
|
||||
assert(offset < 3);
|
||||
m_data[offset] = data;
|
||||
}
|
||||
|
||||
uint16_t gt913_sound_hle_device::data_r(offs_t offset)
|
||||
{
|
||||
assert(offset < 3);
|
||||
return m_data[offset];
|
||||
}
|
||||
|
||||
void gt913_sound_hle_device::command_w(uint16_t data)
|
||||
{
|
||||
uint8_t voicenum = (data & 0x1f00) >> 8;
|
||||
uint16_t voicecmd = data & 0x60ff;
|
||||
|
||||
if (data == 0x0012)
|
||||
{
|
||||
uint8_t gain = m_data[0] & 0x3f;
|
||||
if (gain != m_gain)
|
||||
logerror("gain %u\n", gain);
|
||||
m_gain = gain;
|
||||
}
|
||||
else if (voicenum >= 24)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (voicecmd == 0x0008)
|
||||
{
|
||||
/*
|
||||
Set the voice's sample start point as a ROM address.
|
||||
This is usually word-aligned, but not always
|
||||
(e.g. ctk551's lowest piano sample is at address 0x5a801)
|
||||
*/
|
||||
uint32_t samplestart = (m_data[1] | (m_data[2] << 16)) & 0xfffff;
|
||||
logerror("voice %u sample start 0x%06x\n", voicenum, samplestart);
|
||||
}
|
||||
else if (voicecmd == 0x0000)
|
||||
{
|
||||
/*
|
||||
Set the voice's sample end point as a ROM address.
|
||||
*/
|
||||
uint32_t sampleend = (m_data[0] | (m_data[1] << 16)) & 0xfffff;
|
||||
logerror("voice %u sample end 0x%06x\n", voicenum, sampleend);
|
||||
}
|
||||
else if (voicecmd == 0x2000)
|
||||
{
|
||||
/*
|
||||
Set the voice's sample loop point as a ROM address.
|
||||
*/
|
||||
uint32_t sampleloop = (m_data[0] | (m_data[1] << 16)) & 0xfffff;
|
||||
logerror("voice %u sample loop 0x%06x\n", voicenum, sampleloop);
|
||||
}
|
||||
else if (voicecmd == 0x200b)
|
||||
{
|
||||
/*
|
||||
Turn this voice on/off.
|
||||
ctk551 turns output off before assigning a new note or instrument to this voice,
|
||||
then turns output back on afterward
|
||||
*/
|
||||
logerror("voice %u output %s\n", voicenum, BIT(m_data[2], 7) ? "on" : "off");
|
||||
}
|
||||
else if (voicecmd == 0x4004)
|
||||
{
|
||||
/*
|
||||
Set this voice's panning, in the form of left and right volume levels (3 bits each)
|
||||
*/
|
||||
uint8_t left = (m_data[1] & 0xe0) >> 5;
|
||||
uint8_t right = (m_data[1] & 0x1c) >> 2;
|
||||
logerror("voice %u left %u right %u\n", voicenum, left, right);
|
||||
}
|
||||
else if (voicecmd == 0x4005)
|
||||
{
|
||||
/*
|
||||
Set the current pitch of this voice.
|
||||
The actual format of the value is unknown, but presumably some kind of fixed point
|
||||
*/
|
||||
uint32_t pitch = (m_data[0] << 8) | (m_data[1] >> 8);
|
||||
logerror("voice %u pitch 0x%06x\n", voicenum, pitch);
|
||||
}
|
||||
else if (voicecmd == 0x6007)
|
||||
{
|
||||
/*
|
||||
Raise or lower the volume to a specified level at a specified rate.
|
||||
The actual volume level is probably 7.8 fixed point or something like that, but this command
|
||||
only sets the most significant bits.
|
||||
*/
|
||||
logerror("voice %u volume %u rate %u\n", voicenum, (m_data[0] >> 8) & 0x7f, m_data[0] & 0xff);
|
||||
m_volume_target[voicenum] = m_data[0] & 0x7f00;
|
||||
m_volume_rate[voicenum] = m_data[0] & 0xff;
|
||||
}
|
||||
else if (voicecmd == 0x2028)
|
||||
{
|
||||
/*
|
||||
ctk551 issues this command and then reads the voice's current volume from data0
|
||||
to determine if it's time to start the next part of the volume envelope or not.
|
||||
For now, just return the "target" volume immediately
|
||||
(TODO: also figure out what it expects to be returned in data1)
|
||||
*/
|
||||
m_data[0] = m_volume_target[voicenum];
|
||||
m_data[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("unknown sound write %04x (data: %04x %04x %04x)\n", data, m_data[0], m_data[1], m_data[2]);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t gt913_sound_hle_device::status_r()
|
||||
{
|
||||
/* ctk551 reads the current gain level out of the lower 6 bits and ignores the rest
|
||||
it's unknown what, if anything, the other bits are supposed to contain */
|
||||
return m_gain & 0x3f;
|
||||
}
|
45
src/devices/machine/gt913_snd.h
Normal file
45
src/devices/machine/gt913_snd.h
Normal file
@ -0,0 +1,45 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders: Devin Acker
|
||||
/***************************************************************************
|
||||
Casio GT913 sound (HLE)
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_AUDIO_GT913_H
|
||||
#define MAME_AUDIO_GT913_H
|
||||
|
||||
#pragma once
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> gt913_sound_hle_device
|
||||
|
||||
class gt913_sound_hle_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
gt913_sound_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
|
||||
void data_w(offs_t offset, uint16_t data);
|
||||
uint16_t data_r(offs_t offset);
|
||||
void command_w(uint16_t data);
|
||||
uint16_t status_r();
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
uint8_t m_gain;
|
||||
uint16_t m_data[3];
|
||||
|
||||
uint16_t m_volume_target[24];
|
||||
uint8_t m_volume_rate[24];
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(GT913_SOUND_HLE, gt913_sound_hle_device)
|
||||
|
||||
#endif // MAME_AUDIO_GT913_H
|
356
src/mame/drivers/ctk551.cpp
Normal file
356
src/mame/drivers/ctk551.cpp
Normal file
@ -0,0 +1,356 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Devin Acker
|
||||
/*
|
||||
Casio CTK-551 keyboard (and related models)
|
||||
|
||||
Casio released several keyboard models with the same main board.
|
||||
As usual, some of them were also rebranded by Radio Shack.
|
||||
|
||||
- CTK-531, CTK-533
|
||||
Basic 61-key model
|
||||
- CTK-541, Optimus MD-1150
|
||||
Adds velocity-sensitive keys
|
||||
- CTK-551, CTK-558, Radio Shack MD-1160
|
||||
Adds pitch wheel and different selection of demo songs
|
||||
|
||||
Main board (JCM456-MA1M):
|
||||
|
||||
LSI1: CPU (Casio GT913F)
|
||||
Custom chip based on H8/300 instruction set, built in peripheral controllers & sound generator
|
||||
|
||||
LSI2: 8Mbit ROM (OKI MSM538002E)
|
||||
|
||||
LSI3: LCD controller (HD44780 compatible)
|
||||
May be either a Samsung KS0066U-10B or Epson SED1278F2A.
|
||||
|
||||
IC1: stereo DAC (NEC uPD6379GR)
|
||||
|
||||
CTK-541 service manual with schematics, pinouts, etc.:
|
||||
https://revenant1.net/ctk541.pdf
|
||||
|
||||
To access the test mode (not mentioned in the service manual):
|
||||
Hold the "Start/Stop" and keypad 0 buttons together when turning on the keyboard.
|
||||
Afterwards, press one of these buttons:
|
||||
- Tone: LCD test (press repeatedly)
|
||||
- Keypad 0: switch test (press all front panel buttons in a specific order, generally left to right)
|
||||
- Keypad 1 or Rhythm: pedal and key test
|
||||
- Keypad 2: ROM test
|
||||
- Keypad 4/5/6: sound volume test
|
||||
- Keypad 7/8: stereo test
|
||||
- Keypad 9: MIDI loopback test
|
||||
- Keypad + or Song Bank: power source test
|
||||
- Keypad -: pitch wheel test
|
||||
- FFWD: exit test mode
|
||||
- Stop: power off
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/midi/midiinport.h"
|
||||
#include "bus/midi/midioutport.h"
|
||||
#include "cpu/h8/gt913.h"
|
||||
#include "video/hd44780.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class ctk551_state : public driver_device
|
||||
{
|
||||
public:
|
||||
ctk551_state(machine_config const &mconfig, device_type type, char const *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_lcdc(*this, "lcdc")
|
||||
, m_led_touch(*this, "led_touch")
|
||||
{
|
||||
}
|
||||
|
||||
void ctk551(machine_config &config);
|
||||
|
||||
DECLARE_CUSTOM_INPUT_MEMBER(lcd_r) { return m_lcdc->db_r() >> 4; }
|
||||
DECLARE_WRITE_LINE_MEMBER(lcd_w) { m_lcdc->db_w(state << 4); }
|
||||
|
||||
DECLARE_CUSTOM_INPUT_MEMBER(switch_r) { return m_switch; }
|
||||
DECLARE_INPUT_CHANGED_MEMBER(switch_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(led_touch_w) { m_led_touch = state; }
|
||||
DECLARE_WRITE_LINE_MEMBER(apo_w);
|
||||
|
||||
private:
|
||||
void ctk551_io_map(address_map &map);
|
||||
|
||||
virtual void driver_start() override;
|
||||
|
||||
HD44780_PIXEL_UPDATE(lcd_update);
|
||||
void palette_init(palette_device &palette);
|
||||
|
||||
required_device<gt913_device> m_maincpu;
|
||||
required_device<hd44780_device> m_lcdc;
|
||||
|
||||
output_finder<> m_led_touch;
|
||||
|
||||
ioport_value m_switch;
|
||||
};
|
||||
|
||||
|
||||
INPUT_CHANGED_MEMBER(ctk551_state::switch_w)
|
||||
{
|
||||
logerror("switch_w: %x\n", param);
|
||||
if (!oldval && newval)
|
||||
{
|
||||
if (m_switch == 0x1 && param != m_switch)
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
else
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
||||
|
||||
m_switch = param;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(ctk551_state::apo_w)
|
||||
{
|
||||
logerror("apo_w: %x\n", state);
|
||||
/* TODO: when 1, this should turn off the LCD, speakers, etc.
|
||||
the CPU will go to sleep until the power switch triggers a NMI */
|
||||
}
|
||||
|
||||
HD44780_PIXEL_UPDATE(ctk551_state::lcd_update)
|
||||
{
|
||||
if (x < 6 && y < 8 && line < 2 && pos < 8)
|
||||
bitmap.pix(line * 8 + y, pos * 6 + x) = state;
|
||||
}
|
||||
|
||||
void ctk551_state::palette_init(palette_device &palette)
|
||||
{
|
||||
palette.set_pen_color(0, rgb_t(255, 255, 255));
|
||||
palette.set_pen_color(1, rgb_t(0, 0, 0));
|
||||
}
|
||||
|
||||
void ctk551_state::ctk551_io_map(address_map &map)
|
||||
{
|
||||
map(h8_device::PORT_1, h8_device::PORT_1).portr("P1_R").portw("P1_W").umask16(0x00ff);
|
||||
map(h8_device::PORT_2, h8_device::PORT_2).portrw("P2").umask16(0x00ff);
|
||||
map(h8_device::PORT_3, h8_device::PORT_3).portrw("P3").umask16(0x00ff);
|
||||
map(h8_device::ADC_0, h8_device::ADC_0).portr("AN0");
|
||||
map(h8_device::ADC_1, h8_device::ADC_1).portr("AN1");
|
||||
}
|
||||
|
||||
void ctk551_state::driver_start()
|
||||
{
|
||||
m_led_touch.resolve();
|
||||
|
||||
m_switch = 0x2;
|
||||
|
||||
save_item(NAME(m_switch));
|
||||
}
|
||||
|
||||
void ctk551_state::ctk551(machine_config &config)
|
||||
{
|
||||
// CPU
|
||||
GT913(config, m_maincpu, 30'000'000);
|
||||
m_maincpu->set_addrmap(AS_IO, &ctk551_state::ctk551_io_map);
|
||||
|
||||
// MIDI
|
||||
auto &mdin(MIDI_PORT(config, "mdin"));
|
||||
midiin_slot(mdin);
|
||||
mdin.rxd_handler().set("maincpu:sci", FUNC(h8_sci_device::rx_w));
|
||||
|
||||
auto &mdout(MIDI_PORT(config, "mdout"));
|
||||
midiout_slot(mdout);
|
||||
m_maincpu->subdevice<h8_sci_device>("sci")->tx_handler().set(mdout, FUNC(midi_port_device::write_txd));
|
||||
|
||||
// LCD
|
||||
HD44780(config, m_lcdc, 0);
|
||||
m_lcdc->set_lcd_size(2, 8);
|
||||
m_lcdc->set_pixel_update_cb(FUNC(ctk551_state::lcd_update));
|
||||
|
||||
// screen (for testing only)
|
||||
// TODO: the actual LCD with custom segments
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
|
||||
screen.set_screen_update("lcdc", FUNC(hd44780_device::screen_update));
|
||||
screen.set_size(6 * 8, 8 * 2);
|
||||
screen.set_visarea_full();
|
||||
screen.set_palette("palette");
|
||||
|
||||
PALETTE(config, "palette", FUNC(ctk551_state::palette_init), 2);
|
||||
}
|
||||
|
||||
INPUT_PORTS_START(ctk551)
|
||||
PORT_START("maincpu:kbd:KO0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C2")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C2#")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D2")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D2#")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E2")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F2")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F2#")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G2")
|
||||
|
||||
PORT_START("maincpu:kbd:KO1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G2#")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A2")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A2#")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B2")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C3")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C3#")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D3")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D3#")
|
||||
|
||||
PORT_START("maincpu:kbd:KO2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E3")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F3")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F3#")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G3")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G3#")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A3")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A3#")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B3")
|
||||
|
||||
PORT_START("maincpu:kbd:KO3")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C4")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C4#")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D4")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D4#")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E4")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F4")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F4#")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G4")
|
||||
|
||||
PORT_START("maincpu:kbd:KO4")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G4#")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A4")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A4#")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B4")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C5")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C5#")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D5")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D5#")
|
||||
|
||||
PORT_START("maincpu:kbd:KO5")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E5")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F5")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F5#")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G5")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G5#")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A5")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A5#")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B5")
|
||||
|
||||
PORT_START("maincpu:kbd:KO6")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C6")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C6#")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D6")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("D6#")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("E6")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F6")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("F6#")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G6")
|
||||
|
||||
PORT_START("maincpu:kbd:KO7")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("G6#")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A6")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("A6#")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("B6")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("C7")
|
||||
PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
PORT_START("maincpu:kbd:KO8")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad +") PORT_CODE(KEYCODE_PLUS_PAD)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Touch Response")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Song Bank")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rhythm")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tone")
|
||||
|
||||
PORT_START("maincpu:kbd:KO9")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_MINUS_PAD)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Accomp Volume")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Transpose / Tune / MIDI")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Chord Book")
|
||||
|
||||
PORT_START("maincpu:kbd:KO10")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Play / Pause")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Rewind")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Start / Stop")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Sync / Fill In")
|
||||
|
||||
PORT_START("maincpu:kbd:KO11")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Right Hand On/Off")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Left Hand On/Off")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Fast Forward")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Stop")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tempo Down")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Volume Down")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Tempo Up")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Volume Up")
|
||||
|
||||
PORT_START("maincpu:kbd:KO12")
|
||||
PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(ctk551_state, switch_r)
|
||||
|
||||
PORT_START("maincpu:kbd:VELOCITY")
|
||||
PORT_BIT( 0x7f, 0x7f, IPT_POSITIONAL ) PORT_NAME("Key Velocity") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0)
|
||||
|
||||
PORT_START("SWITCH")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Power Off") PORT_CHANGED_MEMBER(DEVICE_SELF, ctk551_state, switch_w, 0x1)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Normal") PORT_CHANGED_MEMBER(DEVICE_SELF, ctk551_state, switch_w, 0x2)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Casio Chord") PORT_CHANGED_MEMBER(DEVICE_SELF, ctk551_state, switch_w, 0x4)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Fingered") PORT_CHANGED_MEMBER(DEVICE_SELF, ctk551_state, switch_w, 0x8)
|
||||
|
||||
PORT_START("P1_R")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Pedal")
|
||||
PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(ctk551_state, lcd_r)
|
||||
|
||||
PORT_START("P1_W")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_MEMBER(ctk551_state, led_touch_w)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OUTPUT ) // unknown
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", hd44780_device, e_w)
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_MEMBER(ctk551_state, lcd_w)
|
||||
|
||||
PORT_START("P2")
|
||||
PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", hd44780_device, rs_w)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("lcdc", hd44780_device, rw_w)
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
|
||||
PORT_START("P3")
|
||||
PORT_BIT( 0x3f, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_MEMBER(ctk551_state, apo_w)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
|
||||
PORT_START("AN0")
|
||||
PORT_CONFNAME( 0xff, 0x00, "Power Source" )
|
||||
PORT_CONFSETTING( 0x00, "AC Adapter" )
|
||||
PORT_CONFSETTING( 0xff, "Battery" )
|
||||
|
||||
PORT_START("AN1")
|
||||
PORT_BIT( 0xff, 0x7f, IPT_PADDLE ) PORT_NAME("Pitch Wheel") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_MINMAX(0x00, 0xff)
|
||||
|
||||
INPUT_PORTS_END
|
||||
|
||||
ROM_START(ctk551)
|
||||
ROM_REGION(0x100000, "maincpu", 0)
|
||||
ROM_LOAD16_WORD_SWAP("ctk551.lsi2", 0x000000, 0x100000, CRC(66fc34cd) SHA1(47e9559edc106132f8a83462ed17a6c5c3872157))
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
SYST( 1999, ctk551, 0, 0, ctk551, ctk551, ctk551_state, empty_init, "Casio", "CTK-551", MACHINE_NO_SOUND | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
|
@ -11567,6 +11567,9 @@ cswat // (c) 1984
|
||||
@source:ct486.cpp
|
||||
ct486 // 1993? 486 with CS4031
|
||||
|
||||
@source:ctk551.cpp
|
||||
ctk551 //
|
||||
|
||||
@source:cubeqst.cpp
|
||||
cubeqst // (c) 1983 Simutrek Inc.
|
||||
cubeqsta // (c) 1983 Simutrek Inc.
|
||||
|
@ -207,6 +207,7 @@ crei680.cpp
|
||||
crimson.cpp
|
||||
crvision.cpp
|
||||
ct486.cpp
|
||||
ctk551.cpp
|
||||
cvicny.cpp
|
||||
cxg_ch2001.cpp
|
||||
cxg_dominator.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user