Skip to content

Commit

Permalink
Significant improvements to the Software IEC module.
Browse files Browse the repository at this point in the history
SoftwareIEC now supports the following commands:
SCRATCH
COPY
RENAME
INITIALIZE
CD (Change Directory)
CP (Change Partition)
MD (Make Directory)
RD (Remove Directory)

.. as well as the @ replace-file indicator.
  • Loading branch information
GideonZ committed Mar 24, 2019
1 parent c63c13d commit 1b750d5
Show file tree
Hide file tree
Showing 9 changed files with 1,252 additions and 573 deletions.
129 changes: 32 additions & 97 deletions software/io/iec/iec.cc
Expand Up @@ -93,7 +93,8 @@ IecInterface iec_if;
// The track and sector will be send seperately

const char msg00[] = " OK"; //00
const char msg01[] = "FILES SCRATCHED"; //01 Track number shows how many files were removed
const char msg01[] = " FILES SCRATCHED"; //01 Track number shows how many files were removed
const char msg02[] = "PARTITION SELECTED"; //02
const char msg20[] = "READ ERROR"; //20 (Block Header Not Found)
//const char msg21[] = "READ ERROR"; //21 (No Sync Character)
//const char msg22[] = "READ ERROR"; //22 (Data Block not Present)
Expand Down Expand Up @@ -121,19 +122,21 @@ const char msg64[] = "FILE TYPE MISMATCH"; //64
//const char msg65[] = "NO BLOCK"; //65
//const char msg66[] = "ILLEGAL TRACK AND SECTOR";//66
//const char msg67[] = "ILLEGAL SYSTEM T OR S"; //67
const char msg69[] = "FILESYSTEM ERROR"; //69
const char msg70[] = "NO CHANNEL"; //70
const char msg71[] = "DIRECTORY ERROR"; //71
const char msg72[] = "DISK FULL"; //72
const char msg73[] = "ULTIMATE IEC DOS V0.8"; //73 DOS MISMATCH(Returns DOS Version)
const char msg73[] = "ULTIMATE IEC DOS V0.9"; //73 DOS MISMATCH(Returns DOS Version)
const char msg74[] = "DRIVE NOT READY"; //74

const char msg77[] = "SELECTED PARTITION ILLEGAL"; //77
const char msg_c1[] = "BAD COMMAND"; //custom
const char msg_c2[] = "UNIMPLEMENTED"; //custom


const IEC_ERROR_MSG last_error_msgs[] = {
{ 00,(char*)msg00,NR_OF_EL(msg00) - 1 },
{ 01,(char*)msg01,NR_OF_EL(msg01) - 1 },
{ 02,(char*)msg02,NR_OF_EL(msg02) - 1 },
{ 20,(char*)msg20,NR_OF_EL(msg20) - 1 },
// { 21,(char*)msg21,NR_OF_EL(msg21) - 1 },
// { 22,(char*)msg22,NR_OF_EL(msg22) - 1 },
Expand Down Expand Up @@ -161,11 +164,13 @@ const IEC_ERROR_MSG last_error_msgs[] = {
// { 65,(char*)msg65,NR_OF_EL(msg65) - 1 },
// { 66,(char*)msg66,NR_OF_EL(msg66) - 1 },
// { 67,(char*)msg67,NR_OF_EL(msg67) - 1 },
{ 69,(char*)msg69,NR_OF_EL(msg69) - 1 },
{ 70,(char*)msg70,NR_OF_EL(msg70) - 1 },
{ 71,(char*)msg71,NR_OF_EL(msg71) - 1 },
{ 72,(char*)msg72,NR_OF_EL(msg72) - 1 },
{ 73,(char*)msg73,NR_OF_EL(msg73) - 1 },
{ 74,(char*)msg74,NR_OF_EL(msg74) - 1 },
{ 77,(char*)msg77,NR_OF_EL(msg77) - 1 },

{ 75,(char*)msg_c1,NR_OF_EL(msg_c1) - 1 },
{ 76,(char*)msg_c2,NR_OF_EL(msg_c2) - 1 }
Expand Down Expand Up @@ -200,13 +205,9 @@ IecInterface :: IecInterface() : SubSystem(SUBSYSID_IEC)
printf("%d bytes loaded.\n", size);

atn = false;
path = fm->get_new_path("IEC");
path->cd(cfg->get_string(CFG_IEC_PATH));
cmd_path = fm->get_new_path("IEC Gui Path");
cmd_ui = 0;

dirlist = new IndexedList<FileInfo *>(8, NULL);
iecNames = new IndexedList<char *>(8, NULL);
last_error = ERR_DOS;
current_channel = 0;
talking = false;
Expand All @@ -220,6 +221,8 @@ IecInterface :: IecInterface() : SubSystem(SUBSYSID_IEC)

effectuate_settings();

vfs = new IecFileSystem(this);

for(int i=0;i<15;i++) {
channels[i] = new IecChannel(this, i);
}
Expand All @@ -246,10 +249,14 @@ IecInterface :: ~IecInterface()
delete channels[i];

delete channel_printer;
fm->release_path(path);
fm->release_path(cmd_path);
}

IecCommandChannel *IecInterface :: get_command_channel(void)
{
return (IecCommandChannel *)channels[15];
}

void IecInterface :: effectuate_settings(void)
{
uint32_t was_talk = 0x18800040 + last_addr; // compare instruction
Expand Down Expand Up @@ -291,6 +298,7 @@ void IecInterface :: effectuate_settings(void)
last_printer_addr = bus_id;
}

rootPath = cfg->get_string(CFG_IEC_PATH);
channel_printer->set_filename(cfg->get_string(CFG_IEC_PRINTER_FILENAME));
channel_printer->set_output_type(cfg->get_value(CFG_IEC_PRINTER_TYPE));
channel_printer->set_ink_density(cfg->get_value(CFG_IEC_PRINTER_DENSITY));
Expand All @@ -304,6 +312,11 @@ void IecInterface :: effectuate_settings(void)
}


const char *IecInterface :: get_root_path(void)
{
return rootPath;
}

// called from GUI task
int IecInterface :: fetch_task_items(Path *path, IndexedList<Action *> &list)
{
Expand Down Expand Up @@ -358,7 +371,9 @@ void IecInterface :: poll()
while (!((a = HW_IEC_RX_FIFO_STATUS) & IEC_FIFO_EMPTY)) {
data = HW_IEC_RX_DATA;
if(a & IEC_FIFO_CTRL) {
//printf("<%b>", data);
#if IECDEBUG
printf("<%b>", data);
#endif
switch(data) {
case 0xDA:
HW_IEC_TX_DATA = 0x00; // handshake and wait for IRQ
Expand Down Expand Up @@ -414,7 +429,9 @@ void IecInterface :: poll()
}
} else {
if(atn) {
//printf("[/%b] ", data);
#if IECDEBUG
printf("[/%b] ", data);
#endif
if(data >= 0x60) { // workaround for passing of wrong atn codes talk/untalk
if (printer) {
channel_printer->push_command(data & 0x7);
Expand All @@ -427,7 +444,9 @@ void IecInterface :: poll()
if (printer) {
channel_printer->push_data(data);
} else {
//printf("[%b] ", data);
#if IECDEBUG
printf("[%b] ", data);
#endif
channels[current_channel]->push_data(data);
}
}
Expand Down Expand Up @@ -742,12 +761,12 @@ void IecInterface :: save_copied_disk()
}
}

int IecInterface :: get_last_error(char *buffer)
int IecInterface :: get_last_error(char *buffer, int track, int sector)
{
int len;
for(int i = 0; i < NR_OF_EL(last_error_msgs); i++) {
if(last_error == last_error_msgs[i].nr) {
return sprintf(buffer,"%02d,%s,%02d,00\015", last_error,last_error_msgs[i].msg, 0);
return sprintf(buffer,"%02d,%s,%02d,%02d\015", last_error,last_error_msgs[i].msg, track, sector);
}
}
return sprintf(buffer,"99,UNKNOWN,00,00\015");
Expand Down Expand Up @@ -916,90 +935,6 @@ void IecInterface :: test_master(int test)
}
}

void IecInterface :: cleanupDir() {
if (!dirlist)
return;
for(int i=0;i < dirlist->get_elements();i++) {
delete (*dirlist)[i];
delete (*iecNames)[i];

}
dirlist->clear_list();
iecNames->clear_list();
}

FRESULT IecInterface :: readDirectory()
{
cleanupDir();
FRESULT res = path->get_directory(*dirlist);
for(int i=0;i<dirlist->get_elements();i++) {
iecNames->append(getIecName((*dirlist)[i]->lfname));
}
return res;
}

char *IecInterface :: getIecName(char *in)
{
char *out = new char[24];
memset(out, 0, 24);

char temp[64];
strncpy(temp, in, 64);

char ext[8];
get_extension(in, ext);

if (strcmp(ext, "PRG") == 0) {
memcpy(out, ext, 3);
set_extension(temp, "", 64);
} else if (strcmp(ext, "SEQ") == 0) {
memcpy(out, ext, 3);
set_extension(temp, "", 64);
} else if (strcmp(ext, "REL") == 0) {
memcpy(out, ext, 3);
set_extension(temp, "", 64);
} else if (strcmp(ext, "USR") == 0) {
memcpy(out, ext, 3);
set_extension(temp, "", 64);
} else {
memcpy(out, "SEQ", 3);
}

for(int i=0;i<16;i++) {
char o;
if(temp[i] == 0) {
break;
} else if(temp[i] == '_') {
o = 164;
} else if(temp[i] < 32) {
o = 32;
} else {
o = toupper(in[i]);
}
out[i+3] = o;
}
return out;
}

int IecInterface :: findIecName(const char *name, const char *ext)
{
char temp[32];
if (ext[0]=='.')
ext++;
temp[0] = toupper(ext[0]);
temp[1] = toupper(ext[1]);
temp[2] = toupper(ext[2]);

strncpy(temp+3, name, 28);

for(int i=0;i<iecNames->get_elements();i++) {
if (pattern_match(temp, (*iecNames)[i], false)) {
return i;
}
}
return -1;
}

/*********************************************************************/
/* Copier user interface screen
/*********************************************************************/
Expand Down
25 changes: 13 additions & 12 deletions software/io/iec/iec.h
Expand Up @@ -53,23 +53,24 @@
#define LOGGER_CMD_STOP 0x44

class IecChannel;
class IecCommandChannel;
class IecPrinter;
class UltiCopy;
class IecFileSystem;

class IecInterface : public SubSystem, ObjectWithMenu, ConfigurableObject
{
TaskHandle_t taskHandle;
FileManager *fm;
IndexedList<FileInfo *> *dirlist;
IndexedList<char *> *iecNames;
Path *path;
Path *cmd_path;
UserInterface *cmd_ui;
SemaphoreHandle_t ulticopyBusy;
SemaphoreHandle_t ulticopyMutex;
QueueHandle_t queueGuiToIec;
Path *cmd_path;
FileManager *fm;
IecFileSystem *vfs;

int last_addr;
const char *rootPath;
int last_addr;
int last_printer_addr;
bool wait_irq;
bool atn;
Expand Down Expand Up @@ -97,8 +98,6 @@ class IecInterface : public SubSystem, ObjectWithMenu, ConfigurableObject
UltiCopy *ui_window;
uint8_t last_track;
static void iec_task(void *a);
void cleanupDir(void);
char *getIecName(char *in);
public:
int last_error;
uint8_t iec_enable;
Expand All @@ -111,10 +110,9 @@ class IecInterface : public SubSystem, ObjectWithMenu, ConfigurableObject

int fetch_task_items(Path *path, IndexedList<Action *> &list);
void effectuate_settings(void); // from ConfigurableObject
int get_last_error(char *); // writes string into buffer

FRESULT readDirectory(void);
int findIecName(const char *name, const char *ext);
int get_last_error(char *, int track = 0, int sector = 0); // writes string into buffer
IecCommandChannel *get_command_channel();
const char *get_root_path();

friend class IecChannel;
friend class IecCommandChannel;
Expand Down Expand Up @@ -148,6 +146,7 @@ class UltiCopy : public UIObject

#define ERR_OK 00
#define ERR_FILES_SCRATCHED 01
#define ERR_PARTITION_OK 02
#define ERR_READ_ERROR 20
#define ERR_WRITE_ERROR 25
#define ERR_WRITE_PROTECT_ON 26
Expand All @@ -165,6 +164,7 @@ class UltiCopy : public UIObject
#define ERR_FILE_NOT_FOUND 62
#define ERR_FILE_EXISTS 63
#define ERR_FILE_TYPE_MISMATCH 64
#define ERR_FRESULT_CODE 69
#define ERR_NO_CHANNEL 70
#define ERR_DIRECTORY_ERROR 71
#define ERR_DISK_FULL 72
Expand All @@ -173,6 +173,7 @@ class UltiCopy : public UIObject
// custom
#define ERR_BAD_COMMAND 75
#define ERR_UNIMPLEMENTED 76
#define ERR_PARTITION_ERROR 77

typedef struct {
uint8_t nr;
Expand Down

3 comments on commit 1b750d5

@xlar54
Copy link
Contributor

@xlar54 xlar54 commented on 1b750d5 Mar 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YES!

@xlar54
Copy link
Contributor

@xlar54 xlar54 commented on 1b750d5 Mar 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Built and tested some of the functions. This is terrific!

@xlar54
Copy link
Contributor

@xlar54 xlar54 commented on 1b750d5 Mar 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please though, if you could fix the U64 build instructions so I can test on my Ultimate 64 also, that would be great. Something about building the fpga.

Please sign in to comment.