#include #include #include #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; }