You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
4.2 KiB
C
210 lines
4.2 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "drive/drive.h"
|
|
|
|
int drive_io_penality = 1;
|
|
|
|
void drive_set(int id, char *name)
|
|
{
|
|
int qi;
|
|
|
|
if ((id >= 0) && (id <256))
|
|
{
|
|
if(drives[id].name)
|
|
free(drives[id].name);
|
|
|
|
drives[id].name = strdup(name);
|
|
memset(drives[id].serial,0x00,sizeof(drives[id].serial));
|
|
|
|
if (drives[id].name)
|
|
{
|
|
|
|
if (!strncasecmp(drives[id].name,"disk_",5))
|
|
{
|
|
qi = 0;
|
|
while ( (qi<16) &&
|
|
( ((toupper(drives[id].name[5+qi]) >='A') &&
|
|
(toupper(drives[id].name[5+qi]) <='Z')) ||
|
|
((toupper(drives[id].name[5+qi]) >='0') &&
|
|
(toupper(drives[id].name[5+qi]) <='9')) ) )
|
|
{
|
|
drives[id].serial[qi] = drives[id].name[5+qi];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// printf("strdup() failed\n");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void drive(int id)
|
|
{
|
|
FILE *diskfile;
|
|
int sector, size;
|
|
|
|
unsigned char dummy[0x80];
|
|
char tempstring[256];
|
|
|
|
switch (drives[id].command)
|
|
{
|
|
case 0x01:
|
|
memset(drives[id].buffer, 0x00, 128);
|
|
if (drives[id].name)
|
|
strncpy(drives[id].buffer,drives[id].name,127);
|
|
|
|
drives[id].command = 0x00;
|
|
break;
|
|
|
|
case 0x02:
|
|
snprintf(tempstring,256,"%s.img",drives[id].buffer);
|
|
drive_set(id, tempstring);
|
|
|
|
drives[id].type = 0;
|
|
drives[id].command = 0x00;
|
|
break;
|
|
|
|
case 0x03:
|
|
memset(drives[id].buffer, 0x00, 128);
|
|
|
|
if (drives[id].type)
|
|
{
|
|
strcpy(drives[id].buffer,"System Disk");
|
|
}
|
|
else
|
|
{
|
|
if (drives[id].serial)
|
|
memcpy(drives[id].buffer, drives[id].serial, sizeof(drives[id].serial));
|
|
else if (drives[id].name)
|
|
strncpy(drives[id].buffer, drives[id].name,127);
|
|
}
|
|
|
|
drives[id].command = 0x00;
|
|
break;
|
|
|
|
case 0x04:
|
|
if (drives[id].sector >= 2048)
|
|
drives[id].command = 0xff;
|
|
|
|
else if (drives[id].name)
|
|
{
|
|
// printf("drive %d name %s\n", id, drives[id].name);
|
|
if ((diskfile = fopen(drives[id].name, "rb")) == NULL)
|
|
{
|
|
// printf("open failed\n");
|
|
drives[id].command = 0xff;
|
|
break;
|
|
}
|
|
|
|
fseek(diskfile, drives[id].sector << 7, SEEK_SET);
|
|
size = fread(drives[id].buffer, 1, 0x80, diskfile);
|
|
fclose(diskfile);
|
|
|
|
// printf("drive %d read sector %d success, size = %d\n",id,drives[id].sector,size);
|
|
|
|
if (size != 0x80)
|
|
drives[id].command = 0xff;
|
|
else
|
|
drives[id].command = 0x00;
|
|
|
|
}
|
|
else
|
|
{
|
|
drives[id].command = 0xff;
|
|
}
|
|
break;
|
|
|
|
case 0x05:
|
|
if (drives[id].sector >= 2048)
|
|
drives[id].command = 0xff;
|
|
else if (drives[id].name && !drives[id].type)
|
|
{
|
|
if ((diskfile = fopen(drives[id].name, "rb+")) == NULL)
|
|
{
|
|
if ((diskfile = fopen(drives[id].name, "wb")) == NULL)
|
|
{
|
|
drives[id].command = 0xff;
|
|
break;
|
|
}
|
|
}
|
|
|
|
memset(dummy,0x00,sizeof(dummy));
|
|
|
|
fseek(diskfile, 0, SEEK_END);
|
|
size = ftell(diskfile);
|
|
while (size < (drives[id].sector << 7))
|
|
{
|
|
size += fwrite(&dummy, 1, 0x80, diskfile);
|
|
}
|
|
|
|
fseek(diskfile, drives[id].sector << 7, SEEK_SET);
|
|
size = fwrite(&drives[id].buffer, 1, 0x80, diskfile);
|
|
fclose(diskfile);
|
|
if (size != 0x80)
|
|
drives[id].command = 0xff;
|
|
else
|
|
drives[id].command = 0x00;
|
|
}
|
|
else
|
|
drives[id].command = 0xff;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void drive_store(int id, int ptr, unsigned char value)
|
|
{
|
|
if ((id >= 0) && (id <256))
|
|
{
|
|
if ((ptr >= 0) && (ptr < 0x80))
|
|
drives[id].buffer[ptr] = value;
|
|
|
|
else if (ptr == 0x80)
|
|
drives[id].sector = (drives[id].sector & 0xff00) | value;
|
|
|
|
else if (ptr == 0x81)
|
|
drives[id].sector = (drives[id].sector & 0xff) | (value << 8);
|
|
|
|
else if (ptr == 0x82)
|
|
{
|
|
drives[id].command = value;
|
|
|
|
if (!drive_io_penality)
|
|
drive(id);
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned char drive_load(int id, int ptr)
|
|
{
|
|
if ((id >= 0) && (id < 256))
|
|
{
|
|
if ((ptr >= 0) && (ptr < 0x80))
|
|
return drives[id].buffer[ptr];
|
|
|
|
else if (ptr == 0x80)
|
|
return drives[id].sector & 0xff;
|
|
|
|
else if (ptr == 0x81)
|
|
return (drives[id].sector >> 8) & 0xff;
|
|
|
|
else if (ptr == 0x82)
|
|
return drives[id].command;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void drive_type(int id, int type)
|
|
{
|
|
if ((id >= 0) && (id <256))
|
|
drives[id].type = type;
|
|
}
|