summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/st62xx/st62xx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/st62xx/st62xx.cpp')
-rw-r--r--src/devices/cpu/st62xx/st62xx.cpp443
1 files changed, 251 insertions, 192 deletions
diff --git a/src/devices/cpu/st62xx/st62xx.cpp b/src/devices/cpu/st62xx/st62xx.cpp
index d475ef0048e..7b47c087dfd 100644
--- a/src/devices/cpu/st62xx/st62xx.cpp
+++ b/src/devices/cpu/st62xx/st62xx.cpp
@@ -7,7 +7,8 @@
To Do:
- Cycle counts
- STOP, WAIT opcodes
- - Peripherals
+ - ADC, UART, SPI, Watchdog, Auto-Reload Timer peripherals
+ - Interrupts
**********************************************************************/
@@ -15,6 +16,14 @@
#include "st62xx.h"
#include "st62xx_dasm.h"
+#define LOG_UNIMPL (1U << 1)
+#define LOG_GPIO (1U << 2)
+#define LOG_TIMER (1U << 3)
+#define LOG_ALL (LOG_UNIMPL | LOG_GPIO | LOG_TIMER)
+
+#define VERBOSE (LOG_ALL)
+#include "logmacro.h"
+
DEFINE_DEVICE_TYPE(ST6228, st6228_device, "st6228", "STmicro ST6228")
st6228_device::st6228_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -28,26 +37,39 @@ st6228_device::st6228_device(const machine_config &mconfig, const char *tag, dev
, m_portb_out(*this)
, m_portc_out(*this)
, m_portd_out(*this)
+ , m_timer_out(*this)
, m_program(nullptr)
, m_data(nullptr)
- , m_rambank(*this, "rambank")
- , m_program_rombank(*this, "program_rombank")
- , m_data_rombank(*this, "data_rombank")
+ , m_ram_bank(*this, "rambank")
+ , m_data_bank(*this, "databank")
+ , m_program_rom_bank(*this, "program_rombank")
+ , m_data_rom_bank(*this, "data_rombank")
, m_rom(*this, this->tag())
{
}
void st6228_device::st6228_program_map(address_map &map)
{
- map(0x000, 0x7ff).bankr(m_program_rombank);
+ map(0x000, 0x7ff).bankr(m_program_rom_bank);
map(0x800, 0xfff).rom().region(tag(), 0x800);
}
void st6228_device::st6228_data_map(address_map &map)
{
- map(0x00, 0x3f).bankrw(m_rambank);
- map(0x40, 0x7f).bankr(m_data_rombank);
- map(0x80, 0xff).rw(FUNC(st6228_device::regs_r), FUNC(st6228_device::regs_w));
+ map(0x00, 0x3f).bankrw(m_ram_bank);
+ map(0x40, 0x7f).bankr(m_data_rom_bank);
+ map(0x80, 0xbf).bankrw(m_data_bank);
+ map(0xc0, 0xff).rw(FUNC(st6228_device::unimplemented_reg_r), FUNC(st6228_device::unimplemented_reg_w));
+ map(0xc0, 0xc3).rw(FUNC(st6228_device::gpio_data_r), FUNC(st6228_device::gpio_data_w));
+ map(0xc4, 0xc7).rw(FUNC(st6228_device::gpio_dir_r), FUNC(st6228_device::gpio_dir_w));
+ map(0xc9, 0xc9).w(FUNC(st6228_device::data_rom_window_w));
+ map(0xca, 0xca).w(FUNC(st6228_device::rom_bank_select_w));
+ map(0xcb, 0xcb).w(FUNC(st6228_device::ram_bank_select_w));
+ map(0xcc, 0xcf).rw(FUNC(st6228_device::gpio_option_r), FUNC(st6228_device::gpio_option_w));
+ map(0xd2, 0xd2).rw(FUNC(st6228_device::timer_prescale_r), FUNC(st6228_device::timer_prescale_w));
+ map(0xd3, 0xd3).rw(FUNC(st6228_device::timer_counter_r), FUNC(st6228_device::timer_counter_w));
+ map(0xd4, 0xd4).rw(FUNC(st6228_device::timer_status_r), FUNC(st6228_device::timer_control_w));
+ map(0xd8, 0xd8).w(FUNC(st6228_device::watchdog_w));
}
void st6228_device::device_start()
@@ -93,17 +115,18 @@ void st6228_device::device_start()
save_item(NAME(m_port_input));
save_item(NAME(m_port_irq_enable));
+ save_item(NAME(m_timer_divider));
+ save_item(NAME(m_timer_pin));
+ save_item(NAME(m_timer_active));
+
// set our instruction counter
set_icountptr(m_icount);
- m_rambank->configure_entries(0, 2, m_ram, 0x40);
- m_program_rombank->configure_entries(0, 4, m_rom->base(), 0x800);
- m_data_rombank->configure_entries(0, 128, m_rom->base(), 0x40);
+ m_ram_bank->configure_entries(0, 2, m_ram, 0x40);
+ m_program_rom_bank->configure_entries(0, 4, m_rom->base(), 0x800);
+ m_data_rom_bank->configure_entries(0, 128, m_rom->base(), 0x40);
- m_porta_out.resolve_all_safe();
- m_portb_out.resolve_all_safe();
- m_portc_out.resolve_all_safe();
- m_portd_out.resolve_all_safe();
+ m_data_bank->set_base(&m_regs[0x80]);
}
void st6228_device::device_reset()
@@ -121,19 +144,23 @@ void st6228_device::device_reset()
std::fill(std::begin(m_port_input), std::end(m_port_input), 0);
std::fill(std::begin(m_port_irq_enable), std::end(m_port_irq_enable), 0);
- m_pc = m_program->read_word(VEC_RESET);
+ m_pc = VEC_RESET;
m_stack_index = 0;
m_mode = MODE_NMI;
m_prev_mode = MODE_NORMAL;
- m_rambank->set_entry(0);
- m_program_rombank->set_entry(0);
- m_data_rombank->set_entry(0);
+ m_ram_bank->set_entry(0);
+ m_program_rom_bank->set_entry(0);
+ m_data_rom_bank->set_entry(0);
m_regs[REG_TIMER_COUNT] = 0xff;
m_regs[REG_TIMER_PRESCALE] = 0x7f;
m_regs[REG_WATCHDOG] = 0xfe;
m_regs[REG_AD_CONTROL] = 0x40;
+
+ m_timer_divider = 12;
+ m_timer_pin = 0;
+ m_timer_active = false;
}
device_memory_interface::space_config_vector st6228_device::memory_space_config() const
@@ -166,31 +193,31 @@ std::unique_ptr<util::disasm_interface> st6228_device::create_disassembler()
}
// TODO: interrupts
-WRITE_LINE_MEMBER(st6228_device::porta0_w) { m_port_input[PORT_A] &= ~(1 << 0); m_port_input[PORT_A] |= (state << 0); }
-WRITE_LINE_MEMBER(st6228_device::porta1_w) { m_port_input[PORT_A] &= ~(1 << 1); m_port_input[PORT_A] |= (state << 1); }
-WRITE_LINE_MEMBER(st6228_device::porta2_w) { m_port_input[PORT_A] &= ~(1 << 2); m_port_input[PORT_A] |= (state << 2); }
-WRITE_LINE_MEMBER(st6228_device::porta3_w) { m_port_input[PORT_A] &= ~(1 << 3); m_port_input[PORT_A] |= (state << 3); }
-WRITE_LINE_MEMBER(st6228_device::porta4_w) { m_port_input[PORT_A] &= ~(1 << 4); m_port_input[PORT_A] |= (state << 4); }
-WRITE_LINE_MEMBER(st6228_device::porta5_w) { m_port_input[PORT_A] &= ~(1 << 5); m_port_input[PORT_A] |= (state << 5); }
-
-WRITE_LINE_MEMBER(st6228_device::portb4_w) { m_port_input[PORT_B] &= ~(1 << 4); m_port_input[PORT_B] |= (state << 4); }
-WRITE_LINE_MEMBER(st6228_device::portb5_w) { m_port_input[PORT_B] &= ~(1 << 5); m_port_input[PORT_B] |= (state << 5); }
-WRITE_LINE_MEMBER(st6228_device::portb6_w) { m_port_input[PORT_B] &= ~(1 << 6); m_port_input[PORT_B] |= (state << 6); }
-
-WRITE_LINE_MEMBER(st6228_device::portc4_w) { m_port_input[PORT_C] &= ~(1 << 4); m_port_input[PORT_C] |= (state << 4); }
-WRITE_LINE_MEMBER(st6228_device::portc5_w) { m_port_input[PORT_C] &= ~(1 << 5); m_port_input[PORT_C] |= (state << 5); }
-WRITE_LINE_MEMBER(st6228_device::portc6_w) { m_port_input[PORT_C] &= ~(1 << 6); m_port_input[PORT_C] |= (state << 6); }
-WRITE_LINE_MEMBER(st6228_device::portc7_w) { m_port_input[PORT_C] &= ~(1 << 7); m_port_input[PORT_C] |= (state << 7); }
-
-WRITE_LINE_MEMBER(st6228_device::portd1_w) { m_port_input[PORT_D] &= ~(1 << 1); m_port_input[PORT_D] |= (state << 1); }
-WRITE_LINE_MEMBER(st6228_device::portd2_w) { m_port_input[PORT_D] &= ~(1 << 2); m_port_input[PORT_D] |= (state << 2); }
-WRITE_LINE_MEMBER(st6228_device::portd3_w) { m_port_input[PORT_D] &= ~(1 << 3); m_port_input[PORT_D] |= (state << 3); }
-WRITE_LINE_MEMBER(st6228_device::portd4_w) { m_port_input[PORT_D] &= ~(1 << 4); m_port_input[PORT_D] |= (state << 4); }
-WRITE_LINE_MEMBER(st6228_device::portd5_w) { m_port_input[PORT_D] &= ~(1 << 5); m_port_input[PORT_D] |= (state << 5); }
-WRITE_LINE_MEMBER(st6228_device::portd6_w) { m_port_input[PORT_D] &= ~(1 << 6); m_port_input[PORT_D] |= (state << 6); }
-WRITE_LINE_MEMBER(st6228_device::portd7_w) { m_port_input[PORT_D] &= ~(1 << 7); m_port_input[PORT_D] |= (state << 7); }
-
-void st6228_device::set_port_output_bit(uint8_t index, uint8_t bit, uint8_t state)
+void st6228_device::porta0_w(int state) { m_port_input[PORT_A] &= ~(1 << 0); m_port_input[PORT_A] |= (state << 0); }
+void st6228_device::porta1_w(int state) { m_port_input[PORT_A] &= ~(1 << 1); m_port_input[PORT_A] |= (state << 1); }
+void st6228_device::porta2_w(int state) { m_port_input[PORT_A] &= ~(1 << 2); m_port_input[PORT_A] |= (state << 2); }
+void st6228_device::porta3_w(int state) { m_port_input[PORT_A] &= ~(1 << 3); m_port_input[PORT_A] |= (state << 3); }
+void st6228_device::porta4_w(int state) { m_port_input[PORT_A] &= ~(1 << 4); m_port_input[PORT_A] |= (state << 4); }
+void st6228_device::porta5_w(int state) { m_port_input[PORT_A] &= ~(1 << 5); m_port_input[PORT_A] |= (state << 5); }
+
+void st6228_device::portb4_w(int state) { m_port_input[PORT_B] &= ~(1 << 4); m_port_input[PORT_B] |= (state << 4); }
+void st6228_device::portb5_w(int state) { m_port_input[PORT_B] &= ~(1 << 5); m_port_input[PORT_B] |= (state << 5); }
+void st6228_device::portb6_w(int state) { m_port_input[PORT_B] &= ~(1 << 6); m_port_input[PORT_B] |= (state << 6); }
+
+void st6228_device::portc4_w(int state) { m_port_input[PORT_C] &= ~(1 << 4); m_port_input[PORT_C] |= (state << 4); }
+void st6228_device::portc5_w(int state) { m_port_input[PORT_C] &= ~(1 << 5); m_port_input[PORT_C] |= (state << 5); }
+void st6228_device::portc6_w(int state) { m_port_input[PORT_C] &= ~(1 << 6); m_port_input[PORT_C] |= (state << 6); }
+void st6228_device::portc7_w(int state) { m_port_input[PORT_C] &= ~(1 << 7); m_port_input[PORT_C] |= (state << 7); }
+
+void st6228_device::portd1_w(int state) { m_port_input[PORT_D] &= ~(1 << 1); m_port_input[PORT_D] |= (state << 1); }
+void st6228_device::portd2_w(int state) { m_port_input[PORT_D] &= ~(1 << 2); m_port_input[PORT_D] |= (state << 2); }
+void st6228_device::portd3_w(int state) { m_port_input[PORT_D] &= ~(1 << 3); m_port_input[PORT_D] |= (state << 3); }
+void st6228_device::portd4_w(int state) { m_port_input[PORT_D] &= ~(1 << 4); m_port_input[PORT_D] |= (state << 4); }
+void st6228_device::portd5_w(int state) { m_port_input[PORT_D] &= ~(1 << 5); m_port_input[PORT_D] |= (state << 5); }
+void st6228_device::portd6_w(int state) { m_port_input[PORT_D] &= ~(1 << 6); m_port_input[PORT_D] |= (state << 6); }
+void st6228_device::portd7_w(int state) { m_port_input[PORT_D] &= ~(1 << 7); m_port_input[PORT_D] |= (state << 7); }
+
+void st6228_device::gpio_set_output_bit(uint8_t index, uint8_t bit, uint8_t state)
{
switch (index)
{
@@ -213,7 +240,7 @@ void st6228_device::set_port_output_bit(uint8_t index, uint8_t bit, uint8_t stat
}
}
-void st6228_device::update_port_mode(uint8_t index, uint8_t changed)
+void st6228_device::gpio_update_mode(uint8_t index, uint8_t changed)
{
const uint8_t dir = m_port_dir[index];
const uint8_t option = m_port_option[index];
@@ -252,182 +279,210 @@ void st6228_device::update_port_mode(uint8_t index, uint8_t changed)
}
}
-void st6228_device::regs_w(offs_t offset, uint8_t data)
+void st6228_device::unimplemented_reg_w(offs_t offset, uint8_t data)
{
- offset += 0x80;
+ LOGMASKED(LOG_UNIMPL, "%s: unimplemented_reg_w: Unimplemented write: %02x = %02x\n", machine().describe_context(), offset + 0xc0, data);
+}
- if (offset > REG_W && offset < REG_PORTA_DATA)
- {
- // Data RAM
- m_regs[offset] = data;
- return;
- }
+uint8_t st6228_device::unimplemented_reg_r(offs_t offset)
+{
+ LOGMASKED(LOG_UNIMPL, "%s: unimplemented_reg_r: Unimplemented read: %02x\n", machine().describe_context(), offset + 0xc0);
+ return 0;
+}
- static char PORT_NAMES[4] = { 'A', 'B', 'C', 'D' };
+void st6228_device::data_rom_window_w(offs_t offset, uint8_t data)
+{
+ m_regs[REG_DATA_ROM_WINDOW] = data;
+ m_data_rom_bank->set_entry(data & 0x7f);
+}
- switch (offset)
- {
- case REG_X:
- case REG_Y:
- case REG_V:
- case REG_W:
- case REG_A:
- m_regs[offset] = data;
- break;
+void st6228_device::rom_bank_select_w(offs_t offset, uint8_t data)
+{
+ m_regs[REG_ROM_BANK_SELECT] = data;
+ m_program_rom_bank->set_entry(data & 3);
+}
- case REG_DATA_ROM_WINDOW:
- m_regs[offset] = data;
- m_data_rombank->set_entry(data & 0x7f);
- break;
+void st6228_device::ram_bank_select_w(offs_t offset, uint8_t data)
+{
+ m_regs[REG_RAM_BANK_SELECT] = data;
+ m_ram_bank->set_entry(data & 1);
+}
- case REG_ROM_BANK_SELECT:
- m_regs[offset] = data;
- m_program_rombank->set_entry(data & 3);
- break;
+void st6228_device::gpio_data_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_GPIO, "%s: gpio_data_w: Port %c Data = %02x\n", machine().describe_context(), offset + 'A', data);
+ const uint8_t old_data = m_port_data[offset];
+ const uint8_t changed = old_data ^ data;
- case REG_RAM_BANK_SELECT:
- m_regs[offset] = data;
- m_rambank->set_entry(data & 1);
- break;
+ m_port_data[offset] = data;
+ gpio_update_mode(offset, changed);
- case REG_PORTA_DATA:
- case REG_PORTB_DATA:
- case REG_PORTC_DATA:
- case REG_PORTD_DATA:
+ if (changed & m_port_dir[offset])
+ {
+ for (uint8_t bit = 0; bit < 8; bit++)
{
- const uint8_t index = offset - REG_PORTA_DATA;
- logerror("%s: Port %c data = %02x\n", machine().describe_context(), PORT_NAMES[index], data);
- const uint8_t old_data = m_port_data[index];
- const uint8_t changed = old_data ^ data;
+ if (BIT(changed, bit))
+ gpio_set_output_bit(offset, bit, BIT(data, bit));
+ }
+ }
+}
+
+void st6228_device::gpio_dir_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_GPIO, "%s: gpio_dir_w: Port %c Direction = %02x\n", machine().describe_context(), offset + 'A', data);
+ const uint8_t old_dir = m_port_dir[offset];
+ const uint8_t changed = old_dir ^ data;
- m_port_data[index] = data;
- update_port_mode(index, changed);
+ m_port_dir[offset] = data;
+ gpio_update_mode(offset, changed);
- if (changed & m_port_dir[index])
+ if (changed)
+ {
+ for (uint8_t bit = 0; bit < 8; bit++)
+ {
+ if (BIT(changed, bit))
{
- for (uint8_t bit = 0; bit < 8; bit++)
- {
- if (BIT(changed, bit))
- set_port_output_bit(index, bit, BIT(data, bit));
- }
+ gpio_set_output_bit(offset, bit, BIT(m_port_data[offset], bit));
}
- break;
}
+ }
+}
- case REG_PORTA_DIR:
- case REG_PORTB_DIR:
- case REG_PORTC_DIR:
- case REG_PORTD_DIR:
- {
- const uint8_t index = offset - REG_PORTA_DIR;
- logerror("%s: Port %c dir = %02x\n", machine().describe_context(), PORT_NAMES[index], data);
- const uint8_t old_dir = m_port_dir[index];
- const uint8_t changed = old_dir ^ data;
+void st6228_device::gpio_option_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_GPIO, "%s: gpio_option_w: Port %c Option = %02x\n", machine().describe_context(), offset + 'A', data);
- m_port_dir[index] = data;
- update_port_mode(index, changed);
+ const uint8_t changed = m_port_option[offset] ^ data;
+ m_port_option[offset] = data;
- if (changed)
- {
- for (uint8_t bit = 0; bit < 8; bit++)
- {
- if (BIT(changed, bit))
- {
- set_port_output_bit(index, bit, BIT(m_port_data[index], bit));
- }
- }
- }
- break;
- }
+ gpio_update_mode(offset, changed);
+}
- case REG_PORTA_OPTION:
- case REG_PORTB_OPTION:
- case REG_PORTC_OPTION:
- case REG_PORTD_OPTION:
- {
- const uint8_t index = offset - REG_PORTA_OPTION;
- logerror("%s: Port %c option = %02x\n", machine().describe_context(), PORT_NAMES[index], data);
+void st6228_device::watchdog_w(offs_t offset, uint8_t data)
+{
+ // FIXME: Not yet implemented.
+}
- const uint8_t changed = m_port_option[index] ^ data;
- m_port_option[index] = data;
+uint8_t st6228_device::gpio_data_r(offs_t offset)
+{
+ const uint8_t data = (m_port_data[offset] & m_port_dir[offset]) |
+ (m_port_input[offset] & ~m_port_dir[offset]) |
+ (m_port_pullup[offset] & ~m_port_dir[offset]);
+ LOGMASKED(LOG_GPIO, "%s: gpio_data_r: Port %c Data: %02x\n", machine().describe_context(), offset + 'A', data);
+ return data;
+}
- update_port_mode(index, changed);
- break;
+uint8_t st6228_device::gpio_dir_r(offs_t offset)
+{
+ const uint8_t data = m_port_dir[offset];
+ LOGMASKED(LOG_GPIO, "%s: gpio_dir_r: Port %c Direction: %02x\n", machine().describe_context(), offset + 'A', data);
+ return data;
+}
+
+uint8_t st6228_device::gpio_option_r(offs_t offset)
+{
+ const uint8_t data = m_port_option[offset];
+ LOGMASKED(LOG_GPIO, "%s: gpio_option_r: Port %c Option: %02x\n", machine().describe_context(), offset + 'A', data);
+ return data;
+}
+
+void st6228_device::timer_w(int state)
+{
+ const int old = m_timer_pin;
+ m_timer_pin = state;
+ if (old != m_timer_pin && m_timer_pin) // Rising Edge
+ {
+ if ((m_regs[REG_TIMER_CONTROL] & TSCR_MODE_MASK) == TSCR_MODE_EVENT) // Event-Counter mode
+ {
+ timer_prescaler_tick();
}
+ }
+}
- case REG_WATCHDOG:
- // Do nothing for now
- break;
+void st6228_device::timer_counter_tick()
+{
+ m_regs[REG_TIMER_COUNT]--;
+ if (m_regs[REG_TIMER_COUNT])
+ {
+ m_regs[REG_TIMER_CONTROL] &= ~(1 << TSCR_TMZ_BIT);
+ }
+ else
+ {
+ m_regs[REG_TIMER_CONTROL] |= (1 << TSCR_TMZ_BIT);
+ const uint8_t control = m_regs[REG_TIMER_CONTROL];
+ if (BIT(control, TSCR_ETI_BIT))
+ {
+ // TODO: Request interrupt
+ }
- default:
- logerror("%s: Unknown register write: %02x = %02x\n", machine().describe_context(), offset, data);
- break;
+ if (BIT(control, TSCR_TOUT_BIT))
+ m_timer_out(BIT(control, TSCR_DOUT_BIT));
}
}
-uint8_t st6228_device::regs_r(offs_t offset)
+void st6228_device::timer_prescaler_tick()
{
- uint8_t ret = 0;
- offset += 0x80;
+ const uint8_t old_prescaler = m_regs[REG_TIMER_PRESCALE];
+ m_regs[REG_TIMER_PRESCALE]--;
+ const uint8_t prescaler_rising = ~old_prescaler & m_regs[REG_TIMER_PRESCALE];
+
+ const uint8_t timer_ctrl = m_regs[REG_TIMER_CONTROL];
- if (offset > REG_W && offset < REG_PORTA_DATA)
+ const uint8_t prescaler_divider = (timer_ctrl & TSCR_PS_MASK) >> TSCR_PS_BIT;
+ if (prescaler_divider == 0 || BIT(prescaler_rising, prescaler_divider - 1))
{
- // Data RAM
- return m_regs[offset];
+ timer_counter_tick();
}
+}
- static char PORT_NAMES[4] = { 'A', 'B', 'C', 'D' };
+void st6228_device::timer_prescale_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_TIMER, "%s: timer_prescale_w: Timer Prescale = %02x\n", machine().describe_context(), data);
+ m_regs[REG_TIMER_PRESCALE] = data;
+}
- switch (offset)
+void st6228_device::timer_counter_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_TIMER, "%s: timer_counter_w: Timer Count = %02x\n", machine().describe_context(), data);
+ m_regs[REG_TIMER_COUNT] = data;
+}
+
+void st6228_device::timer_control_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_TIMER, "%s: timer_control_w: Timer Control = %02x\n", machine().describe_context(), data);
+ m_regs[REG_TIMER_CONTROL] = data;
+ if (BIT(data, TSCR_ETI_BIT) && BIT(data, TSCR_TMZ_BIT))
{
- case REG_X:
- case REG_Y:
- case REG_V:
- case REG_W:
- case REG_A:
- ret = m_regs[offset];
- break;
+ // TODO: Request interrupt
+ }
+ else
+ {
+ // TODO: Clear interrupt
+ }
- case REG_PORTA_DATA:
- case REG_PORTB_DATA:
- case REG_PORTC_DATA:
- case REG_PORTD_DATA:
- {
- const uint8_t index = offset - REG_PORTA_DATA;
- ret = (m_port_data[index] & m_port_dir[index]) |
- (m_port_input[index] & ~m_port_dir[index]) |
- (m_port_pullup[index] & ~m_port_dir[index]);
- logerror("%s: Port %c data read (%02x)\n", machine().describe_context(), PORT_NAMES[index], ret);
- break;
- }
+ const bool active_mode = (BIT(data, TSCR_TOUT_BIT) || (BIT(data, TSCR_DOUT_BIT) && m_timer_pin));
+ m_timer_active = BIT(data, TSCR_PSI_BIT) && active_mode;
+}
- case REG_PORTA_DIR:
- case REG_PORTB_DIR:
- case REG_PORTC_DIR:
- case REG_PORTD_DIR:
- {
- const uint8_t index = offset - REG_PORTA_DIR;
- ret = m_port_dir[index];
- logerror("%s: Port %c direction read (%02x)\n", machine().describe_context(), PORT_NAMES[index], ret);
- break;
- }
+uint8_t st6228_device::timer_prescale_r(offs_t offset)
+{
+ const uint8_t data = m_regs[REG_TIMER_PRESCALE];
+ LOGMASKED(LOG_TIMER, "%s: timer_prescale_r: Timer Prescale: %02x\n", machine().describe_context(), data);
+ return data;
+}
- case REG_PORTA_OPTION:
- case REG_PORTB_OPTION:
- case REG_PORTC_OPTION:
- case REG_PORTD_OPTION:
- {
- const uint8_t index = offset - REG_PORTA_OPTION;
- ret = m_port_option[index];
- logerror("%s: Port %c option read (%02x)\n", machine().describe_context(), PORT_NAMES[index], ret);
- break;
- }
+uint8_t st6228_device::timer_counter_r(offs_t offset)
+{
+ const uint8_t data = m_regs[REG_TIMER_COUNT];
+ LOGMASKED(LOG_TIMER, "%s: timer_counter_r: Timer Count: %02x\n", machine().describe_context(), data);
+ return data;
+}
- default:
- logerror("%s: Unknown register read: %02x\n", machine().describe_context(), offset);
- break;
- }
- return ret;
+uint8_t st6228_device::timer_status_r(offs_t offset)
+{
+ const uint8_t data = m_regs[REG_TIMER_CONTROL];
+ LOGMASKED(LOG_TIMER, "%s: timer_status_r: Timer Status: %02x\n", machine().describe_context(), data);
+ return data;
}
uint32_t st6228_device::execute_min_cycles() const noexcept
@@ -450,10 +505,6 @@ void st6228_device::execute_set_input(int inputnum, int state)
logerror("%s: Unimplemented: execute_set_input line %d = %d\n", machine().describe_context(), inputnum, state);
}
-void st6228_device::tick_timers(int cycles)
-{
-}
-
void st6228_device::unimplemented_opcode(uint8_t op)
{
fatalerror("ST62xx: unknown opcode (%02x) at %04x\n", op, m_pc);
@@ -695,7 +746,7 @@ void st6228_device::execute_run()
}
else
{
- fatalerror("Attempted to RETI with nothing on the stack");
+ m_mode = MODE_NORMAL;
}
break;
case 0x5d: // DEC Y
@@ -981,7 +1032,7 @@ void st6228_device::execute_run()
{
m_regs[REG_A] = m_data->read_byte(m_program->read_byte(m_pc+1));
- if (m_regs[REG_V])
+ if (m_regs[REG_A])
m_flags[m_mode] &= ~FLAG_Z;
else
m_flags[m_mode] |= FLAG_Z;
@@ -1104,7 +1155,7 @@ void st6228_device::execute_run()
break;
case 0x9f: // LD rr,A
{
- m_regs[REG_A] = m_data->read_byte(m_program->read_byte(m_pc+1));
+ m_data->write_byte(m_program->read_byte(m_pc+1), m_regs[REG_A]);
if (m_regs[REG_A])
m_flags[m_mode] &= ~FLAG_Z;
@@ -1204,7 +1255,15 @@ void st6228_device::execute_run()
m_pc++;
- tick_timers(cycles);
+ if (m_timer_active)
+ {
+ m_timer_divider -= cycles;
+ if (m_timer_divider <= 0)
+ {
+ m_timer_divider += 12;
+ timer_prescaler_tick();
+ }
+ }
m_icount -= cycles;
}