Attempt high-level version of Loriciels loader.
This commit is contained in:
1 parent
6bd497d9d0
commit
d8d8d00985
7 files changed
+70
-16
No files matched your search
@@ -893,7 +893,7 @@ public:
|
||||
|
||||
// TODO (in the player, not here): adapt it to accept an input clock rate and
|
||||
// run_for as HalfCycles.
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(cycle.length.get());
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(cycle.length.reduce<Cycles>());
|
||||
|
||||
// Pump the AY.
|
||||
ay_.run_for(cycle.length);
|
||||
|
||||
@@ -773,8 +773,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if(!tape_player_is_sleeping_)
|
||||
tape_player_.run_for(cycle.length.as<int>());
|
||||
if(!tape_player_is_sleeping_) {
|
||||
tape_player_.run_for(cycle.length.reduce<Cycles>());
|
||||
}
|
||||
|
||||
return addition;
|
||||
}
|
||||
|
||||
@@ -621,7 +621,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void advance(HalfCycles duration) {
|
||||
void advance(const HalfCycles duration) {
|
||||
time_since_audio_update_ += duration;
|
||||
|
||||
video_ += duration;
|
||||
@@ -629,7 +629,7 @@ private:
|
||||
z80_.set_interrupt_line(video_.last_valid()->get_interrupt_line(), video_.last_sequence_point_overrun());
|
||||
}
|
||||
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(duration.get());
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(Cycles(duration.get()));
|
||||
|
||||
// Update automatic tape motor control, if enabled; if it's been
|
||||
// 0.5 seconds since software last possibly polled the tape, stop it.
|
||||
|
||||
@@ -18,14 +18,14 @@ namespace Thomson::FastLoader {
|
||||
|
||||
Sampling code is:
|
||||
|
||||
Z35CA LDA ,U ;35CA: A6 C4 '..'
|
||||
Z35CA LDA ,U ;35CA: A6 C4 '..'
|
||||
LSRA ;35CC: 44 'D'
|
||||
STA ,-S ;35CD: A7 E2 '..'
|
||||
STA ,S ;35CF: A7 E4 '..'
|
||||
STA ,S ;35CF: A7 E4 '..' ; [S], [S+1] = tape in b6
|
||||
LDA ,U ;35D1: A6 C4 '..'
|
||||
LSRA ;35D3: 44 'D'
|
||||
ADDA ,S ;35D4: AB E4 '..'
|
||||
STA ,S ;35D6: A7 E4 '..'
|
||||
STA ,S ;35D6: A7 E4 '..' ; [S] = two-bit tape average in b6:b7
|
||||
LDA ,U ;35D8: A6 C4 '..'
|
||||
LSRA ;35DA: 44 'D'
|
||||
ADDA ,S+ ;35DB: AB E0 '..'
|
||||
@@ -34,11 +34,26 @@ namespace Thomson::FastLoader {
|
||||
|
||||
Outer loop is:
|
||||
|
||||
Z35AD BSR Z35CA ;35AD: 8D 1B '..'
|
||||
BPL Z35AD ;35AF: 2A FC '*.' ; loop until edge?
|
||||
LDX #M0041 ;35B1: 8E 00 41 '..A'
|
||||
BSR Z35C4 ;35B4: 8D 0E '..' ; fixed delay
|
||||
Z35AD BSR Z35CA ;35AD: 8D 1B '..'
|
||||
BPL Z35AD ;35AF: 2A FC '*.' ; loop until sample differs from 3507
|
||||
LDX #M0041 ;35B1: 8E 00 41 '..A' ; bit length
|
||||
BSR Z35C4 ;35B4: 8D 0E '..' ; fixed delay: 7µs + [as per 35C4]
|
||||
BSR Z35CA ;35B6: 8D 12 '..' ; sample again for bit
|
||||
BPL Z35BF ;35B8: 2A 05 '*.' ; BPL -> 43 = COMA, which sets carry
|
||||
COM M3507 ;35BA: 73 35 07 's5.'
|
||||
CLRA ;35BD: 4F 'O' ; clear carry
|
||||
BRN Z3603 ;35BE: 21 43 '!C'
|
||||
ROL M3508 ;35C0: 79 35 08 'y5.'
|
||||
RTS ;35C3: 39 '9'
|
||||
|
||||
Delay loop is:
|
||||
|
||||
Z35C4 DEX ;35C4: 30 1F '0.' ; 5 µs
|
||||
BNE Z35C4 ;35C6: 26 FC '&.' ; 3 µs
|
||||
CLRA ;35C8: 4F 'O' ; 2 µs
|
||||
RTS ;35C9: 39 '9' ; 5 µs
|
||||
|
||||
i.e. length is 8*X + 7 µs.
|
||||
|
||||
*/
|
||||
struct LoricielsBactron: public Loader {
|
||||
@@ -60,7 +75,6 @@ struct LoricielsBactron: public Loader {
|
||||
memory.iterator(address - 2)
|
||||
)
|
||||
) {
|
||||
// TODO: use 'outer' for validation.
|
||||
switch(address) {
|
||||
case 0x35cc: return 0x35ad;
|
||||
default:
|
||||
@@ -75,7 +89,7 @@ struct LoricielsBactron: public Loader {
|
||||
const uint16_t address,
|
||||
MemoryAccess &memory,
|
||||
CPU::M6809::Registers &,
|
||||
Storage::Tape::BinaryTapePlayer &,
|
||||
Storage::Tape::BinaryTapePlayer &player,
|
||||
Storage::Tape::TapeSerialiser &
|
||||
) override {
|
||||
// Check that this is still the expected routine.
|
||||
@@ -88,9 +102,29 @@ struct LoricielsBactron: public Loader {
|
||||
return std::make_pair(TrapAction::None, false);
|
||||
}
|
||||
|
||||
// TODO.
|
||||
player.run_for(Storage::Time(14 + 8*0x41, 1'000'000));
|
||||
|
||||
return std::make_pair(TrapAction::None, false);
|
||||
// Sample current level.
|
||||
const bool start_level = memory[0x3507] & 0x80;
|
||||
|
||||
// Proceed to next edge; time can be skipped here.
|
||||
while(player.input() == start_level) {
|
||||
player.complete_pulse();
|
||||
}
|
||||
|
||||
// Wait for 14 + 8*(0x41) µs.
|
||||
player.run_for(Storage::Time(14 + 8*0x41, 1'000'000));
|
||||
|
||||
// Sample current level to determine bit, shift and complement as appropriate.
|
||||
const bool final_level = player.input();
|
||||
memory[0x3508] <<= 1;
|
||||
if(final_level == start_level) {
|
||||
memory[0x3508] |= 1;
|
||||
} else {
|
||||
memory[0x3507] ^= 0xff;
|
||||
}
|
||||
|
||||
return std::make_pair(TrapAction::RTS, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -128,6 +128,8 @@ struct ConcreteMachine:
|
||||
audio_queue_.lock_flush();
|
||||
}
|
||||
|
||||
uint16_t previous_pc = 0;
|
||||
|
||||
template <
|
||||
CPU::M6809::BusPhase bus_phase,
|
||||
CPU::M6809::LIC lic,
|
||||
@@ -250,6 +252,11 @@ struct ConcreteMachine:
|
||||
value = memory_.read(address);
|
||||
|
||||
if constexpr (lic == CPU::M6809::LIC::InstructionFetch) {
|
||||
if(address == 0x35ad && previous_pc < 0x35ad) {
|
||||
printf("[%d] 3507: %02x; 3508: %02x\n", tape_player_.serialiser()->offset(), memory_[0x3507], memory_[0x3508]);
|
||||
}
|
||||
previous_pc = address;
|
||||
|
||||
if(
|
||||
allow_fast_tape_loading_ &&
|
||||
tape_player_.motor_control() &&
|
||||
|
||||
@@ -132,6 +132,12 @@ void TapePlayer::run_for(const Cycles cycles) {
|
||||
}
|
||||
}
|
||||
|
||||
void TapePlayer::run_for(const Time time) {
|
||||
run_for(Cycles(
|
||||
(get_input_clock_rate() * time.length) / time.clock_rate
|
||||
));
|
||||
}
|
||||
|
||||
void TapePlayer::run_for_input_pulse() {
|
||||
jump_to_next_event();
|
||||
}
|
||||
@@ -200,6 +206,10 @@ void BinaryTapePlayer::run_for(const Cycles cycles) {
|
||||
if(motor_is_running_) TapePlayer::run_for(cycles);
|
||||
}
|
||||
|
||||
void BinaryTapePlayer::run_for(const Time time) {
|
||||
if(motor_is_running_) TapePlayer::run_for(time);
|
||||
}
|
||||
|
||||
void BinaryTapePlayer::set_delegate(Delegate *const delegate) {
|
||||
delegate_ = delegate;
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@ public:
|
||||
TapeSerialiser *serialiser();
|
||||
|
||||
void run_for(Cycles);
|
||||
void run_for(Time); // Converts the Time to an integral number of cycles; some precision is lost.
|
||||
void run_for_input_pulse();
|
||||
|
||||
ClockingHint::Preference preferred_clocking() const override;
|
||||
@@ -166,6 +167,7 @@ public:
|
||||
bool input() const;
|
||||
|
||||
void run_for(Cycles);
|
||||
void run_for(Time); // Converts the Time to an integral number of cycles; some precision is lost.
|
||||
|
||||
struct Delegate {
|
||||
virtual void tape_did_change_input(BinaryTapePlayer &) = 0;
|
||||
|
||||
Reference in new issue
Block a user