summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-12-18 12:52:58 -0500
committer AJR <ajrhacker@users.noreply.github.com>2019-12-18 12:52:58 -0500
commit7c6a82c3d14e4c68918f95d76ae0801877ca40ea (patch)
tree11b4bbe71b845142ce3abb133436e0b9f8eff5df
parent5da18d74228cb91b07590867d22e2d704e54a986 (diff)
vt52: Extremely preliminary CPU execution (many instructions still unimplemented)
-rw-r--r--src/devices/cpu/vt50/vt50.cpp303
-rw-r--r--src/devices/cpu/vt50/vt50.h15
-rw-r--r--src/devices/cpu/vt50/vt50dasm.cpp2
-rw-r--r--src/mame/drivers/vt52.cpp2
4 files changed, 318 insertions, 4 deletions
diff --git a/src/devices/cpu/vt50/vt50.cpp b/src/devices/cpu/vt50/vt50.cpp
index 260f2190aa2..80b94012859 100644
--- a/src/devices/cpu/vt50/vt50.cpp
+++ b/src/devices/cpu/vt50/vt50.cpp
@@ -33,6 +33,12 @@ vt5x_cpu_device::vt5x_cpu_device(const machine_config &mconfig, device_type type
, m_x8(false)
, m_cursor_ff(false)
, m_video_process(false)
+ , m_t(0)
+ , m_write_ff(false)
+ , m_flag_test_ff(false)
+ , m_load_pc(false)
+ , m_qa_e23(0)
+ , m_icount(0)
{
m_rom_config.m_is_octal = true;
m_ram_config.m_is_octal = true;
@@ -101,6 +107,11 @@ void vt5x_cpu_device::device_start()
save_item(NAME(m_x8));
save_item(NAME(m_cursor_ff));
save_item(NAME(m_video_process));
+ save_item(NAME(m_t));
+ save_item(NAME(m_write_ff));
+ save_item(NAME(m_flag_test_ff));
+ save_item(NAME(m_load_pc));
+ save_item(NAME(m_qa_e23));
}
void vt5x_cpu_device::device_reset()
@@ -108,13 +119,301 @@ void vt5x_cpu_device::device_reset()
m_pc = 0;
m_rom_bank = 0;
m_video_process = false;
+ m_t = 7;
+ m_flag_test_ff = false;
+ m_load_pc = false;
+ m_qa_e23 = false;
+}
+
+void vt5x_cpu_device::execute_te(u8 inst)
+{
+ if (BIT(inst, 3) && !BIT(inst, 7))
+ {
+ switch (inst & 0160)
+ {
+ case 0000:
+ // ZXZY
+ m_x = 0;
+ m_y = 0;
+ break;
+
+ case 0020:
+ // X8
+ m_x8 = !m_x8;
+ break;
+
+ case 0040:
+ // IXDY
+ m_x = (m_x + 1) & 0177;
+ m_y = (m_y - 1) & ((1 << m_ybits) - 1);
+ break;
+
+ case 0060:
+ // IX
+ m_x = (m_x + 1) & 0177;
+ break;
+
+ case 0100:
+ // ZA
+ m_ac = 0;
+ break;
+
+ case 0120:
+ // M1
+ m_mode_ff = true;
+ break;
+
+ case 0140:
+ // ZX
+ m_x = 0;
+ break;
+
+ case 0160:
+ // M0
+ m_mode_ff = false;
+ break;
+ }
+ }
+
+ m_flag_test_ff = false;
+ m_load_pc = false;
+ if (!BIT(inst, 7))
+ m_done_ff = false;
+}
+
+void vt5x_cpu_device::execute_tf(u8 inst)
+{
+ if (BIT(inst, 2) && !BIT(inst, 7))
+ {
+ switch (inst & 0160)
+ {
+ case 0000:
+ // DXDY
+ m_x = (m_x - 1) & 0177;
+ m_y = (m_y - 1) & ((1 << m_ybits) - 1);
+ break;
+
+ case 0020:
+ case 0040:
+ // IA or IA1
+ m_ac = (m_ac + 1) & 0177;
+ break;
+
+ case 0060:
+ // IY
+ m_y = (m_y + 1) & ((1 << m_ybits) - 1);
+ break;
+
+ case 0100:
+ // DY
+ m_y = (m_y - 1) & ((1 << m_ybits) - 1);
+ break;
+
+ case 0120:
+ // IROM
+ m_rom_bank = (m_rom_bank + 1) & 3;
+ break;
+
+ case 0140:
+ // DX
+ m_x = (m_x - 1) & 0177;
+ break;
+
+ case 0160:
+ // DA
+ m_ac = (m_ac - 1) & 0177;
+ break;
+ }
+ }
+}
+
+void vt5x_cpu_device::execute_tw(u8 inst)
+{
+ if ((inst & 0217) == 0)
+ {
+ switch (inst & 0160)
+ {
+ case 0000:
+ // SCFF
+ m_cursor_ff = true;
+ break;
+
+ case 0020:
+ // SVID
+ m_video_process = true;
+ break;
+
+ case 0040:
+ // B2Y
+ m_y = m_buffer & ((1 << m_ybits) - 1);
+ break;
+
+ case 0060:
+ // CBFF (TODO)
+ break;
+
+ case 0100:
+ // ZCAV
+ m_cursor_ff = false;
+ m_video_process = false;
+ break;
+
+ case 0120:
+ // LPB (TODO: load print shift register)
+ break;
+
+ case 0140:
+ // EPR (TODO: start printer)
+ break;
+
+ case 0160:
+ // HPR!ZY (TODO: halt printer)
+ m_y = 0;
+ break;
+ }
+ }
+
+ if (BIT(inst, 0) && !BIT(inst, 7))
+ m_flag_test_ff = true;
+
+ // set FF for instructions that write to RAM
+ m_write_ff = (BIT(inst, 7) && !m_done_ff) || inst == 022 || inst == 042 || inst == 062;
+ if (m_write_ff)
+ m_done_ff = true;
+}
+
+void vt5x_cpu_device::execute_tg(u8 inst)
+{
+ // TODO
+
+ m_write_ff = false;
+}
+
+void vt5x_cpu_device::execute_th(u8 inst)
+{
+ if (m_flag_test_ff)
+ {
+ switch (inst & 0160)
+ {
+ case 0000:
+ // M0: PSCJ (TODO)
+ // M1: URJ (TODO)
+ break;
+
+ case 0020:
+ // M0: TABJ
+ // M1: AEMJ (TODO)
+ if (!m_mode_ff)
+ m_load_pc = (m_ac & 7) == 7;
+ break;
+
+ case 0040:
+ // M0: KCLJ (TODO)
+ // M1: ALMJ (TODO)
+ break;
+
+ case 0060:
+ // M0: FRQJ (TODO)
+ // M1: ADXJ
+ if (m_mode_ff)
+ m_load_pc = m_ac != m_x;
+ break;
+
+ case 0100:
+ // M0: PRQJ (TODO)
+ // M1: AEM2J (TODO)
+ break;
+
+ case 0120:
+ // TRUJ
+ m_load_pc = true;
+ break;
+
+ case 0140:
+ // M0: UTJ (TODO)
+ // M1: VSCJ (TODO)
+ break;
+
+ case 0160:
+ // M0: TOSJ (TODO)
+ // M1: KEYJ (TODO)
+ break;
+ }
+ }
+
+ if ((m_pc & 0377) == 0377)
+ m_rom_bank = (m_rom_bank + 1) & 3;
+ m_pc = (m_pc + 1) & 03777;
+}
+
+void vt5x_cpu_device::execute_tj(u8 dest)
+{
+ if (m_load_pc)
+ m_pc = u16(m_rom_bank) << 8 | dest;
+ else
+ m_pc = (m_pc + 1) & 03777;
}
void vt5x_cpu_device::execute_run()
{
- debugger_instruction_hook(m_pc);
+ while (m_icount > 0)
+ {
+ switch (m_t)
+ {
+ case 0:
+ if (!m_qa_e23)
+ debugger_instruction_hook(m_pc);
+ m_t = 1;
+ break;
+
+ case 1:
+ if (!m_qa_e23)
+ execute_te(m_rom_cache->read_byte(m_pc));
+ m_t = 2;
+ break;
- m_icount = 0;
+ case 2:
+ if (!m_qa_e23)
+ execute_tf(m_rom_cache->read_byte(m_pc));
+ m_t = 3;
+ break;
+
+ case 3:
+ if (m_qa_e23 && m_write_ff)
+ execute_tg(m_rom_cache->read_byte(m_pc));
+ m_t = 4;
+ break;
+
+ case 4:
+ if (m_qa_e23)
+ execute_th(m_rom_cache->read_byte(m_pc));
+ m_t = 5;
+ break;
+
+ case 5:
+ m_t = 6;
+ break;
+
+ case 6:
+ if (m_qa_e23 && m_flag_test_ff)
+ execute_tj(m_rom_cache->read_byte(m_pc));
+ m_t = 7;
+ break;
+
+ case 7:
+ if (!m_qa_e23)
+ execute_tw(m_rom_cache->read_byte(m_pc));
+ m_t = 8;
+ break;
+
+ case 8:
+ m_t = 0;
+ m_qa_e23 = !m_qa_e23;
+ break;
+ }
+
+ m_icount--;
+ }
}
void vt5x_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
diff --git a/src/devices/cpu/vt50/vt50.h b/src/devices/cpu/vt50/vt50.h
index 894a5bb7538..69d7f6f2b09 100644
--- a/src/devices/cpu/vt50/vt50.h
+++ b/src/devices/cpu/vt50/vt50.h
@@ -34,6 +34,14 @@ protected:
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
private:
+ // execution helpers
+ void execute_te(u8 inst);
+ void execute_tf(u8 inst);
+ void execute_tw(u8 inst);
+ void execute_tg(u8 inst);
+ void execute_th(u8 inst);
+ void execute_tj(u8 dest);
+
// address spaces
address_space_config m_rom_config;
address_space_config m_ram_config;
@@ -56,6 +64,13 @@ private:
bool m_x8;
bool m_cursor_ff;
bool m_video_process;
+
+ // execution phases
+ u8 m_t;
+ bool m_write_ff;
+ bool m_flag_test_ff;
+ bool m_load_pc;
+ bool m_qa_e23;
s32 m_icount;
};
diff --git a/src/devices/cpu/vt50/vt50dasm.cpp b/src/devices/cpu/vt50/vt50dasm.cpp
index 9b2e603e0c4..69d0d5b68f8 100644
--- a/src/devices/cpu/vt50/vt50dasm.cpp
+++ b/src/devices/cpu/vt50/vt50dasm.cpp
@@ -103,7 +103,7 @@ offs_t vt5x_disassembler::disassemble(std::ostream &stream, offs_t pc, const vt5
if (m_jumps_h[1][(opcode & 0160) >> 4] != nullptr)
util::stream_format(stream, "/%sJ", m_jumps_h[1][(opcode & 0160) >> 4]);
- u16 nextpc = pc + 2;
+ u16 nextpc = pc + 1;
if ((opcode & 0164) == 0124) // IROM!TRUJ adjustment
nextpc += 0400;
util::stream_format(stream, " %04o", (nextpc & 01400) | opcodes.r8(pc + 1));
diff --git a/src/mame/drivers/vt52.cpp b/src/mame/drivers/vt52.cpp
index 06a827a5690..ddb11c5dadc 100644
--- a/src/mame/drivers/vt52.cpp
+++ b/src/mame/drivers/vt52.cpp
@@ -97,4 +97,4 @@ ROM_START(vt52)
ROM_LOAD("23-002b4.e1", 0x000, 0x400, NO_DUMP)
ROM_END
-COMP(1975, vt52, 0, 0, vt52, vt52, vt52_state, empty_init, "DEC", "VT52", MACHINE_IS_SKELETON)
+COMP(1975, vt52, 0, 0, vt52, vt52, vt52_state, empty_init, "Digital Equipment Corporation", "VT52", MACHINE_IS_SKELETON)