slight bugfix and work on drive

This commit is contained in:
2026-04-01 12:34:57 +02:00
parent 9f6b22cdcf
commit d95726cbf6
3 changed files with 166 additions and 24 deletions

View File

@@ -588,6 +588,11 @@ static nn_Exit ncl_fsHandler(nn_FSRequest *req) {
}
if(req->action == NN_FS_SETLABEL) {
nn_lock(ctx, state->lock);
if(state->isReadonly) {
nn_unlock(ctx, state->lock);
nn_setError(C, "is readonly");
return NN_EBADCALL;
}
state->usage++;
size_t len = req->setlabel.len;
if(len > NN_MAX_LABEL) len = NN_MAX_LABEL;

View File

@@ -2364,30 +2364,6 @@ const nn_Drive nn_floppyDrive = {
.dataEnergyCost = 128.0 / NN_MiB,
};
void nn_drive_seekPenalty(nn_Computer *C, size_t lastSector, size_t newSector, const nn_Drive *drive) {
// Check if SSD
if(drive->rpm == 0) return;
size_t maxSectors = drive->capacity / drive->sectorSize;
size_t sectorsPerPlatter = maxSectors / drive->platterCount;
// RPM over the number of sectors, over 60 seconds.
double latencyPerSector = 1.0 / ((double)drive->rpm / 60 * maxSectors);
// magic
lastSector %= sectorsPerPlatter;
newSector %= sectorsPerPlatter;
size_t sectorDelta;
if(newSector >= lastSector) {
sectorDelta = newSector - lastSector;
} else if(drive->onlySpinForwards) {
sectorDelta = sectorsPerPlatter - (lastSector - newSector);
} else {
sectorDelta = lastSector - newSector;
}
nn_addIdleTime(C, sectorDelta * latencyPerSector);
}
const nn_ScreenConfig nn_defaultScreens[4] = {
(nn_ScreenConfig) {
@@ -3780,6 +3756,104 @@ nn_Component *nn_createFilesystem(nn_Universe *universe, const char *address, co
nn_Component *nn_createVFilesystem(nn_Universe *universe, const char *address, const nn_VFilesystem *vfs, const nn_Filesystem *fs);
static void nn_drive_seekPenalty(nn_Computer *C, size_t lastSector, size_t newSector, const nn_Drive *drive) {
// Check if SSD
if(drive->rpm == 0) return;
size_t maxSectors = drive->capacity / drive->sectorSize;
size_t sectorsPerPlatter = maxSectors / drive->platterCount;
// RPM over the number of sectors, over 60 seconds.
double latencyPerSector = 1.0 / ((double)drive->rpm / 60 * maxSectors);
// magic
lastSector %= sectorsPerPlatter;
newSector %= sectorsPerPlatter;
size_t sectorDelta;
if(newSector >= lastSector) {
sectorDelta = newSector - lastSector;
} else if(drive->onlySpinForwards) {
sectorDelta = sectorsPerPlatter - (lastSector - newSector);
} else {
sectorDelta = lastSector - newSector;
}
nn_addIdleTime(C, sectorDelta * latencyPerSector);
}
typedef enum nn_DrvNum {
NN_DRVNUM_GETCAPACITY,
NN_DRVNUM_GETSECTORSIZE,
NN_DRVNUM_GETPLATTERCOUNT,
NN_DRVNUM_GETLABEL,
NN_DRVNUM_SETLABEL,
NN_DRVNUM_READSECTOR,
NN_DRVNUM_WRITESECTOR,
NN_DRVNUM_READBYTE,
NN_DRVNUM_READUBYTE,
NN_DRVNUM_WRITEBYTE,
NN_DRVNUM_COUNT,
} nn_DrvNum;
typedef struct nn_DrvState {
nn_Context *ctx;
nn_Drive drive;
nn_DriveHandler *handler;
} nn_DrvState;
static nn_Exit nn_drvHandler(nn_ComponentRequest *request) {
nn_Context *ctx = request->ctx;
nn_Computer *C = request->computer;
nn_DrvState *state = request->classState;
nn_DriveRequest dreq;
dreq.ctx = ctx;
dreq.computer = C;
dreq.state = request->state;
if(request->action == NN_COMP_DROP) {
dreq.action = NN_DRIVE_DROP;
state->handler(&dreq);
nn_free(ctx, state, sizeof(*state));
return NN_OK;
}
if(C) nn_setError(C, "bad call");
return NN_EBADCALL;
}
nn_Component *nn_createDrive(nn_Universe *universe, const char *address, const nn_Drive *drive, void *state, nn_DriveHandler *handler) {
nn_Component *c = nn_createComponent(universe, address, "drive");
if(c == NULL) return NULL;
const nn_Method methods[NN_DRVNUM_COUNT] = {
[NN_DRVNUM_GETCAPACITY] = {"getCapacity", "function(): integer - Get drive capacity", NN_DIRECT},
[NN_DRVNUM_GETSECTORSIZE] = {"getSectorSize", "function(): integer - Get sector size", NN_DIRECT},
[NN_DRVNUM_GETPLATTERCOUNT] = {"getPlatterCount", "function(): integer - Get number of platters on this drive", NN_DIRECT},
[NN_DRVNUM_GETLABEL] = {"getLabel", "function(): string? - Get drive label", NN_DIRECT},
[NN_DRVNUM_SETLABEL] = {"setLabel", "function(label: string?): string - Set drive label", NN_DIRECT},
};
nn_Exit e = nn_setComponentMethodsArray(c, methods, NN_DRVNUM_COUNT);
if(e) {
nn_dropComponent(c);
return NULL;
}
nn_Context *ctx = &universe->ctx;
nn_DrvState *drvstate = nn_alloc(ctx, sizeof(*drvstate));
if(drvstate == NULL) {
nn_dropComponent(c);
return NULL;
}
drvstate->ctx = ctx;
drvstate->drive = *drive;
drvstate->handler = handler;
nn_setComponentState(c, state);
nn_setComponentClassState(c, drvstate);
nn_setComponentHandler(c, nn_drvHandler);
return c;
}
nn_Component *nn_createVDrive(nn_Universe *universe, const char *address, const nn_VDrive *vdrive, const nn_Drive *drive);
typedef struct nn_ScreenState {
nn_Context *ctx;
nn_ScreenConfig scrconf;

View File

@@ -1130,6 +1130,69 @@ typedef struct nn_VDrive {
extern const nn_Drive nn_defaultDrives[4];
extern const nn_Drive nn_floppyDrive;
typedef enum nn_DriveAction {
// drive gone
NN_DRIVE_DROP,
// get current label
NN_DRIVE_GETLABEL,
// set or remove current label
NN_DRIVE_SETLABEL,
// get the last read position
NN_DRIVE_LASTREADPOS,
// read a sector
NN_DRIVE_READSECTOR,
// write a sector
NN_DRIVE_WRITESECTOR,
// read a byte
NN_DRIVE_READBYTE,
// write a byte
NN_DRIVE_WRITEBYTE,
} nn_DriveAction;
typedef struct nn_DriveRequest {
nn_Context *ctx;
nn_Computer *computer;
void *state;
const nn_Filesystem *fs;
nn_DriveAction action;
union {
struct {
char *buf;
size_t len;
} getlabel;
struct {
const char *label;
size_t len;
} setlabel;
size_t lastReadPos;
struct {
// 1-indexed
size_t sector;
char *buf;
} readSector;
struct {
// 1-indexed
size_t sector;
const char *buf;
} writeSector;
struct {
// 1-indexed
size_t byte;
unsigned char value;
} readByte;
struct {
// 1-indexed
size_t byte;
unsigned char value;
} writeByte;
};
} nn_DriveRequest;
typedef nn_Exit (nn_DriveHandler)(nn_DriveRequest *request);
nn_Component *nn_createDrive(nn_Universe *universe, const char *address, const nn_Drive *drive, void *state, nn_DriveHandler *handler);
nn_Component *nn_createVDrive(nn_Universe *universe, const char *address, const nn_VDrive *vdrive, const nn_Drive *drive);
// Screen class
typedef enum nn_ScreenFeatures {