Casio CTK-551 [Daivn Acker]

* New machine marked as NOT_WORKING
----------------------------------
Casio CTK-551 [Devin Acker]
This commit is contained in:
Devin Acker 2021-10-13 03:35:00 -04:00 committed by GitHub
parent a15538b4ae
commit 8962638b77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1585 additions and 47 deletions

View File

@ -700,6 +700,8 @@ if CPUS["H8"] then
MAME_DIR .. "src/devices/cpu/h8/h8_sci.h", 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.cpp",
MAME_DIR .. "src/devices/cpu/h8/h8_watchdog.h", 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 { 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/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/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/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 { 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/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/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/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 end
if opt_tool(CPUS, "H8") then 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/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/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/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/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/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/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/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/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.cpp")
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/h8d.h") 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/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.cpp")
table.insert(disasm_files, MAME_DIR .. "src/devices/cpu/h8/h8s2600d.h") 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 end
-------------------------------------------------- --------------------------------------------------

View File

@ -1391,6 +1391,22 @@ if (MACHINES["FGA002"]~=null) then
} }
end 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 --@src/devices/machine/hd63450.h,MACHINES["HD63450"] = true

View File

@ -530,6 +530,7 @@ MACHINES["ER2055"] = true
MACHINES["EXORTERM"] = true MACHINES["EXORTERM"] = true
MACHINES["F3853"] = true MACHINES["F3853"] = true
MACHINES["F4702"] = true MACHINES["F4702"] = true
MACHINES["GT913"] = true
MACHINES["HD63450"] = true MACHINES["HD63450"] = true
MACHINES["HD64610"] = true MACHINES["HD64610"] = true
MACHINES["HP_DC100_TAPE"] = true MACHINES["HP_DC100_TAPE"] = true
@ -2024,6 +2025,7 @@ files {
MAME_DIR .. "src/mame/drivers/fp6000.cpp", MAME_DIR .. "src/mame/drivers/fp6000.cpp",
MAME_DIR .. "src/mame/machine/fp6000_kbd.cpp", MAME_DIR .. "src/mame/machine/fp6000_kbd.cpp",
MAME_DIR .. "src/mame/machine/fp6000_kbd.h", 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/ht6000.cpp",
MAME_DIR .. "src/mame/drivers/pb1000.cpp", MAME_DIR .. "src/mame/drivers/pb1000.cpp",
MAME_DIR .. "src/mame/drivers/pv1000.cpp", MAME_DIR .. "src/mame/drivers/pv1000.cpp",

View 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"

View 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

View 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

View 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)
{
}

View 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

View File

@ -28,6 +28,7 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char
has_exr = false; has_exr = false;
mac_saturating = false; mac_saturating = false;
has_trace = false; has_trace = false;
has_hc = true;
} }
void h8_device::device_config_complete() 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_Z) ? 'Z' : '-',
(CCR & F_V) ? 'V' : '-', (CCR & F_V) ? 'V' : '-',
(CCR & F_C) ? 'C' : '-'); (CCR & F_C) ? 'C' : '-');
else else if(has_hc)
str = string_format("%c%c%c%c%c%c%c%c", str = string_format("%c%c%c%c%c%c%c%c",
(CCR & F_I) ? 'I' : '-', (CCR & F_I) ? 'I' : '-',
(CCR & F_UI) ? 'u' : '-', (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_Z) ? 'Z' : '-',
(CCR & F_V) ? 'V' : '-', (CCR & F_V) ? 'V' : '-',
(CCR & F_C) ? 'C' : '-'); (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; break;
case H8_R0: case H8_R0:
case H8_R1: case H8_R1:
@ -449,9 +460,13 @@ int h8_device::trapa_setup()
uint8_t h8_device::do_addx8(uint8_t v1, uint8_t v2) uint8_t h8_device::do_addx8(uint8_t v1, uint8_t v2)
{ {
uint16_t res = v1 + v2 + (CCR & F_C ? 1 : 0); uint16_t res = v1 + v2 + (CCR & F_C ? 1 : 0);
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xf) + (v2 & 0xf) + (CCR & F_C ? 1 : 0)) & 0x10) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if(((v1 & 0xf) + (v2 & 0xf) + (CCR & F_C ? 1 : 0)) & 0x10)
CCR |= F_H;
}
if(!uint8_t(res)) if(!uint8_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int8_t(res) < 0) 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) uint8_t h8_device::do_subx8(uint8_t v1, uint8_t v2)
{ {
uint16_t res = v1 - v2 - (CCR & F_C ? 1 : 0); uint16_t res = v1 - v2 - (CCR & F_C ? 1 : 0);
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xf) - (v2 & 0xf) - (CCR & F_C ? 1 : 0)) & 0x10) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if (((v1 & 0xf) - (v2 & 0xf) - (CCR & F_C ? 1 : 0)) & 0x10)
CCR |= F_H;
}
if(!uint8_t(res)) if(!uint8_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int8_t(res) < 0) 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) uint8_t h8_device::do_add8(uint8_t v1, uint8_t v2)
{ {
uint16_t res = v1 + v2; uint16_t res = v1 + v2;
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xf) + (v2 & 0xf)) & 0x10) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if (((v1 & 0xf) + (v2 & 0xf)) & 0x10)
CCR |= F_H;
}
if(!uint8_t(res)) if(!uint8_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int8_t(res) < 0) 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) uint16_t h8_device::do_add16(uint16_t v1, uint16_t v2)
{ {
uint32_t res = v1 + v2; uint32_t res = v1 + v2;
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xfff) + (v2 & 0xffff)) & 0x1000) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if (((v1 & 0xfff) + (v2 & 0xffff)) & 0x1000)
CCR |= F_H;
}
if(!uint16_t(res)) if(!uint16_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int16_t(res) < 0) 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) uint32_t h8_device::do_add32(uint32_t v1, uint32_t v2)
{ {
uint64_t res = uint64_t(v1) + uint64_t(v2); uint64_t res = uint64_t(v1) + uint64_t(v2);
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if (((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000)
CCR |= F_H;
}
if(!uint32_t(res)) if(!uint32_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int32_t(res) < 0) 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) uint8_t h8_device::do_sub8(uint8_t v1, uint8_t v2)
{ {
uint16_t res = v1 - v2; uint16_t res = v1 - v2;
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xf) - (v2 & 0xf)) & 0x10) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if (((v1 & 0xf) - (v2 & 0xf)) & 0x10)
CCR |= F_H;
}
if(!uint8_t(res)) if(!uint8_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int8_t(res) < 0) 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) uint16_t h8_device::do_sub16(uint16_t v1, uint16_t v2)
{ {
uint32_t res = v1 - v2; uint32_t res = v1 - v2;
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xfff) - (v2 & 0xffff)) & 0x1000) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if (((v1 & 0xfff) - (v2 & 0xffff)) & 0x1000)
CCR |= F_H;
}
if(!uint16_t(res)) if(!uint16_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int16_t(res) < 0) 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) uint32_t h8_device::do_sub32(uint32_t v1, uint32_t v2)
{ {
uint64_t res = uint64_t(v1) - uint64_t(v2); uint64_t res = uint64_t(v1) - uint64_t(v2);
CCR &= ~(F_N|F_V|F_Z|F_C|F_H); CCR &= ~(F_N|F_V|F_Z|F_C);
if(((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000) if (has_hc)
CCR |= F_H; {
CCR &= ~F_H;
if (((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000)
CCR |= F_H;
}
if(!uint32_t(res)) if(!uint32_t(res))
CCR |= F_Z; CCR |= F_Z;
else if(int32_t(res) < 0) else if(int32_t(res) < 0)

View File

@ -135,6 +135,7 @@ protected:
uint32_t TMPR; /* For debugger ER register import */ uint32_t TMPR; /* For debugger ER register import */
bool has_exr, has_trace, supports_advanced, mode_advanced, mode_a20, mac_saturating; 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 inst_state, inst_substate, requested_state;
int icount, bcount, count_before_instruction_step; int icount, bcount, count_before_instruction_step;
@ -334,7 +335,7 @@ protected:
O(divxu_b_r8h_r16l); O(divxu_b_r8h_r16l);
O(eepmov_b); O(eepmov_b);
O(inc_b_one_r8l); 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(jsr_abs8i); O(jsr_abs16e); O(jsr_r16h);
O(ldc_imm8_ccr); O(ldc_r8l_ccr); 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); 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);

View File

@ -100,7 +100,7 @@ macro jsr32 %opc %spreg
prefetch_done(); prefetch_done();
10000 reset 10000 reset
CCR |= F_I; CCR |= (has_hc ? F_I : F_H);
EXR = EXR_I | EXR_NC; EXR = EXR_I | EXR_NC;
if(mode_advanced) { if(mode_advanced) {
IR[0] = read16i(0); IR[0] = read16i(0);
@ -1007,7 +1007,7 @@ macro jsr32 %opc %spreg
TMP1 = r8_r(IR[0]); TMP1 = r8_r(IR[0]);
TMP2 = 0; TMP2 = 0;
if(CCR & F_C) { if(CCR & F_C) {
if(CCR & F_H) { if(has_hc && (CCR & F_H)) {
if((TMP1 & 0xf0) <= 0x30 && (TMP1 & 0x0f) <= 3) if((TMP1 & 0xf0) <= 0x30 && (TMP1 & 0x0f) <= 3)
TMP2 = 0x66; TMP2 = 0x66;
} else { } else {
@ -1015,7 +1015,7 @@ macro jsr32 %opc %spreg
TMP2 = (TMP1 & 0x0f) <= 9 ? 0x60 : 0x66; TMP2 = (TMP1 & 0x0f) <= 9 ? 0x60 : 0x66;
} }
} else { } else {
if(CCR & F_H) { if(has_hc && (CCR & F_H)) {
if((TMP1 & 0x0f) <= 3) if((TMP1 & 0x0f) <= 3)
TMP2 = (TMP1 & 0xf0) <= 0x90 ? 0x06 : 0x66; TMP2 = (TMP1 & 0xf0) <= 0x90 ? 0x06 : 0x66;
} else { } else {
@ -1378,7 +1378,7 @@ macro jsr32 %opc %spreg
TMP1 = r8_r(IR[0]); TMP1 = r8_r(IR[0]);
TMP2 = 0; TMP2 = 0;
if(CCR & F_C) { if(CCR & F_C) {
if(CCR & F_H) { if(has_hc && (CCR & F_H)) {
if((TMP1 & 0xf0) >= 0x60 && (TMP1 & 0x0f) >= 6) if((TMP1 & 0xf0) >= 0x60 && (TMP1 & 0x0f) >= 6)
TMP2 = 0x9a; TMP2 = 0x9a;
} else { } else {
@ -1386,7 +1386,7 @@ macro jsr32 %opc %spreg
TMP2 = 0xa0; TMP2 = 0xa0;
} }
} else { } else {
if(CCR & F_H) { if(has_hc && (CCR & F_H)) {
if((TMP1 & 0xf0) <= 0x80 && (TMP1 & 0x0f) >= 6) if((TMP1 & 0xf0) <= 0x80 && (TMP1 & 0x0f) >= 6)
TMP2 = 0xfa; TMP2 = 0xfa;
} }
@ -1647,6 +1647,11 @@ macro jsr32 %opc %spreg
58f0 ffff 0 ble rel16 - h 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 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 5900 ff8f 0 jmp r32h - h
fetch(); fetch();
PC = r32_r(IR[0] >> 4); PC = r32_r(IR[0] >> 4);

View File

@ -3,9 +3,10 @@
#include "emu.h" #include "emu.h"
#include "h8_intc.h" #include "h8_intc.h"
DEFINE_DEVICE_TYPE(H8_INTC, h8_intc_device, "h8_intc", "H8 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(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(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::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) h8_intc_device(mconfig, H8_INTC, tag, owner, clock)
@ -47,7 +48,7 @@ int h8_intc_device::interrupt_taken(int vector)
if(0) if(0)
logerror("taking internal interrupt %d\n", vector); logerror("taking internal interrupt %d\n", vector);
pending_irqs[vector >> 5] &= ~(1 << (vector & 31)); 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; int irq = vector - irq_vector_base;
if(irq_type[irq] != IRQ_LEVEL || !(irq_input & (1 << irq))) if(irq_type[irq] != IRQ_LEVEL || !(irq_input & (1 << irq)))
isr &= ~(1 << irq); isr &= ~(1 << irq);
@ -159,8 +160,11 @@ void h8_intc_device::update_irq_types()
void h8_intc_device::update_irq_state() void h8_intc_device::update_irq_state()
{ {
pending_irqs[0] &= ~(255 << irq_vector_base); if (irq_vector_base >= 0)
pending_irqs[0] |= (isr & ier) << irq_vector_base; {
pending_irqs[0] &= ~(255 << irq_vector_base);
pending_irqs[0] |= (isr & ier) << irq_vector_base;
}
int cur_vector = 0; int cur_vector = 0;
int cur_level = -1; 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::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) h8h_intc_device(mconfig, H8H_INTC, tag, owner, clock)
{ {

View File

@ -60,6 +60,14 @@ protected:
void check_level_irqs(bool force_update = false); 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 { class h8h_intc_device : public h8_intc_device {
public: public:
h8h_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); 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; virtual void device_reset() override;
}; };
DECLARE_DEVICE_TYPE(H8_INTC, h8_intc_device) DECLARE_DEVICE_TYPE(H8_INTC, h8_intc_device)
DECLARE_DEVICE_TYPE(H8H_INTC, h8h_intc_device) DECLARE_DEVICE_TYPE(H8H_INTC, h8h_intc_device)
DECLARE_DEVICE_TYPE(H8S_INTC, h8s_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 #endif // MAME_CPU_H8_H8_INTC_H

View File

@ -25,6 +25,11 @@ void h8_port_device::ddr_w(uint8_t data)
update_output(); update_output();
} }
uint8_t h8_port_device::ddr_r()
{
return ddr;
}
void h8_port_device::dr_w(uint8_t data) void h8_port_device::dr_w(uint8_t data)
{ {
// logerror("dr_w %02x\n", data); // logerror("dr_w %02x\n", data);

View File

@ -28,6 +28,7 @@ public:
void set_info(int address, uint8_t default_ddr, uint8_t mask); void set_info(int address, uint8_t default_ddr, uint8_t mask);
void ddr_w(uint8_t data); void ddr_w(uint8_t data);
uint8_t ddr_r();
void dr_w(uint8_t data); void dr_w(uint8_t data);
uint8_t dr_r(); uint8_t dr_r();
uint8_t port_r(); uint8_t port_r();

View File

@ -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); util::stream_format(stream, "#%x", (opcode >> 4) & 3);
break; break;
case DASM_imm2l:
util::stream_format(stream, "#%x", opcode & 3);
break;
case DASM_imm3: case DASM_imm3:
util::stream_format(stream, "#%x", (opcode >> 4) & 7); util::stream_format(stream, "#%x", (opcode >> 4) & 7);
break; break;
case DASM_imm4l:
util::stream_format(stream, "#%x", opcode & 15);
break;
case DASM_imm8: case DASM_imm8:
util::stream_format(stream, "#h'%02x", opcodes.r8(epc-1)); util::stream_format(stream, "#h'%02x", opcodes.r8(epc-1));
break; break;
@ -237,6 +245,14 @@ void h8_disassembler::disassemble_am(std::ostream &stream, int am, offs_t pc, co
util::stream_format(stream, "exr"); util::stream_format(stream, "exr");
break; break;
case DASM_bankl:
util::stream_format(stream, "bankl");
break;
case DASM_bankh:
util::stream_format(stream, "bankh");
break;
case DASM_macl: case DASM_macl:
util::stream_format(stream, "macl"); util::stream_format(stream, "macl");
break; break;

View File

@ -80,13 +80,17 @@ protected:
DASM_four, /* immediate value 4 */ DASM_four, /* immediate value 4 */
DASM_imm2, /* 2-bit immediate in bits 4-5 (trapa) */ 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_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_imm8, /* 8-bit immediate at +1 */
DASM_imm16, /* 16-bit immediate at +2 */ DASM_imm16, /* 16-bit immediate at +2 */
DASM_imm32, /* 32-bit immediate at +2 */ DASM_imm32, /* 32-bit immediate at +2 */
DASM_ccr, /* internal register ccr */ DASM_ccr, /* internal register ccr */
DASM_exr, /* internal register exr */ DASM_exr, /* internal register exr */
DASM_bankl, /* internal register bankl (GT913) */
DASM_bankh, /* internal register bankl (GT913) */
DASM_macl, /* internal register macl */ DASM_macl, /* internal register macl */
DASM_mach /* internal register mach */ DASM_mach /* internal register mach */
}; };

View File

@ -18,6 +18,8 @@ def name_to_type(name):
return 2 return 2
if name == "s26": if name == "s26":
return 3 return 3
if name == "g":
return 4
sys.stderr.write("Unknown chip type name %s\n" % name) sys.stderr.write("Unknown chip type name %s\n" % name)
sys.exit(1) sys.exit(1)
@ -29,7 +31,9 @@ def type_to_device(dtype, mode):
return "h8h_device" return "h8h_device"
if dtype == 2: if dtype == 2:
return "h8s2000_device" return "h8s2000_device"
return "h8s2600_device" if dtype == 3:
return "h8s2600_device"
return "gt913_device"
else: else:
if dtype == 0: if dtype == 0:
return "h8_disassembler" return "h8_disassembler"
@ -37,7 +41,9 @@ def type_to_device(dtype, mode):
return "h8h_disassembler" return "h8h_disassembler"
if dtype == 2: if dtype == 2:
return "h8s2000_disassembler" return "h8s2000_disassembler"
return "h8s2600_disassembler" if dtype == 3:
return "h8s2600_disassembler"
return "gt913_disassembler"
def hexsplit(str): def hexsplit(str):
res = [] res = []
@ -474,7 +480,7 @@ def main(argv):
if mode == 's': if mode == 's':
opcodes.build_dispatch() opcodes.build_dispatch()
opcodes.save_opcodes(f, dname) opcodes.save_opcodes(f, dname)
if dtype == 0: if dtype == 0 or dtype == 4:
opcodes.save_dispatch(f, dname) opcodes.save_dispatch(f, dname)
opcodes.save_exec(f, dname, dtype, "full") opcodes.save_exec(f, dname, dtype, "full")
opcodes.save_exec(f, dname, dtype, "partial") opcodes.save_exec(f, dname, dtype, "partial")

View 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];
}

View 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

View 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();
}

View 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

View 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;
}

View 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
View 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 )

View File

@ -11567,6 +11567,9 @@ cswat // (c) 1984
@source:ct486.cpp @source:ct486.cpp
ct486 // 1993? 486 with CS4031 ct486 // 1993? 486 with CS4031
@source:ctk551.cpp
ctk551 //
@source:cubeqst.cpp @source:cubeqst.cpp
cubeqst // (c) 1983 Simutrek Inc. cubeqst // (c) 1983 Simutrek Inc.
cubeqsta // (c) 1983 Simutrek Inc. cubeqsta // (c) 1983 Simutrek Inc.

View File

@ -207,6 +207,7 @@ crei680.cpp
crimson.cpp crimson.cpp
crvision.cpp crvision.cpp
ct486.cpp ct486.cpp
ctk551.cpp
cvicny.cpp cvicny.cpp
cxg_ch2001.cpp cxg_ch2001.cpp
cxg_dominator.cpp cxg_dominator.cpp