1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-13 07:30:21 +00:00

Fixed slots for DFS and ADFS to sideways RAM; continued working on the 1770 to get as far as trying to get the body of a sector.

This commit is contained in:
Thomas Harte 2016-09-24 22:04:54 -04:00
parent 7154e8986e
commit ce4100e5b9
5 changed files with 95 additions and 17 deletions

View File

@ -276,7 +276,7 @@ void WD1770::process_input_bit(int value, unsigned int cycles_since_index_hole)
bits_since_token_++;
Token::Type token_type = Token::Byte;
if(is_double_density_)
if(!is_double_density_)
{
switch(shift_register_ & 0xffff)
{
@ -356,16 +356,19 @@ void WD1770::process_index_hole()
#define END_SECTION() 0; }
void WD1770::posit_event(Event type)
void WD1770::posit_event(Event new_event_type)
{
if(!(interesting_event_mask_ & (int)type)) return;
interesting_event_mask_ &= ~type;
if(!(interesting_event_mask_ & (int)new_event_type)) return;
interesting_event_mask_ &= ~new_event_type;
BEGIN_SECTION()
// Wait for a new command, branch to the appropriate handler.
wait_for_command:
printf("Idle...\n");
status_ &= ~Flag::Busy;
WAIT_FOR_EVENT(Event::Command);
printf("Starting %02x\n", command_);
status_ |= Flag::Busy;
if(!(command_ & 0x80)) goto begin_type_1;
if(!(command_ & 0x40)) goto begin_type_2;
@ -377,9 +380,9 @@ void WD1770::posit_event(Event type)
*/
begin_type_1:
// Set initial flags, skip spin-up if possible.
status_ &= ~(Flag::DataRequest | Flag::DataRequest);
status_ &= ~(Flag::DataRequest | Flag::DataRequest | Flag::SeekError);
set_interrupt_request(false);
if(!(command_&0x08)) goto test_type1_type;
if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type1_type;
// Perform spin up.
status_ |= Flag::MotorOn;
@ -389,6 +392,7 @@ void WD1770::posit_event(Event type)
WAIT_FOR_EVENT(Event::IndexHole);
WAIT_FOR_EVENT(Event::IndexHole);
WAIT_FOR_EVENT(Event::IndexHole);
status_ |= Flag::SpinUp;
test_type1_type:
// Set step direction if this is a step in or out.
@ -402,10 +406,10 @@ void WD1770::posit_event(Event type)
perform_seek_or_restore_command:
if(track_ == data_) goto verify;
step_direction_ = (data_ < track_);
step_direction_ = (data_ > track_);
adjust_track:
if(step_direction_) track_--; else track_++;
if(step_direction_) track_++; else track_--;
perform_step:
if(!step_direction_ && get_is_track_zero())
@ -435,15 +439,77 @@ void WD1770::posit_event(Event type)
if(!(command_ & 0x04))
{
set_interrupt_request(true);
status_ &= ~(Flag::Busy);
goto wait_for_command;
}
printf("!!!TODO: verify a type 1!!!\n");
begin_type_2:
printf("!!!TODO: type 2 commands!!!\n");
/*
Type 2 entry point.
*/
begin_type_2:
status_ &= ~(Flag::DataRequest | Flag::LostData | Flag::RecordNotFound | Flag::WriteProtect | Flag::RecordType);
set_interrupt_request(false);
distance_into_header_ = 0;
if((command_&0x08) || (status_ & Flag::MotorOn)) goto test_type2_delay;
// Perform spin up.
status_ |= Flag::MotorOn;
WAIT_FOR_EVENT(Event::IndexHole);
WAIT_FOR_EVENT(Event::IndexHole);
WAIT_FOR_EVENT(Event::IndexHole);
WAIT_FOR_EVENT(Event::IndexHole);
WAIT_FOR_EVENT(Event::IndexHole);
WAIT_FOR_EVENT(Event::IndexHole);
test_type2_delay:
index_hole_count_ = 0;
if(!(command_ & 0x04)) goto test_type2_write_protection;
WAIT_FOR_TIME(30);
test_type2_write_protection:
if(command_&0x20) // TODO:: && is_write_protected
{
set_interrupt_request(true);
status_ |= Flag::WriteProtect;
goto wait_for_command;
}
type2_get_header:
WAIT_FOR_EVENT(Event::IndexHole | Event::Token);
if(new_event_type == Event::Token)
{
if(!distance_into_header_ && latest_token_.type == Token::ID) distance_into_header_++;
else if(distance_into_header_ && latest_token_.type == Token::Byte)
{
header[distance_into_header_ - 1] = latest_token_.byte_value;
distance_into_header_++;
if(distance_into_header_ == 5)
{
if(header[0] == track_ && header[1] == sector_)
{
// TODO: test CRC
goto type2_read_or_write_data;
}
else
{
distance_into_header_ = 0;
}
}
}
}
else if(index_hole_count_ == 5)
{
set_interrupt_request(true);
status_ |= Flag::RecordNotFound;
goto wait_for_command;
}
goto type2_get_header;
type2_read_or_write_data:
printf("!!!TODO: data portion of sector!!!\n");
begin_type_3:
printf("!!!TODO: type 3 commands!!!\n");

View File

@ -30,6 +30,7 @@ class WD1770: public Storage::Disk::Drive {
RecordType = 0x20,
SpinUp = 0x20,
RecordNotFound = 0x10,
SeekError = 0x10,
CRCError = 0x08,
LostData = 0x04,
TrackZero = 0x04,
@ -116,6 +117,10 @@ class WD1770: public Storage::Disk::Drive {
int resume_point_;
int delay_time_;
// ID buffer
int distance_into_header_;
uint8_t header[5];
//
virtual void process_input_bit(int value, unsigned int cycles_since_index_hole);
virtual void process_index_hole();

View File

@ -411,6 +411,9 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
{
*value &= _roms[ROMSlotBASIC][address & 16383];
}
} else if(_rom_write_masks[_active_rom])
{
_roms[_active_rom][address & 16383] = *value;
}
}
break;
@ -496,7 +499,7 @@ void Machine::configure_as_target(const StaticAnalyser::Target &target)
if(target.acorn.has_dfs)
{
set_rom(ROMSlot0, _dfs);
set_rom(ROMSlot0, _dfs, true);
}
_wd1770->set_disk(target.disks.front());
@ -505,7 +508,7 @@ void Machine::configure_as_target(const StaticAnalyser::Target &target)
ROMSlot slot = ROMSlot12;
for(std::shared_ptr<Storage::Cartridge::Cartridge> cartridge : target.cartridges)
{
set_rom(slot, cartridge->get_segments().front().data);
set_rom(slot, cartridge->get_segments().front().data, false);
slot = (ROMSlot)(((int)slot + 1)&15);
}
@ -515,7 +518,7 @@ void Machine::configure_as_target(const StaticAnalyser::Target &target)
}
}
void Machine::set_rom(ROMSlot slot, std::vector<uint8_t> data)
void Machine::set_rom(ROMSlot slot, std::vector<uint8_t> data, bool is_writeable)
{
uint8_t *target = nullptr;
switch(slot)
@ -524,7 +527,10 @@ void Machine::set_rom(ROMSlot slot, std::vector<uint8_t> data)
case ROMSlotADFS: _adfs = data; return;
case ROMSlotOS: target = _os; break;
default: target = _roms[slot]; break;
default:
target = _roms[slot];
_rom_write_masks[slot] = is_writeable;
break;
}
memcpy(target, &data[0], std::min((size_t)16384, data.size()));

View File

@ -148,7 +148,7 @@ class Machine:
public:
Machine();
void set_rom(ROMSlot slot, std::vector<uint8_t> data);
void set_rom(ROMSlot slot, std::vector<uint8_t> data, bool is_writeable);
void configure_as_target(const StaticAnalyser::Target &target);
void set_key_state(Key key, bool isPressed);
@ -189,6 +189,7 @@ class Machine:
// Things that directly constitute the memory map.
uint8_t _roms[16][16384];
bool _rom_write_masks[16];
uint8_t _os[16384], _ram[32768];
std::vector<uint8_t> _dfs, _adfs;

View File

@ -33,7 +33,7 @@
- (void)setROM:(nonnull NSData *)rom slot:(int)slot {
@synchronized(self) {
_electron.set_rom((Electron::ROMSlot)slot, rom.stdVector8);
_electron.set_rom((Electron::ROMSlot)slot, rom.stdVector8, false);
}
}