1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-07 08:26:28 +00:00

Tweaked disk side density, added call-outs to a WD1770 if the Electron had one (albeit without run_for_cycles yet as I need to figure out the clock rate), added a shell of the basic functions of the WD1770. No implementation yet.

This commit is contained in:
Thomas Harte
2016-09-19 22:06:56 -04:00
parent c9dd07cecd
commit a9e65e9b7a
6 changed files with 308 additions and 260 deletions

View File

@@ -7,3 +7,26 @@
//
#include "1770.hpp"
using namespace WD;
void WD1770::set_drive(std::shared_ptr<Storage::Disk::Drive> drive)
{
}
void WD1770::set_is_double_density(bool is_double_density)
{
}
void WD1770::set_register(int address, uint8_t value)
{
}
uint8_t WD1770::get_register(int address)
{
return 0;
}
void WD1770::run_for_cycles(unsigned int number_of_cycles)
{
}

View File

@@ -15,11 +15,12 @@ namespace WD {
class WD1770 {
public:
void set_drive(std::shared_ptr<Storage::Disk::Drive> drive);
void set_is_double_density(bool is_double_density);
void set_register(int address, uint8_t value);
void get_register(int address);
uint8_t get_register(int address);
void run_for_cycles(unsigned int number_of_cycles);
};
}

View File

@@ -120,13 +120,9 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
}
else
{
if(address >= 0xc000)
switch(address & 0xff0f)
{
if((address & 0xff00) == 0xfe00)
{
switch(address&0xf)
{
case 0x0:
case 0xfe00:
if(isReadOperation(operation))
{
*value = _interrupt_status;
@@ -138,23 +134,21 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
evaluate_interrupts();
}
break;
case 0x1:
break;
case 0x2:
case 0xfe02:
if(!isReadOperation(operation))
{
_startScreenAddress = (_startScreenAddress & 0xfe00) | (uint16_t)(((*value) & 0xe0) << 1);
if(!_startScreenAddress) _startScreenAddress |= 0x8000;
}
break;
case 0x3:
case 0xfe03:
if(!isReadOperation(operation))
{
_startScreenAddress = (_startScreenAddress & 0x01ff) | (uint16_t)(((*value) & 0x3f) << 9);
if(!_startScreenAddress) _startScreenAddress |= 0x8000;
}
break;
case 0x4:
case 0xfe04:
if(isReadOperation(operation))
{
*value = _tape.get_data_register();
@@ -166,7 +160,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
_tape.clear_interrupts(Interrupt::TransmitDataEmpty);
}
break;
case 0x5:
case 0xfe05:
if(!isReadOperation(operation))
{
const uint8_t interruptDisable = (*value)&0xf0;
@@ -199,7 +193,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
}
}
break;
case 0x6:
case 0xfe06:
if(!isReadOperation(operation))
{
update_audio();
@@ -207,7 +201,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
_tape.set_counter(*value);
}
break;
case 0x7:
case 0xfe07:
if(!isReadOperation(operation))
{
// update screen mode
@@ -215,7 +209,6 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
if(new_screen_mode == 7) new_screen_mode = 4;
if(new_screen_mode != _screen_mode)
{
// printf("To mode %d, at %d cycles into field (%d)\n", new_screen_mode, _fieldCycles, _fieldCycles >> 7);
update_display();
_screen_mode = new_screen_mode;
switch(_screen_mode)
@@ -242,7 +235,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
// TODO: caps lock LED
}
break;
default:
case 0xfe08: case 0xfe09: case 0xfe0a: case 0xfe0b: case 0xfe0c: case 0xfe0d: case 0xfe0e: case 0xfe0f:
{
if(!isReadOperation(operation))
{
@@ -303,9 +296,35 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
}
}
break;
}
}
case 0xfcc4: case 0xfcc5: case 0xfcc6: case 0xfcc7:
if(_wd1770 && (address&0x00f0) == 0x00c0)
{
if(isReadOperation(operation))
*value = _wd1770->get_register(address);
else
_wd1770->set_register(address, *value);
}
break;
case 0xfcc0:
if(_wd1770 && (address&0x00f0) == 0x00c0)
{
if(isReadOperation(operation))
*value = 1;
else
{
// TODO:
// bit 0 => enable or disable drive 1
// bit 1 => enable or disable drive 2
// bit 2 => side select
// bit 3 => single density select
// _wd1770->set_register(address, *value);
}
}
break;
default:
if(address >= 0xc000)
{
if(isReadOperation(operation))
{
@@ -371,7 +390,6 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
}
}
}
}
else
{
if(isReadOperation(operation))
@@ -391,6 +409,8 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
}
}
}
break;
}
}
// if(operation == CPU6502::BusOperation::ReadOpcode)

View File

@@ -10,6 +10,7 @@
#define Electron_hpp
#include "../../Processors/6502/CPU6502.hpp"
#include "../../Components/1770/1770.hpp"
#include "../../Storage/Tape/Tape.hpp"
#include "../ConfigurationTarget.hpp"
@@ -227,6 +228,9 @@ class Machine:
bool _use_fast_tape_hack;
bool _fast_load_is_in_data;
// Disk
std::unique_ptr<WD::WD1770> _wd1770;
// Outputs
std::shared_ptr<Outputs::CRT::CRT> _crt;
std::shared_ptr<Speaker> _speaker;

View File

@@ -26,7 +26,7 @@ class FMParser: public Storage::Disk::Drive {
Storage::Time bit_length;
bit_length.length = 1;
bit_length.clock_rate = 250000; // i.e. 250 kbps
bit_length.clock_rate = 250000; // i.e. 250 kbps (including clocks)
set_expected_bit_length(bit_length);
}

View File

@@ -199,7 +199,7 @@ std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetFMTrackWithSec
6, 0,
17, 14,
0,
6400);
6250); // i.e. 250kbps (including clocks) * 60 = 15000kpm, at 300 rpm => 50 kbits/rotation => 6250 bytes/rotation
}
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetMFMTrackWithSectors(const std::vector<Sector> &sectors)
@@ -213,5 +213,5 @@ std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetMFMTrackWithSe
12, 22,
12, 18,
32,
12800);
12500); // unintelligently: double the single-density bytes/rotation (or: 500kps @ 300 rpm)
}