mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-08 18:55:14 +00:00
Attempts to add proper bus timing.
This commit is contained in:
parent
ce66b5fd9c
commit
1fd19c5786
@ -147,8 +147,6 @@ class ConcreteMachine:
|
|||||||
// A null cycle leaves nothing else to do.
|
// A null cycle leaves nothing else to do.
|
||||||
if(!(cycle.operation & (Microcycle::NewAddress | Microcycle::SameAddress))) return HalfCycles(0);
|
if(!(cycle.operation & (Microcycle::NewAddress | Microcycle::SameAddress))) return HalfCycles(0);
|
||||||
|
|
||||||
/* TODO: DTack, bus error, VPA. */
|
|
||||||
|
|
||||||
// An interrupt acknowledge, perhaps?
|
// An interrupt acknowledge, perhaps?
|
||||||
if(cycle.operation & Microcycle::InterruptAcknowledge) {
|
if(cycle.operation & Microcycle::InterruptAcknowledge) {
|
||||||
// Current implementation: everything other than 6 (i.e. the MFP is autovectored.
|
// Current implementation: everything other than 6 (i.e. the MFP is autovectored.
|
||||||
@ -169,6 +167,20 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a new strobing of the address signal, test for bus error and pre-DTack delay.
|
||||||
|
HalfCycles delay(0);
|
||||||
|
if(cycle.operation & Microcycle::NewAddress) {
|
||||||
|
// DTack will be implicit; work out how long until that should be,
|
||||||
|
// and apply bus error constraints.
|
||||||
|
const int i_phase = bus_phase_.as<int>() & 7;
|
||||||
|
if(i_phase < 4) {
|
||||||
|
delay = HalfCycles(4 - i_phase);
|
||||||
|
advance_time(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: presumably test is if(after declared memory size and (not supervisor or before hardware space)) bus_error?
|
||||||
|
}
|
||||||
|
|
||||||
auto address = cycle.word_address();
|
auto address = cycle.word_address();
|
||||||
// if(cycle.data_select_active()) printf("%c %06x\n", (cycle.operation & Microcycle::Read) ? 'r' : 'w', *cycle.address & 0xffffff);
|
// if(cycle.data_select_active()) printf("%c %06x\n", (cycle.operation & Microcycle::Read) ? 'r' : 'w', *cycle.address & 0xffffff);
|
||||||
uint16_t *memory;
|
uint16_t *memory;
|
||||||
@ -205,7 +217,7 @@ class ConcreteMachine:
|
|||||||
cycle.value->halves.low = 0xff;
|
cycle.value->halves.low = 0xff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return HalfCycles(0);
|
return delay;
|
||||||
|
|
||||||
case BusDevice::IO:
|
case BusDevice::IO:
|
||||||
switch(address) {
|
switch(address) {
|
||||||
@ -226,7 +238,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
case 0x7fc400: /* PSG: write to select register, read to read register. */
|
case 0x7fc400: /* PSG: write to select register, read to read register. */
|
||||||
case 0x7fc401: /* PSG: write to write register. */
|
case 0x7fc401: /* PSG: write to write register. */
|
||||||
if(!cycle.data_select_active()) return HalfCycles(0);
|
if(!cycle.data_select_active()) return delay;
|
||||||
|
|
||||||
advance_time(HalfCycles(2));
|
advance_time(HalfCycles(2));
|
||||||
update_audio();
|
update_audio();
|
||||||
@ -244,7 +256,7 @@ class ConcreteMachine:
|
|||||||
ay_.set_data_input(cycle.value8_high());
|
ay_.set_data_input(cycle.value8_high());
|
||||||
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
ay_.set_control_lines(GI::AY38910::ControlLines(0));
|
||||||
}
|
}
|
||||||
return HalfCycles(2);
|
return delay + HalfCycles(2);
|
||||||
|
|
||||||
// The MFP block:
|
// The MFP block:
|
||||||
case 0x7ffd00: case 0x7ffd01: case 0x7ffd02: case 0x7ffd03:
|
case 0x7ffd00: case 0x7ffd01: case 0x7ffd02: case 0x7ffd03:
|
||||||
@ -255,7 +267,7 @@ class ConcreteMachine:
|
|||||||
case 0x7ffd14: case 0x7ffd15: case 0x7ffd16: case 0x7ffd17:
|
case 0x7ffd14: case 0x7ffd15: case 0x7ffd16: case 0x7ffd17:
|
||||||
case 0x7ffd18: case 0x7ffd19: case 0x7ffd1a: case 0x7ffd1b:
|
case 0x7ffd18: case 0x7ffd19: case 0x7ffd1a: case 0x7ffd1b:
|
||||||
case 0x7ffd1c: case 0x7ffd1d: case 0x7ffd1e: case 0x7ffd1f:
|
case 0x7ffd1c: case 0x7ffd1d: case 0x7ffd1e: case 0x7ffd1f:
|
||||||
if(!cycle.data_select_active()) return HalfCycles(0);
|
if(!cycle.data_select_active()) return delay;
|
||||||
|
|
||||||
if(cycle.operation & Microcycle::Read) {
|
if(cycle.operation & Microcycle::Read) {
|
||||||
cycle.set_value8_low(mfp_->read(int(address)));
|
cycle.set_value8_low(mfp_->read(int(address)));
|
||||||
@ -278,7 +290,7 @@ class ConcreteMachine:
|
|||||||
case 0x7fc128: case 0x7fc129: case 0x7fc12a: case 0x7fc12b:
|
case 0x7fc128: case 0x7fc129: case 0x7fc12a: case 0x7fc12b:
|
||||||
case 0x7fc12c: case 0x7fc12d: case 0x7fc12e: case 0x7fc12f:
|
case 0x7fc12c: case 0x7fc12d: case 0x7fc12e: case 0x7fc12f:
|
||||||
case 0x7fc130: case 0x7fc131:
|
case 0x7fc130: case 0x7fc131:
|
||||||
if(!cycle.data_select_active()) return HalfCycles(0);
|
if(!cycle.data_select_active()) return delay;
|
||||||
|
|
||||||
if(cycle.operation & Microcycle::Read) {
|
if(cycle.operation & Microcycle::Read) {
|
||||||
cycle.set_value16(video_->read(int(address)));
|
cycle.set_value16(video_->read(int(address)));
|
||||||
@ -291,7 +303,7 @@ class ConcreteMachine:
|
|||||||
case 0x7ffe00: case 0x7ffe01: case 0x7ffe02: case 0x7ffe03: {
|
case 0x7ffe00: case 0x7ffe01: case 0x7ffe02: case 0x7ffe03: {
|
||||||
// Set VPA.
|
// Set VPA.
|
||||||
mc68000_.set_is_peripheral_address(!cycle.data_select_active());
|
mc68000_.set_is_peripheral_address(!cycle.data_select_active());
|
||||||
if(!cycle.data_select_active()) return HalfCycles(0);
|
if(!cycle.data_select_active()) return delay;
|
||||||
|
|
||||||
const auto acia_ = (address < 0x7ffe02) ? &keyboard_acia_ : &midi_acia_;
|
const auto acia_ = (address < 0x7ffe02) ? &keyboard_acia_ : &midi_acia_;
|
||||||
if(cycle.operation & Microcycle::Read) {
|
if(cycle.operation & Microcycle::Read) {
|
||||||
@ -303,7 +315,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
// DMA.
|
// DMA.
|
||||||
case 0x7fc302: case 0x7fc303: case 0x7fc304: case 0x7fc305: case 0x7fc306:
|
case 0x7fc302: case 0x7fc303: case 0x7fc304: case 0x7fc305: case 0x7fc306:
|
||||||
if(!cycle.data_select_active()) return HalfCycles(0);
|
if(!cycle.data_select_active()) return delay;
|
||||||
|
|
||||||
if(cycle.operation & Microcycle::Read) {
|
if(cycle.operation & Microcycle::Read) {
|
||||||
cycle.set_value16(dma_->read(int(address)));
|
cycle.set_value16(dma_->read(int(address)));
|
||||||
@ -358,6 +370,7 @@ class ConcreteMachine:
|
|||||||
dma_ += length;
|
dma_ += length;
|
||||||
keyboard_acia_ += length;
|
keyboard_acia_ += length;
|
||||||
midi_acia_ += length;
|
midi_acia_ += length;
|
||||||
|
bus_phase_ += length;
|
||||||
|
|
||||||
// Don't even count time for the keyboard unless it has requested it.
|
// Don't even count time for the keyboard unless it has requested it.
|
||||||
if(keyboard_needs_clock_) {
|
if(keyboard_needs_clock_) {
|
||||||
@ -397,6 +410,8 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
|
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
|
||||||
|
HalfCycles bus_phase_;
|
||||||
|
|
||||||
JustInTimeActor<Video> video_;
|
JustInTimeActor<Video> video_;
|
||||||
HalfCycles cycles_until_video_event_;
|
HalfCycles cycles_until_video_event_;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user