diff options
Diffstat (limited to 'src/devices/cpu/sm510/sm590op.cpp')
-rw-r--r-- | src/devices/cpu/sm510/sm590op.cpp | 157 |
1 files changed, 87 insertions, 70 deletions
diff --git a/src/devices/cpu/sm510/sm590op.cpp b/src/devices/cpu/sm510/sm590op.cpp index c9ead123360..9c43f9250b4 100644 --- a/src/devices/cpu/sm510/sm590op.cpp +++ b/src/devices/cpu/sm510/sm590op.cpp @@ -11,100 +11,130 @@ void sm590_device::do_branch(u8 pu, u8 pm, u8 pl) { - // set new PC(Pu/Pm/Pl) - m_pc = (((u16)pu << 9 & 0x200) | ((u16)pm << 7 & 0x180) | (pl & 0x07f)) & m_prgmask; + // set new PC(Pu/Pm/Pl) (Pu is not used on SM590) + m_pc = ((pu << 9 & 0x200) | (pm << 7 & 0x180) | (pl & 0x07f)) & m_prgmask; } +void sm590_device::port_w(offs_t offset, u8 data) +{ + offset &= 3; + data &= 0xf; + m_rports[offset] = data; + m_write_rx[offset](offset, data); +} + + // instruction set -void sm590_device::op_adx() +// ROM address instructions + +void sm590_device::op_tl() { - // ADX x: add immediate value to ACC, skip next on carry - m_acc += (m_op & 0xf); - m_skip = bool(m_acc & 0x10); - m_acc &= 0xf; + // TL xyz: long jump + do_branch(BIT(m_op, 1), (m_op << 1 & 2) | BIT(m_param, 7), m_param & 0x7f); } -void sm590_device::op_tax() +void sm590_device::op_tls() { - // TAX: skip next if ACC equals 4-bit immediate value - m_skip = (m_acc == (m_op & 0xf)); + // TLS xyz: long call + push_stack(); + do_branch(BIT(m_op, 1), (m_op << 1 & 2) | BIT(m_param, 7), m_param & 0x7f); } + +// Data transfer instructions + void sm590_device::op_lblx() { // LBL x: load BL with 4-bit immediate value m_bl = (m_op & 0xf); } +void sm590_device::op_lbmx() +{ + // LBM x: load BM with 2-bit immediate value + m_bm = (m_op & 0x3); +} + +void sm590_device::op_str() +{ + // STR: store ACC to RAM + ram_w(m_acc); +} + void sm590_device::op_lda() { - // LDA: load ACC with RAM + // LDA: load ACC with RAM (no BM xor) m_acc = ram_r(); } void sm590_device::op_exc() { - // EXC: exchange ACC with RAM + // EXC: exchange ACC with RAM (no BM xor) u8 a = m_acc; m_acc = ram_r(); ram_w(a); } -void sm590_device::op_atr() +void sm590_device::op_exax() { - // ATR: output ACC to R(BL) - m_rports[m_bl & 0x3] = m_acc; // is the mask for BL correct here? if BL is >= 4, do the writes just go nowhere? + // EXAX: exchange X with ACC + u8 a = m_acc; + m_acc = m_x; + m_x = a; } -void sm590_device::op_mtr() +void sm590_device::op_blta() { - // MTR: output RAM to R(BL) - m_rports[m_bl & 0x3] = ram_r(); // is the mask for BL correct here? if BL is >= 4, do the writes just go nowhere? + // BLTA: load ACC with BL + m_acc = m_bl; } -void sm590_device::op_str() -{ - // STR: output ACC to RAM - ram_w(m_acc); -} -void sm590_device::op_inbm() +// Arithmetic instructions + +void sm590_device::op_adx() { - // INBM: increment BM - m_bm = (m_bm + 1) & 0x3; // is this mask correct? + // ADX x: add immediate value to ACC, skip next on carry + m_acc += (m_op & 0xf); + m_skip = bool(m_acc & 0x10); + m_acc &= 0xf; } -void sm590_device::op_debm() +void sm590_device::op_ads() { - // DEBM: decrement BM - m_bm = (m_bm - 1) & 0x3; // is this mask correct? + // ADS: add RAM to ACC, skip next on carry + m_acc += ram_r(); + m_skip = bool(m_acc & 0x10); + m_acc &= 0xf; } -void sm590_device::op_tc() +void sm590_device::op_adc() { - // TC: skip next if carry - m_skip = bool(m_c); + // ADC: add RAM and carry to ACC and carry + op_add11(); + m_skip = false; // no skip } -void sm590_device::op_rta() +void sm590_device::op_inbm() { - // RTA: load ACC with R(BL) - m_acc = m_rports[m_bl & 0x3]; // TODO: need a read function for this; is the mask for BL correct here? if BL is >= 4, do we always read 0 or F? + // INBM: increment BM + m_bm = (m_bm + 1) & m_datamask >> 4; } -void sm590_device::op_blta() +void sm590_device::op_debm() { - // BLTA: load ACC with BL - m_acc = m_bl; + // DEBM: decrement BM + m_bm = (m_bm - 1) & m_datamask >> 4; } -void sm590_device::op_exax() + +// Test instructions + +void sm590_device::op_tax() { - // EXAX: exchange X with ACC - u8 a = m_acc; - m_acc = m_x; - m_x = a; + // TAX: skip next if ACC equals 4-bit immediate value + m_skip = (m_acc == (m_op & 0xf)); } void sm590_device::op_tba() @@ -113,43 +143,30 @@ void sm590_device::op_tba() m_skip = ((m_acc & bitmask(m_op)) != 0); } -void sm590_device::op_ads() +void sm590_device::op_tc() { - // ADS: add RAM to ACC, skip next on carry - m_acc += ram_r(); - m_skip = bool(m_acc & 0x10); - m_acc &= 0xf; + // TC: skip next if carry + m_skip = bool(m_c); } -void sm590_device::op_adc() -{ - // ADC: add RAM and carry to ACC and carry - m_acc += ram_r() + m_c; - m_c = m_acc >> 4 & 1; - m_acc &= 0xf; -} -void sm590_device::op_lbmx() -{ - // LBM x: load BM with 2-bit immediate value - m_bm = (m_op & 0x3); -} +// I/O instructions -void sm590_device::op_tl() +void sm590_device::op_atr() { - // TL xyz: long jump (same as sm510 TL except m_op and m_param masks) - do_branch((m_op & 2)>>1, (((m_op & 1)<<1)|((m_param&0x80)?1:0)), m_param & 0x7f); + // ATR: output ACC to R(BL) + port_w(m_bl, m_acc); } -void sm590_device::op_tml() // aka TLS +void sm590_device::op_mtr() { - // TLS xyz: long call (same as sm510 TML except m_param mask) - push_stack(); - do_branch((m_op & 2)>>1, (((m_op & 1)<<1)|((m_param&0x80)?1:0)), m_param & 0x7f); + // MTR: output RAM to R(BL) + port_w(m_bl, ram_r()); } -void sm590_device::op_t() +void sm590_device::op_rta() { - // TR xy: jump(transfer) within current page (same as sm510 T except m_op/m_pc mask) - m_pc = (m_pc & ~0x7f) | (m_op & 0x7f); + // RTA: load ACC with R(BL) + u8 offset = m_bl & 3; + m_acc = (m_rports[offset] | m_read_rx[offset](offset)) & 0xf; } |