Added a preliminary support for Arduino UNO booting by avr8 (#6624)

-avr8.cpp: Added ATMega328 support. [hiromasa]
* Fixed m_pc to be initialized correctly when in the boot loader section.
* Fixed bootloader size based on BOOTSZ specification.
This commit is contained in:
hiromasa 2020-05-02 23:29:37 +09:00 committed by GitHub
parent 843080adb9
commit ce4a3a8051
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 5 deletions

View File

@ -593,6 +593,7 @@ static const char avr8_reg_name[4] = { 'A', 'B', 'C', 'D' };
//**************************************************************************
DEFINE_DEVICE_TYPE(ATMEGA88, atmega88_device, "atmega88", "Atmel ATmega88")
DEFINE_DEVICE_TYPE(ATMEGA328, atmega328_device, "atmega328", "Atmel ATmega328")
DEFINE_DEVICE_TYPE(ATMEGA644, atmega644_device, "atmega644", "Atmel ATmega644")
DEFINE_DEVICE_TYPE(ATMEGA1280, atmega1280_device, "atmega1280", "Atmel ATmega1280")
DEFINE_DEVICE_TYPE(ATMEGA2560, atmega2560_device, "atmega2560", "Atmel ATmega2560")
@ -607,6 +608,11 @@ void atmega88_device::atmega88_internal_map(address_map &map)
map(0x0000, 0x00ff).rw(FUNC(atmega88_device::regs_r), FUNC(atmega88_device::regs_w));
}
void atmega328_device::atmega328_internal_map(address_map &map)
{
map(0x0000, 0x00ff).rw(FUNC(atmega328_device::regs_r), FUNC(atmega328_device::regs_w));
}
void atmega644_device::atmega644_internal_map(address_map &map)
{
map(0x0000, 0x00ff).rw(FUNC(atmega644_device::regs_r), FUNC(atmega644_device::regs_w));
@ -636,6 +642,15 @@ atmega88_device::atmega88_device(const machine_config &mconfig, const char *tag,
{
}
//-------------------------------------------------
// atmega328_device - constructor
//-------------------------------------------------
atmega328_device::atmega328_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: avr8_device(mconfig, tag, owner, clock, ATMEGA328, 0x7fff, address_map_constructor(FUNC(atmega328_device::atmega328_internal_map), this), 3)
{
}
//-------------------------------------------------
// atmega644_device - constructor
//-------------------------------------------------
@ -888,11 +903,28 @@ void avr8_device::device_reset()
switch ((m_hfuses & (BOOTSZ1 | BOOTSZ0)) >> 1)
{
case 0: m_boot_size = 4096; break;
case 1: m_boot_size = 2048; break;
case 2: m_boot_size = 1024; break;
case 3: m_boot_size = 512; break;
default: break;
case 0:
if (m_addr_mask <= 0x0fff) { m_boot_size = 1024; }
else if (m_addr_mask <= 0x7fff) { m_boot_size = 2048; }
else { m_boot_size = 4096; }
break;
case 1:
if (m_addr_mask <= 0x0fff) { m_boot_size = 512; }
else if (m_addr_mask <= 0x7fff) { m_boot_size = 1024; }
else { m_boot_size = 2048; }
break;
case 2:
if (m_addr_mask <= 0x0fff) { m_boot_size = 256; }
else if (m_addr_mask <= 0x7fff) { m_boot_size = 512; }
else { m_boot_size = 1024; }
break;
case 3:
if (m_addr_mask <= 0x0fff) { m_boot_size = 128; }
else if (m_addr_mask <= 0x7fff) { m_boot_size = 256; }
else { m_boot_size = 512; }
break;
default:
break;
}
if (m_hfuses & BOOTRST)
@ -901,6 +933,7 @@ void avr8_device::device_reset()
LOGMASKED(LOG_BOOT, "Booting AVR core from address 0x0000\n");
} else {
m_shifted_pc = (m_addr_mask + 1) - 2*m_boot_size;
m_pc = m_shifted_pc >> 1;
LOGMASKED(LOG_BOOT, "AVR Boot loader section size: %d words\n", m_boot_size);
}
@ -1066,6 +1099,21 @@ void avr8_device::update_interrupt(int source)
}
}
void atmega328_device::update_interrupt(int source)
{
const CInterruptCondition &condition = s_int_conditions[source];
int intstate = 0;
if (m_r[condition.m_intreg] & condition.m_intmask)
intstate = (m_r[condition.m_regindex] & condition.m_regmask) ? 1 : 0;
set_irq_line(condition.m_intindex << 1, intstate);
if (intstate)
{
m_r[condition.m_regindex] &= ~condition.m_regmask;
}
}
static const CInterruptCondition s_mega644_int_conditions[AVR8_INTIDX_COUNT] =
{

View File

@ -330,6 +330,7 @@ protected:
// device type definition
DECLARE_DEVICE_TYPE(ATMEGA88, atmega88_device)
DECLARE_DEVICE_TYPE(ATMEGA328, atmega328_device)
DECLARE_DEVICE_TYPE(ATMEGA644, atmega644_device)
DECLARE_DEVICE_TYPE(ATMEGA1280, atmega1280_device)
DECLARE_DEVICE_TYPE(ATMEGA2560, atmega2560_device)
@ -345,6 +346,18 @@ public:
void atmega88_internal_map(address_map &map);
};
// ======================> atmega328_device
class atmega328_device : public avr8_device
{
public:
// construction/destruction
atmega328_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void update_interrupt(int source) override;
void atmega328_internal_map(address_map &map);
};
// ======================> atmega644_device
class atmega644_device : public avr8_device