CHS Settings

This commit is contained in:
David Kuder 2023-05-29 19:51:19 -04:00
parent a09d5dbf13
commit 8012d85d23
6 changed files with 184 additions and 181 deletions

View File

@ -1189,101 +1189,132 @@ void makeimagecmd(int argc, char **argv) {
FsFile file;
char tmp_path[MAX_FILE_PATH+1];
uint64_t fileSize = 0;
int i;
bool write_mbr = 0;
uint64_t cylinders = 0;
uint64_t heads = 16;
uint64_t sectors = 63;
uint64_t blocksize = 512;
if(argc < 4) {
return;
}
fixupPath(tmp_path, argv[1]);
if(strncmp(tmp_path, "/sd/", 4)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Can only create images on the SD Card.\r\n");
return;
}
if(!strcmp(argv[2], "msdos") || !strcmp(argv[2], "generic")) {
char *suffix = NULL;
fileSize = strtoul(argv[3], &suffix, 0);
if(suffix && suffix[0] != 0) {
if(!strcmp(suffix, "KB")) fileSize *= 1000ull;
if(!strcmp(suffix, "KiB")) fileSize *= 1024ull;
if(!strcmp(suffix, "MB")) fileSize *= 1000000ull;
if(!strcmp(suffix, "MiB")) fileSize *= 1024ull * 1024ull;
if(!strcmp(suffix, "GB")) fileSize *= 1000000000ull;
if(!strcmp(suffix, "GiB")) fileSize *= 1024ull * 1024ull * 1024ull;
}
if(sd.exists(tmp_path+3)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": file '%s' already exists.\r\n", tmp_path);
return;
}
if(fileSize < (5ull * 1024ull * 1024ull)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Image would be less than 5 MiB.\r\n");
return;
}
if(fileSize > (2048ull * 1024ull * 1024ull)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Image would be larger than 2 GiB.\r\n");
return;
}
// Fixup image size to our 64 Head 32 Sector X Cylinders formula
uint64_t cyl = fileSize / (512ull * 64ull * 32ull);
if(fileSize & 0xFFFFF) cyl++;
if(cyl > 2048) cyl = 2048;
fileSize = cyl * (512ull * 64ull * 32ull);
if(!file.open(tmp_path+3, O_WRONLY | O_CREAT | O_TRUNC)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Unable to open '%s'.\r\n", tmp_path);
} else {
// Take advantage of our cylinders being 1MB
#if 0
if(!file.preAllocate(fileSize)) {
file.close();
sd.remove(tmp_path+3);
tmp_path[0] = 0;
for(i = 1; i < argc; i++) {
if(argv[i][0] == '/') {
fixupPath(tmp_path, argv[i]);
if(strncmp(tmp_path, "/sd/", 4)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Pre-allocate failed, SD Card must be formatted as ExFat.\r\n");
Serial.printf(": Can only create images on the SD Card.\r\n");
return;
}
#endif
if(!strcmp(argv[2], "msdos")) {
file.write(mbr_bin, 512);
fileSize -= 512;
}
memset(zero, 0, 512);
while(fileSize) {
if((fileSize & 0x1FFF) == 0)
Serial.printf(".");
if((fileSize & 0x7FFFF) == 0)
Serial.printf("\r\n");
file.write(zero, 512);
fileSize -= 512;
}
Serial.printf("\r\n");
file.close();
return;
}
if(!strcmp(argv[i], "-msdos")) {
write_mbr = 1;
} else
if(!strcmp(argv[i], "-b") && (i+1 < argc)) {
i++;
blocksize = strtoul(argv[i], NULL, 0);
} else
if(!strcmp(argv[i], "-c") && (i+1 < argc)) {
i++;
cylinders = strtoul(argv[i], NULL, 0);
} else
if(!strcmp(argv[i], "-h") && (i+1 < argc)) {
i++;
heads = strtoul(argv[i], NULL, 0);
} else
if(!strcmp(argv[i], "-s") && (i+1 < argc)) {
i++;
sectors = strtoul(argv[i], NULL, 0);
} else
{
char *suffix = NULL;
fileSize = strtoul(argv[i], &suffix, 0);
if(suffix && suffix[0] != 0) {
if(!strcmp(suffix, "KB")) fileSize *= 1000ull;
if(!strcmp(suffix, "KiB")) fileSize *= 1024ull;
if(!strcmp(suffix, "MB")) fileSize *= 1000000ull;
if(!strcmp(suffix, "MiB")) fileSize *= 1024ull * 1024ull;
if(!strcmp(suffix, "GB")) fileSize *= 1000000000ull;
if(!strcmp(suffix, "GiB")) fileSize *= 1024ull * 1024ull * 1024ull;
}
}
}
if(tmp_path[0] == 0) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": no path specified.\r\n");
return;
}
if((fileSize == 0) && (cylinders != 0)) {
fileSize = cylinders * heads * sectors * blocksize;
} else if(fileSize != 0){
// Fixup image size to our CHS formula
// Capping out at ~2GB
cylinders = fileSize / (blocksize * heads * sectors);
if(fileSize & 0xFFFFF) cylinders++;
if(cylinders > 4095) cylinders = 4095;
fileSize = cylinders * (blocksize * heads * sectors);
} else {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": no image size specified.\r\n");
return;
}
if(sd.exists(tmp_path+3)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": file '%s' already exists.\r\n", tmp_path);
return;
}
if(fileSize < (5ull * 1024ull * 1024ull)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Image would be less than 5 MiB.\r\n");
return;
}
if(fileSize > (2048ull * 1024ull * 1024ull)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Image would be larger than 2 GiB.\r\n");
return;
}
if(!file.open(tmp_path+3, O_WRONLY | O_CREAT | O_TRUNC)) {
errorlevel = -1;
Serial.print("ERROR");
if(scriptlevel >= 0) Serial.printf(" on line %d of '%s'", exec_line, exec_filename);
Serial.printf(": Unable to open '%s'.\r\n", tmp_path);
} else {
if(write_mbr) {
file.write(mbr_bin, 512);
fileSize -= 512;
}
memset(zero, 0, 512);
while(fileSize) {
if((fileSize & 0x1FFF) == 0)
Serial.printf(".");
if((fileSize & 0x7FFFF) == 0)
Serial.printf("\r\n");
file.write(zero, (fileSize < 512) ? fileSize : 512);
fileSize -= (fileSize < 512) ? fileSize : 512;
}
Serial.printf("\r\n");
file.close();
return;
}
errorlevel = -1;
@ -1447,6 +1478,33 @@ void setcmd(int argc, char **argv) {
return;
}
if((param_name) && !strcasecmp(param_name, "/sectors")) {
if(argc<3) {
Serial.printf("%d\r\n", h->m_sectors);
} else {
h->m_blocksize = strtol(argv[2], NULL, 0);
}
return;
}
if((param_name) && !strcasecmp(param_name, "/heads")) {
if(argc<3) {
Serial.printf("%d\r\n", h->m_heads);
} else {
h->m_blocksize = strtol(argv[2], NULL, 0);
}
return;
}
if((param_name) && !strcasecmp(param_name, "/cylinders")) {
if(argc<3) {
Serial.printf("%d\r\n", h->m_cylinders);
} else {
h->m_blocksize = strtol(argv[2], NULL, 0);
}
return;
}
if((param_name) && !strcasecmp(param_name, "/quirks")) {
if(argc<3) {
Serial.printf("0x%02x\r\n", h->m_quirks);
@ -1964,15 +2022,21 @@ char helponVar[] =
char helponMkImg[] =
"\r\n"
"mkimg <file> <type> <size>\r\n"
"mkimg <file> [-msdos] [-b blocksize] [-c cylinders] [-h heads] [-s sectors] [size]\r\n"
"\r\n"
" The mkimg command creates image files on ExFat volumes.\r\n"
" The mkimg command creates image files on FAT or ExFat volumes.\r\n"
"This command is limited to 4095 cylinders or approximately 2GB.\r\n"
"To create larger images, use a USB card reader.\r\n"
"\r\n"
"<type> specifies the partitioning scheme to preload the image with.\r\n"
" generic creates a blank disk ready for partitioning.\r\n"
" msdos preloads an MBR boot menu, and in the future may pre-partition and format.\r\n"
" -msdos preloads an msdos compatible MBR.\r\n"
" -b sets the sector size (default=512).\r\n"
" -c sets the number of cylinders.\r\n"
" -h sets the heads (default=16).\r\n"
" -s sets the sectors per track (default=63).\r\n"
"\r\n"
"<size> specifies file size and supports a KB,MB,GB (1000) or KiB,MiB,GiB (1024) suffix.\r\n"
"You can specify the size either via the combination of -c -h -s parameters, or\r\n"
"specify the file size with optional KB,MB,GB (1000) or KiB,MiB,GiB (1024) suffix\r\n"
"and a cylinder count close to your desired size will be chosen for you.\r\n"
"\r\n"
;
@ -2000,7 +2064,7 @@ Commands_t GlobalCommands[] = {
{ "mount", "/vdevs/vdev", 1, "<path>", helponMount, mountcmd, NULL },
{ "map", "/vdevs/vdev", 1, "<lun>", helponMapV, mapcmd, NULL },
{ "cat", "/sd", 1, "<file>", helponCat, catcmd, NULL },
{ "mkimg", "/sd", 1, "<file>", helponMkImg, makeimagecmd, NULL },
{ "mkimg", "/sd", 1, "<file> <size>", helponMkImg, makeimagecmd, NULL },
{ "unlink", "/", 1, "<path>", helponUnlink, unlinkcmd, NULL },
{ "exec", "/", 1, "<script>", helponExec, execcmd, NULL },
{ "goto", "/", 1, NULL, NULL, gotocmd, NULL },

View File

@ -9,6 +9,8 @@
#define ACK_INTERRUPTS false
#define READ_SPEED_OPTIMIZE true //
#define WRITE_SPEED_OPTIMIZE true //
#define READ_SPEED_OPTIMIZE_RAW true //
#define WRITE_SPEED_OPTIMIZE_RAW true //
#define USE_DB2ID_TABLE true // Use table to get ID from SEL-DB
// SCSI config

View File

@ -219,6 +219,10 @@ void ConfigureDisk(VirtualDevice_t *vdev, const char *image_name) {
}
}
vdev->m_sectors = 63;
vdev->m_heads = 16;
vdev->m_cylinders = (uint32_t)((uint64_t)vdev->m_fileSize / ((uint64_t)vdev->m_blocksize * (uint64_t)vdev->m_heads * (uint64_t)vdev->m_sectors));
if(image_name) {
char configname[MAX_FILE_PATH+1];
memcpy(configname, image_name, MAX_FILE_PATH+1);

View File

@ -177,84 +177,7 @@ void ModeSenseCommandHandler()
}
memset(m_responsebuffer, 0, sizeof(m_responsebuffer));
#if 0
if(m_sel->m_quirks & QUIRKS_SASI) {
int pageCode = cmd2 & 0x3F;
// Assuming sector size 512, number of sectors 25, number of heads 8 as default settings
int size = m_sel->m_fileSize;
int cylinders = (int)(size >> 9);
cylinders >>= 3;
cylinders /= 25;
int sectorsize = 512;
int sectors = 25;
int heads = 8;
// Sector size
int disksize = 0;
for(disksize = 16; disksize > 0; --(disksize)) {
if ((1 << disksize) == sectorsize)
break;
}
// Number of blocks
uint32_t diskblocks = (uint32_t)(size >> disksize);
int a = 4;
if(dbd == 0) {
uint32_t bl = m_sel->m_blocksize;
uint32_t bc = m_sel->m_fileSize / bl;
uint8_t c[8] = {
0,// Density code
bc >> 16, bc >> 8, bc,
0, //Reserve
bl >> 16, bl >> 8, bl
};
memcpy(&m_responsebuffer[4], c, 8);
a += 8;
m_responsebuffer[3] = 0x08;
}
switch(pageCode) {
case 0x3F:
{
m_responsebuffer[len + 0] = 0x01;
m_responsebuffer[len + 1] = 0x06;
a += 8;
}
case 0x03: // drive parameters
{
m_responsebuffer[len + 0] = 0x80 | 0x03; // Page code
m_responsebuffer[len + 1] = 0x16; // Page length
m_responsebuffer[len + 2] = (uint8_t)(heads >> 8);// number of sectors / track
m_responsebuffer[len + 3] = (uint8_t)(heads);// number of sectors / track
m_responsebuffer[len + 10] = (uint8_t)(sectors >> 8);// number of sectors / track
m_responsebuffer[len + 11] = (uint8_t)(sectors);// number of sectors / track
int size = 1 << disksize;
m_responsebuffer[len + 12] = (uint8_t)(size >> 8);// number of sectors / track
m_responsebuffer[len + 13] = (uint8_t)(size);// number of sectors / track
a += 24;
if(pageCode != 0x3F) {
break;
}
}
case 0x04: // drive parameters
{
LOGN("AddDrive");
m_responsebuffer[len + 0] = 0x04; // Page code
m_responsebuffer[len + 1] = 0x12; // Page length
m_responsebuffer[len + 2] = (cylinders >> 16);// Cylinder length
m_responsebuffer[len + 3] = (cylinders >> 8);
m_responsebuffer[len + 4] = cylinders;
m_responsebuffer[len + 5] = heads; // Number of heads
a += 20;
if(pageCode != 0x3F) {
break;
}
}
default:
break;
}
m_responsebuffer[0] = a - 1;
writeDataPhase(len < a ? len : a, m_responsebuffer);
} else
#endif
{
/* Default medium type */
m_responsebuffer[len++] = (m_sel->m_type == DEV_OPTICAL) ? 0xf0 : 0x00;
@ -282,7 +205,7 @@ void ModeSenseCommandHandler()
m_responsebuffer[len++] = 0x04;
m_responsebuffer[len++] = 0x00;
} else {
uint32_t capacity = (m_sel->m_fileSize / m_sel->m_blocksize);
uint32_t capacity = (m_sel->m_fileSize / m_sel->m_blocksize) - 1;
m_responsebuffer[len++] = 8; /* Block descriptor length */
m_responsebuffer[len++] = (capacity >> 24) & 0xff;
m_responsebuffer[len++] = (capacity >> 16) & 0xff;
@ -411,11 +334,14 @@ void ModeSenseCommandHandler()
m_responsebuffer[len + 0] = MODEPAGE_RIGID_GEOMETRY; //Page code
m_responsebuffer[len + 1] = 0x16; // Page length
if((m_cmd[2] >> 6) != 1) {
uint32_t bc = m_sel->m_fileSize / m_sel->m_file;
m_responsebuffer[len + 2] = bc >> 16;// Cylinder length
m_responsebuffer[len + 3] = bc >> 8;
m_responsebuffer[len + 4] = bc;
m_responsebuffer[len + 5] = 1; // Number of heads
m_responsebuffer[len + 2] = m_sel->m_cylinders >> 16; // Number of cylinders
m_responsebuffer[len + 3] = m_sel->m_cylinders >> 8;
m_responsebuffer[len + 4] = m_sel->m_cylinders;
m_responsebuffer[len + 5] = m_sel->m_heads; // Number of heads
memcpy(&m_responsebuffer[len + 6], &m_responsebuffer[len + 2], 3); // Write Precomp Cyl
memcpy(&m_responsebuffer[len + 9], &m_responsebuffer[len + 2], 3); // Reduced Write Current Cyl
m_responsebuffer[len + 20] = 0x1C; // 7200 RPM
m_responsebuffer[len + 21] = 0x20;
}
len += 24;
break;

View File

@ -213,6 +213,9 @@ typedef struct VirtualDevice_s
char m_filename[MAX_FILE_PATH+1];
FsFile m_file; // File object
uint64_t m_fileSize; // File size
uint8_t m_sectors;
uint8_t m_heads;
uint32_t m_cylinders;
size_t m_blocksize; // SCSI BLOCK size
uint32_t m_firstSector; // First sector for partition
boolean m_rawPart; // Raw Partition (True) or Image File (False)
@ -260,7 +263,7 @@ typedef enum {
phase_t m_phase = PHASE_BUSFREE;
// Log File
#define VERSION "1.4-20230513"
#define VERSION "1.4-20230529"
#if DEBUG == 2
#define LOG_FILENAME "LOG.txt"
FsFile LOG_FILE;
@ -293,6 +296,8 @@ boolean OpenImage(VirtualDevice_t *h, const char *image_name)
h->m_file = sd.open(image_name, O_RDWR);
if(h->m_file.isOpen()) {
h->m_fileSize = h->m_file.size();
h->m_cylinders = (uint32_t)((uint64_t)h->m_fileSize / ((uint64_t)h->m_blocksize * (uint64_t)h->m_heads * (uint64_t)h->m_sectors));
return true; // File opened
}
return false;
@ -342,6 +347,7 @@ boolean OpenDiskImage(VirtualDevice_t *h, const char *image_name, int blocksize)
h->m_blocksize = blocksize;
h->m_fileSize = ((uint64_t)mbr->part[partIndex].totalSectors) * ((uint64_t)512);
h->m_cylinders = (uint32_t)((uint64_t)h->m_fileSize / ((uint64_t)h->m_blocksize * (uint64_t)h->m_heads * (uint64_t)h->m_sectors));
h->m_rawPart = true;
h->m_firstSector = mbr->part[partIndex].firstSector;
@ -366,6 +372,7 @@ boolean OpenDiskImage(VirtualDevice_t *h, const char *image_name, int blocksize)
if(h->m_file.isOpen())
{
h->m_fileSize = h->m_file.size();
h->m_cylinders = (uint32_t)((uint64_t)h->m_fileSize / ((uint64_t)h->m_blocksize * (uint64_t)h->m_heads * (uint64_t)h->m_sectors));
LOG(" Imagefile: ");
LOG(image_name);
if(h->m_fileSize>0)

View File

@ -423,7 +423,7 @@ void verifyDataPhaseRaw(uint32_t adds, uint32_t len)
uint32_t i = 0;
//LOGN("DATAOUT PHASE(RAW)");
uint32_t pos = ((adds * m_sel->m_blocksize) / 512) + m_sel->m_firstSector;
//uint32_t pos = ((adds * m_sel->m_blocksize) / 512) + m_sel->m_firstSector;
SET_MSG_INACTIVE();
SET_CD_INACTIVE();
SET_IO_INACTIVE();
@ -446,4 +446,4 @@ void verifyDataPhaseRaw(uint32_t adds, uint32_t len)
}
#endif
}
}
}