1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Seeks to introduce MSX interrupts.

This commit is contained in:
Thomas Harte 2017-11-29 20:31:55 -05:00
parent 69ec8a362e
commit aa4eef41d8
3 changed files with 47 additions and 5 deletions

View File

@ -66,11 +66,15 @@ void TMS9918::run_for(const HalfCycles cycles) {
// PAL output is 313 lines total. NTSC output is 262 lines total.
// Interrupt is signalled upon entering the lower border.
// Keep a count of cycles separate from internal counts to avoid
// potential errors mapping back and forth.
half_cycles_into_frame_ = (half_cycles_into_frame_ + cycles) % HalfCycles(frame_lines_ * 228 * 2);
// Convert to 342 cycles per line; the internal clock is 1.5 times the
// nominal 3.579545 Mhz that I've advertised for this part.
int int_cycles = (cycles.as_int() * 3) + cycles_error_;
cycles_error_ = int_cycles & 3;
int_cycles >>= 2;
cycles_error_ = int_cycles & 7;
int_cycles >>= 3;
if(!int_cycles) return;
//
@ -296,3 +300,16 @@ uint8_t TMS9918::get_register(int address) {
void TMS9918::reevaluate_interrupts() {
}
HalfCycles TMS9918::get_time_until_interrupt() {
if(!generate_interrupts_) return HalfCycles(-1);
if(get_interrupt_line()) return HalfCycles(-1);
const int half_cycles_per_frame = frame_lines_ * 228 * 2;
int half_cycles_remaining = (192 * 228 * 2 + half_cycles_per_frame - half_cycles_into_frame_.as_int()) % half_cycles_per_frame;
return HalfCycles(half_cycles_remaining);
}
bool TMS9918::get_interrupt_line() {
return (status_ & 0x80) && generate_interrupts_;
}

View File

@ -44,6 +44,9 @@ class TMS9918 {
void set_register(int address, uint8_t value);
uint8_t get_register(int address);
HalfCycles get_time_until_interrupt();
bool get_interrupt_line();
private:
std::shared_ptr<Outputs::CRT::CRT> crt_;
@ -73,6 +76,7 @@ class TMS9918 {
void reevaluate_interrupts();
HalfCycles half_cycles_into_frame_;
int column_ = 0, row_ = 0, output_column_ = 0;
int cycles_error_ = 0;
uint32_t *pixel_target_ = nullptr;
@ -93,7 +97,7 @@ class TMS9918 {
uint8_t pattern_buffer_[40];
uint8_t colour_buffer_[32];
int access_pointer_ = 0;
uint8_t pattern_name_;
uint8_t pattern_name_ = 0;
};
};

View File

@ -20,7 +20,15 @@
namespace MSX {
class AYPortHandler: public GI::AY38910::PortHandler {
struct AYPortHandler: public GI::AY38910::PortHandler {
void set_port_output(bool port_b, uint8_t value) {
printf("AY port %c output: %02x\n", port_b ? 'b' : 'a', value);
}
uint8_t get_port_input(bool port_b) {
printf("AY port %c input\n", port_b ? 'b' : 'a');
return 0xff;
}
};
class ConcreteMachine:
@ -65,6 +73,7 @@ class ConcreteMachine:
}
void page_memory(uint8_t value) {
printf("Page %02x\n", value);
for(int c = 0; c < 4; ++c) {
read_pointers_[c] = unpopulated_;
write_pointers_[c] = scratch_;
@ -87,6 +96,13 @@ class ConcreteMachine:
}
HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
if(time_until_interrupt_ > 0) {
time_until_interrupt_ -= cycle.length;
if(time_until_interrupt_ <= HalfCycles(0)) {
z80_.set_interrupt_line(true, time_until_interrupt_);
}
}
uint16_t address = cycle.address ? *cycle.address : 0x0000;
switch(cycle.operation) {
case CPU::Z80::PartialMachineCycle::ReadOpcode:
@ -104,6 +120,8 @@ class ConcreteMachine:
vdp_->run_for(time_since_vdp_update_);
time_since_vdp_update_ = 0;
*cycle.value = vdp_->get_register(address);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
case 0xa2:
@ -124,6 +142,8 @@ class ConcreteMachine:
vdp_->run_for(time_since_vdp_update_);
time_since_vdp_update_ = 0;
vdp_->set_register(address, *cycle.value);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
case 0xa0:
@ -205,7 +225,7 @@ class ConcreteMachine:
uint8_t get_value(int port) {
if(port == 1) {
printf("?? Read keyboard\n");
}
} else printf("What what?\n");
return 0xff;
}
@ -229,6 +249,7 @@ class ConcreteMachine:
std::vector<uint8_t> basic_, main_;
HalfCycles time_since_vdp_update_;
HalfCycles time_until_interrupt_;
};
}