Skip to content

Commit

Permalink
Interrupts
Browse files Browse the repository at this point in the history
  • Loading branch information
drhelius committed Jul 20, 2024
1 parent 19079ad commit 2008ea8
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 81 deletions.
22 changes: 11 additions & 11 deletions platforms/shared/desktop/gui_debug_huc6280.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void gui_debug_window_huc6280(void)
HuC6280* processor = core->GetHuC6280();
HuC6280::Processor_State* proc_state = processor->GetState();
Memory* memory = core->GetMemory();
Input* input = core->GetInput();

if (ImGui::BeginTable("huc6280", 1, ImGuiTableFlags_BordersInnerH))
{
Expand Down Expand Up @@ -131,8 +132,8 @@ void gui_debug_window_huc6280(void)

ImGui::TableNextColumn();
ImGui::TextColored(red, "I/O "); ImGui::SameLine();
ImGui::Text(" $%02X", proc_state->A->GetValue());
ImGui::Text(BYTE_TO_BINARY_PATTERN_SPACED, BYTE_TO_BINARY(proc_state->A->GetValue()));
ImGui::Text(" $%02X", input->GetIORegister());
ImGui::Text(BYTE_TO_BINARY_PATTERN_SPACED, BYTE_TO_BINARY(input->GetIORegister()));

ImGui::TableNextColumn();
ImGui::TextColored(blue, "TIM "); ImGui::SameLine();
Expand All @@ -151,23 +152,24 @@ void gui_debug_window_huc6280(void)

ImGui::TableNextColumn();
ImGui::TextColored(magenta, "IDR "); ImGui::SameLine();
ImGui::Text(" $%02X", proc_state->A->GetValue());
ImGui::Text(BYTE_TO_BINARY_PATTERN_SPACED, BYTE_TO_BINARY(proc_state->A->GetValue()));
ImGui::Text(" $%02X", *proc_state->IDR);
ImGui::Text(BYTE_TO_BINARY_PATTERN_SPACED, BYTE_TO_BINARY(*proc_state->IDR));

ImGui::TableNextColumn();
ImGui::TextColored(magenta, "IRR "); ImGui::SameLine();
ImGui::Text(" $%02X", proc_state->A->GetValue());
ImGui::Text(BYTE_TO_BINARY_PATTERN_SPACED, BYTE_TO_BINARY(proc_state->A->GetValue()));
ImGui::Text(" $%02X", *proc_state->IRR);
ImGui::Text(BYTE_TO_BINARY_PATTERN_SPACED, BYTE_TO_BINARY(*proc_state->IRR));

ImGui::EndTable();
}

ImGui::PopStyleVar();

ImGui::TableNextColumn();
ImGui::TextColored(*proc_state->IRQ1 ? green : gray, " IRQ1"); ImGui::SameLine();
ImGui::TextColored(*proc_state->IRQ2 ? green : gray, " IRQ2"); ImGui::SameLine();
ImGui::TextColored(*proc_state->TIMER_IRQ ? green : gray, " TIQ ");
ImGui::TextColored(*proc_state->NMI ? green : gray, " NMI"); ImGui::SameLine();
ImGui::TextColored(*proc_state->TIMER_IRQ ? green : gray, "TIQ"); ImGui::SameLine();
ImGui::TextColored(*proc_state->IRQ1 ? green : gray, "IRQ1"); ImGui::SameLine();
ImGui::TextColored(*proc_state->IRQ2 ? green : gray, "IRQ2");

ImGui::TableNextColumn();
ImGui::TextColored(!*proc_state->SPEED ? green : gray, " 1.79 MHz"); ImGui::SameLine();
Expand All @@ -188,5 +190,3 @@ void gui_debug_window_huc6280(void)
ImGui::End();
ImGui::PopStyleVar();
}

#include "../../../src/geargrafx.h"
5 changes: 5 additions & 0 deletions src/geargrafx_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ Audio* GeargrafxCore::GetAudio()
return m_audio;
}

Input* GeargrafxCore::GetInput()
{
return m_input;
}

// Video* GeargrafxCore::GetVideo()
// {
// return m_video;
Expand Down
1 change: 1 addition & 0 deletions src/geargrafx_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class GeargrafxCore
Cartridge* GetCartridge();
HuC6280* GetHuC6280();
Audio* GetAudio();
Input* GetInput();
// HuC6270* GetHuC6270();

private:
Expand Down
48 changes: 29 additions & 19 deletions src/huc6280.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ HuC6280::HuC6280()
m_timer_counter = 0;
m_timer_reload = 0;
m_timer_irq = false;
m_interrupt_disable_register = 0;
m_interrupt_request_register = 0;
m_processor_state.A = &m_A;
m_processor_state.X = &m_X;
m_processor_state.Y = &m_Y;
Expand All @@ -51,6 +53,8 @@ HuC6280::HuC6280()
m_processor_state.IRQ1 = &m_irq1_asserted;
m_processor_state.IRQ2 = &m_irq2_asserted;
m_processor_state.NMI = &m_nmi_requested;
m_processor_state.IDR = &m_interrupt_disable_register;
m_processor_state.IRR = &m_interrupt_request_register;
}

HuC6280::~HuC6280()
Expand Down Expand Up @@ -86,6 +90,8 @@ void HuC6280::Reset()
m_timer_counter = 0;
m_timer_reload = 0;
m_timer_irq = false;
m_interrupt_disable_register = 0;
m_interrupt_request_register = 0;
}

unsigned int HuC6280::RunFor(unsigned int cycles)
Expand Down Expand Up @@ -115,26 +121,29 @@ unsigned int HuC6280::Tick()
irq_high = 0xFFFD;
m_nmi_requested = false;
}
// Timer
else if (m_timer_irq && !IsSetFlag(FLAG_INTERRUPT))
else if (!IsSetFlag(FLAG_INTERRUPT))
{
irq = true;
irq_low = 0xFFFA;
irq_high = 0xFFFB;
}
// IRQ1
else if (m_irq1_asserted && !IsSetFlag(FLAG_INTERRUPT))
{
irq = true;
irq_low = 0xFFF8;
irq_high = 0xFFF9;
}
// IRQ2
else if (m_irq2_asserted && !IsSetFlag(FLAG_INTERRUPT))
{
irq = true;
irq_low = 0xFFF6;
irq_high = 0xFFF7;
// TIQ
if (m_timer_irq && !IsSetBit(m_interrupt_disable_register, 2))
{
irq = true;
irq_low = 0xFFFA;
irq_high = 0xFFFB;
}
// IRQ1
else if (m_irq1_asserted && !IsSetBit(m_interrupt_disable_register, 1))
{
irq = true;
irq_low = 0xFFF8;
irq_high = 0xFFF9;
}
// IRQ2
else if (m_irq2_asserted && !IsSetBit(m_interrupt_disable_register, 0))
{
irq = true;
irq_low = 0xFFF6;
irq_high = 0xFFF7;
}
}

if (irq)
Expand Down Expand Up @@ -175,6 +184,7 @@ void HuC6280::TickTimer(unsigned int cycles)
{
m_timer_counter = m_timer_reload;
m_timer_irq = true;
SetBit(m_interrupt_request_register, 2);
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/huc6280.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class HuC6280
bool* IRQ1;
bool* IRQ2;
bool* NMI;
u8* IDR;
u8* IRR;
};

public:
Expand All @@ -68,11 +70,10 @@ class HuC6280
void RequestNMI();
void SetHighSpeed(bool high_speed);
bool IsHighSpeed();
u8 ReadTimerControl();
void WriteTimerControl(u8 value);
u8 ReadTimerCounter();
u8 ReadTimerReload();
void WriteTimerReload(u8 value);
u8 ReadInterruptRegister(u32 address);
void WriteInterruptRegister(u32 address, u8 value);
u8 ReadTimerRegister();
void WriteTimerRegister(u32 address, u8 value);
Processor_State* GetState();
void DisassembleNextOPCode();

Expand All @@ -97,6 +98,8 @@ class HuC6280
u8 m_timer_counter;
u8 m_timer_reload;
bool m_timer_irq;
u8 m_interrupt_disable_register;
u8 m_interrupt_request_register;

private:
u8 Fetch8();
Expand Down
62 changes: 47 additions & 15 deletions src/huc6280_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,65 @@ inline bool HuC6280::IsHighSpeed()
return m_high_speed;
}

inline u8 HuC6280::ReadTimerControl()
inline u8 HuC6280::ReadInterruptRegister(u32 address)
{
return m_timer_enabled ? 0x01 : 0x00;
}
inline void HuC6280::WriteTimerControl(u8 value)
{
bool enabled = (value &= 0x01);
if (!m_timer_enabled && enabled)
if (address == 0x1FF402)
{
return m_interrupt_disable_register;
}
else if (address == 0x1FF403)
{
return m_interrupt_request_register;
}
else
{
m_timer_counter = m_timer_reload;
Debug("Invalid interrupt register read at %06X", address);
return 0;
}
m_timer_enabled = enabled;
}

inline u8 HuC6280::ReadTimerCounter()
inline void HuC6280::WriteInterruptRegister(u32 address, u8 value)
{
return m_timer_counter;
if (address == 0x1FF402)
{
m_interrupt_disable_register = value & 0x07;
}
else if (address == 0x1FF403)
{
// Acknowledge TIQ
UnsetBit(m_interrupt_request_register, 2);
m_timer_irq = false;
}
else
{
Debug("Invalid interrupt register write at %06X, value=%02X", address, value);
}
}

inline u8 HuC6280::ReadTimerReload()
inline u8 HuC6280::ReadTimerRegister()
{
return m_timer_reload;
return m_timer_counter;
}

inline void HuC6280::WriteTimerReload(u8 value)
inline void HuC6280::WriteTimerRegister(u32 address, u8 value)
{
m_timer_reload = value & 0x7F;
if (address == 0x1FEC00)
{
m_timer_reload = value & 0x7F;
}
else if (address == 0x1FEC01)
{
bool enabled = (value & 0x01);
if (!m_timer_enabled && enabled)
{
m_timer_counter = m_timer_reload;
}
m_timer_enabled = enabled;
}
else
{
Debug("Invalid timer register write at %06X, value=%02X", address, value);
}
}

inline u8 HuC6280::Fetch8()
Expand Down
6 changes: 6 additions & 0 deletions src/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Input
void KeyReleased(GG_Controllers controller, GG_Keys key);
u8 ReadK();
void WriteO(u8 value);
u8 GetIORegister();
// void SaveState(std::ostream& stream);
// void LoadState(std::istream& stream);

Expand All @@ -49,4 +50,9 @@ inline void Input::WriteO(u8 value)

}

inline u8 Input::GetIORegister()
{
return 0;
}

#endif /* INPUT_H */
43 changes: 12 additions & 31 deletions src/memory_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,20 @@ inline u8 Memory::Read(u16 address)
case 0x0C00:
// Timer Counter
Debug("Timer Counter read at %06X", physical_address);
m_io_buffer = (m_huc6280->ReadTimerCounter() & 0x7F) | (m_io_buffer & 0x80);
m_io_buffer = (m_huc6280->ReadTimerRegister() & 0x7F) | (m_io_buffer & 0x80);
return m_io_buffer;
case 0x1000:
// I/O
Debug("I/O read at %06X", physical_address);
m_io_buffer = m_input->ReadK();
return m_io_buffer;
case 0x1400:
if (physical_address == 0x1FF402)
if (physical_address == 0x1FF402 || physical_address == 0x1FF403)
{
// Interrupt disable register
Debug("Interrupt disable read at %06X", physical_address);
return m_io_buffer & 0xF8;
}
else if (physical_address == 0x1FF403)
{
// Interrupt request register
Debug("Interrupt request read at %06X", physical_address);
return m_io_buffer & 0xF8;
// Interrupt registers
Debug("Interrupt register read at %06X", physical_address);
m_io_buffer = m_huc6280->ReadInterruptRegister(physical_address) & 0x07 | (m_io_buffer & 0xF8);
return m_io_buffer;
}
else
{
Expand Down Expand Up @@ -178,18 +173,8 @@ inline void Memory::Write(u16 address, u8 value)
break;
case 0x0C00:
// Timer
if (physical_address & 1)
{
// Timer Control
Debug("Timer Control write at %06X, value=%02X", physical_address, value);
m_huc6280->WriteTimerControl(value);
}
else
{
// Timer Reload
Debug("Timer Reload write at %06X, value=%02X", physical_address, value);
m_huc6280->WriteTimerReload(value);
}
Debug("Timer register write at %06X, value=%02X", physical_address, value);
m_huc6280->WriteTimerRegister(physical_address, value);
m_io_buffer = value;
break;
case 0x1000:
Expand All @@ -199,15 +184,11 @@ inline void Memory::Write(u16 address, u8 value)
m_io_buffer = value;
break;
case 0x1400:
if (physical_address == 0x1FF402)
{
// Interrupt disable register
Debug("Interrupt disable write at %06X, value=%02X", physical_address, value);
}
else if (physical_address == 0x1FF403)
if (physical_address == 0x1FF402 || physical_address == 0x1FF403)
{
// Interrupt request register
Debug("Interrupt request write at %06X, value=%02X", physical_address, value);
// Interrupt registers
Debug("Interrupt register write at %06X, value=%02X", physical_address, value);
m_huc6280->WriteInterruptRegister(physical_address, value);
}
else
{
Expand Down

0 comments on commit 2008ea8

Please sign in to comment.