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:
parent
7154e8986e
commit
ce4100e5b9
@ -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");
|
||||
|
@ -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();
|
||||
|
@ -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()));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user