a0d3ca30e8
Only the first file inside the T64 is loaded. Even though T64 is a tape file you load it using “NAME.T64”,8,1 Regular wild cards should also work. NOTE: T64 containing multiple files will probably not work.
202 lines
4.5 KiB
C++
202 lines
4.5 KiB
C++
// Pi1541 - A Commodore 1541 disk drive emulator
|
|
// Copyright(C) 2018 Stephen White
|
|
//
|
|
// This file is part of Pi1541.
|
|
//
|
|
// Pi1541 is free software : you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Pi1541 is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Pi1541. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef IEC_COMMANDS_H
|
|
#define IEC_COMMANDS_H
|
|
|
|
#include "iec_bus.h"
|
|
#include "ff.h"
|
|
#include "debug.h"
|
|
#include "DiskImage.h"
|
|
|
|
struct TimerMicroSeconds
|
|
{
|
|
TimerMicroSeconds()
|
|
{
|
|
count = 0;
|
|
timeout = 0;
|
|
}
|
|
|
|
void Start(u32 amount)
|
|
{
|
|
count = 0;
|
|
timeout = amount;
|
|
}
|
|
|
|
inline bool TimedOut() { return count >= timeout; }
|
|
|
|
bool Tick()
|
|
{
|
|
delay_us(1);
|
|
count++;
|
|
return TimedOut();
|
|
}
|
|
|
|
u32 count;
|
|
u32 timeout;
|
|
};
|
|
|
|
class IEC_Commands
|
|
{
|
|
public:
|
|
enum UpdateAction
|
|
{
|
|
NONE,
|
|
IMAGE_SELECTED,
|
|
DIR_PUSHED,
|
|
POP_DIR,
|
|
POP_TO_ROOT,
|
|
REFRESH,
|
|
DEVICEID_CHANGED,
|
|
DEVICE_SWITCHED,
|
|
RESET
|
|
};
|
|
|
|
IEC_Commands();
|
|
void Initialise();
|
|
|
|
void SetDeviceId(u8 id) { deviceID = id; }
|
|
u8 GetDeviceId() { return deviceID; }
|
|
|
|
void SetLowercaseBrowseModeFilenames(bool value) { lowercaseBrowseModeFilenames = value; }
|
|
void SetNewDiskType(DiskImage::DiskType type) { newDiskType = type; }
|
|
void SetAutoBootFB128(bool autoBootFB128) { this->autoBootFB128 = autoBootFB128; }
|
|
void Set128BootSectorName(const char* SectorName)
|
|
{
|
|
if (SectorName && SectorName[0])
|
|
this->C128BootSectorName = SectorName;
|
|
else
|
|
this->C128BootSectorName = 0;
|
|
}
|
|
|
|
void Reset(void);
|
|
void SimulateIECBegin(void);
|
|
UpdateAction SimulateIECUpdate(void);
|
|
|
|
const char* GetNameOfImageSelected() const { return selectedImageName; }
|
|
const FILINFO* GetImageSelected() const { return &filInfoSelectedImage; }
|
|
void SetStarFileName(const char* fileName) { starFileName = fileName; }
|
|
|
|
int CreateNewDisk(char* filenameNew, char* ID, bool automount);
|
|
|
|
void SetDisplayingDevices(bool displayingDevices) { this->displayingDevices = displayingDevices; }
|
|
|
|
protected:
|
|
enum ATNSequence
|
|
{
|
|
ATN_SEQUENCE_IDLE,
|
|
ATN_SEQUENCE_ATN,
|
|
ATN_SEQUENCE_RECEIVE_COMMAND_CODE,
|
|
ATN_SEQUENCE_HANDLE_COMMAND_CODE,
|
|
ATN_SEQUENCE_COMPLETE
|
|
};
|
|
|
|
enum DeviceRole
|
|
{
|
|
DEVICE_ROLE_PASSIVE,
|
|
DEVICE_ROLE_LISTEN,
|
|
DEVICE_ROLE_TALK
|
|
};
|
|
|
|
struct Channel
|
|
{
|
|
u8 buffer[0x1000];
|
|
u8 command[0x100];
|
|
|
|
FILINFO filInfo;
|
|
FIL file;
|
|
u32 cursor;
|
|
u32 bytesSent;
|
|
u32 open : 1;
|
|
u32 writing : 1;
|
|
u32 fileSize;
|
|
|
|
void Close();
|
|
bool WriteFull() const { return cursor >= sizeof(buffer); }
|
|
bool CanFit(u32 bytes) const { return bytes <= sizeof(buffer) - cursor; }
|
|
};
|
|
|
|
bool CheckATN(void);
|
|
bool WriteIECSerialPort(u8 data, bool eoi);
|
|
bool ReadIECSerialPort(u8& byte);
|
|
|
|
void Listen();
|
|
void Talk();
|
|
void LoadFile();
|
|
void SaveFile();
|
|
|
|
void AddDirectoryEntry(Channel& channel, const char* name, u16 blocks, int fileType);
|
|
void LoadDirectory();
|
|
void OpenFile();
|
|
void CloseFile(u8 secondary);
|
|
void CloseAllChannels();
|
|
void SendError();
|
|
|
|
|
|
bool Enter(DIR& dir, FILINFO& filInfo);
|
|
bool FindFirst(DIR& dir, const char* matchstr, FILINFO& filInfo);
|
|
|
|
void FolderCommand(void);
|
|
void CD(int partition, char* filename);
|
|
void MKDir(int partition, char* filename);
|
|
void RMDir(void);
|
|
|
|
void Copy(void);
|
|
void New(void);
|
|
void Rename(void);
|
|
void Scratch(void);
|
|
void ChangeDevice(void);
|
|
|
|
void Memory(void);
|
|
void User(void);
|
|
void Extended(void);
|
|
|
|
void ProcessCommand(void);
|
|
|
|
bool SendBuffer(Channel& channel, bool eoi);
|
|
|
|
u8 GetFilenameCharacter(u8 value);
|
|
|
|
UpdateAction updateAction;
|
|
u8 commandCode;
|
|
bool receivedCommand : 1;
|
|
bool receivedEOI : 1; // End Or Identify
|
|
bool usingVIC20 : 1; // When sending data we need to wait longer for the 64 as its VICII may be stealing its cycles. VIC20 does not have this problem and can accept data faster.
|
|
bool autoBootFB128 : 1;
|
|
|
|
u8 deviceID;
|
|
u8 secondaryAddress;
|
|
ATNSequence atnSequence;
|
|
DeviceRole deviceRole;
|
|
|
|
TimerMicroSeconds timer;
|
|
|
|
Channel channels[16];
|
|
|
|
char selectedImageName[256];
|
|
FILINFO filInfoSelectedImage;
|
|
|
|
const char* starFileName;
|
|
const char* C128BootSectorName;
|
|
|
|
bool displayingDevices;
|
|
bool lowercaseBrowseModeFilenames;
|
|
DiskImage::DiskType newDiskType;
|
|
};
|
|
#endif
|
|
|