Merge pull request #9 from speedy-lex/main

emulator drive
This commit is contained in:
Quantum Tomato 2025-07-02 22:53:40 +02:00 committed by GitHub
commit f2d18196bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 96 additions and 6 deletions

BIN
data/drive.img Normal file

Binary file not shown.

View File

@ -51,6 +51,11 @@ void nn_drive_readSector(nn_drive *drive, void *_, nn_component *component, nn_c
nn_value sectorValue = nn_getArgument(computer, 0); nn_value sectorValue = nn_getArgument(computer, 0);
int sector = nn_toInt(sectorValue); int sector = nn_toInt(sectorValue);
size_t sector_size = drive->getSectorSize(component, drive->userdata); size_t sector_size = drive->getSectorSize(component, drive->userdata);
// we leave the +1 intentionally to compare the end of the real sector
if (sector < 1 || (sector * sector_size > drive->getCapacity(component, drive->userdata))) {
nn_setCError(computer, "bad argument #1 (sector out of range)");
return;
}
char buf[sector_size]; char buf[sector_size];
drive->readSector(component, drive->userdata, sector, buf); drive->readSector(component, drive->userdata, sector, buf);
nn_return_string(computer, buf, sector_size); nn_return_string(computer, buf, sector_size);
@ -60,16 +65,31 @@ void nn_drive_writeSector(nn_drive *drive, void *_, nn_component *component, nn_
int sector = nn_toInt(sectorValue); int sector = nn_toInt(sectorValue);
size_t sector_size = drive->getSectorSize(component, drive->userdata); size_t sector_size = drive->getSectorSize(component, drive->userdata);
nn_value bufValue = nn_getArgument(computer, 1); nn_value bufValue = nn_getArgument(computer, 1);
const char *buf = nn_toString(bufValue, &sector_size);
size_t buf_size = 0;
const char *buf = nn_toString(bufValue, &buf_size);
if (buf_size != sector_size) {
nn_setCError(computer, "bad argument #2 (expected buffer of length `sectorSize`)");
return;
}
// we leave the +1 intentionally to compare the end of the real sector
if (sector < 1 || (sector * sector_size > drive->getCapacity(component, drive->userdata))) {
nn_setCError(computer, "bad argument #1 (sector out of range)");
return;
}
drive->writeSector(component, drive->userdata, sector, buf); drive->writeSector(component, drive->userdata, sector, buf);
} }
void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) {
nn_value offsetValue = nn_getArgument(computer, 0); nn_value offsetValue = nn_getArgument(computer, 0);
size_t disk_offset = nn_toInt(offsetValue); size_t disk_offset = nn_toInt(offsetValue) - 1;
size_t sector_size = drive->getSectorSize(component, drive->userdata); size_t sector_size = drive->getSectorSize(component, drive->userdata);
int sector = disk_offset / sector_size; int sector = (disk_offset / sector_size) + 1;
size_t sector_offset = disk_offset % sector_size; size_t sector_offset = disk_offset % sector_size;
if (disk_offset >= drive->getCapacity(component, drive->userdata)) {
nn_setCError(computer, "bad argument #1 (index out of range)");
return;
}
char buf[sector_size]; char buf[sector_size];
drive->readSector(component, drive->userdata, sector, buf); drive->readSector(component, drive->userdata, sector, buf);
@ -78,12 +98,20 @@ void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_com
void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) {
nn_value offsetValue = nn_getArgument(computer, 0); nn_value offsetValue = nn_getArgument(computer, 0);
nn_value writeValue = nn_getArgument(computer, 1); nn_value writeValue = nn_getArgument(computer, 1);
size_t disk_offset = nn_toInt(offsetValue); size_t disk_offset = nn_toInt(offsetValue) - 1;
char write = nn_toInt(writeValue); intptr_t write = nn_toInt(writeValue);
size_t sector_size = drive->getSectorSize(component, drive->userdata); size_t sector_size = drive->getSectorSize(component, drive->userdata);
int sector = disk_offset / sector_size; int sector = (disk_offset / sector_size) + 1;
size_t sector_offset = disk_offset % sector_size; size_t sector_offset = disk_offset % sector_size;
if (write < -128 || write > 255) {
nn_setCError(computer, "bad argument #2 (byte out of range)");
return;
}
if (disk_offset >= drive->getCapacity(component, drive->userdata)) {
nn_setCError(computer, "bad argument #1 (index out of range)");
return;
}
char buf[sector_size]; char buf[sector_size];
drive->readSector(component, drive->userdata, sector, buf); drive->readSector(component, drive->userdata, sector, buf);

View File

@ -238,6 +238,47 @@ bool ne_fs_exists(nn_component *component, ne_fs *fs, const char *path) {
return FileExists(p) || DirectoryExists(p); return FileExists(p) || DirectoryExists(p);
} }
typedef struct ne_drive {
FILE *file;
} ne_drive;
void ne_drive_close(nn_component *component, ne_drive *drive) {
fclose(drive->file);
}
nn_driveControl ne_drive_getControl(nn_component *component, ne_drive *_) {
return (nn_driveControl){};
}
size_t ne_drive_getPlatterCount(nn_component *component, ne_drive *_) {
return 1;
}
size_t ne_drive_getSectorSize(nn_component *component, ne_drive *_) {
return 512;
}
size_t ne_drive_getCapacity(nn_component *component, ne_drive *drive) {
fseek(drive->file, 0, SEEK_END);
return ftell(drive->file);
}
void ne_drive_readSector(nn_component *component, ne_drive *drive, int shifted_sector, char *buf) {
int sector = shifted_sector - 1;
size_t sectorSize = ne_drive_getSectorSize(component, drive);
size_t offset = sector * sectorSize;
fseek(drive->file, offset, SEEK_SET);
fread(buf, sizeof(char), sectorSize, drive->file);
}
void ne_drive_writeSector(nn_component *component, ne_drive *drive, int shifted_sector, const char *buf) {
int sector = shifted_sector - 1;
size_t sectorSize = ne_drive_getSectorSize(component, drive);
size_t offset = sector * sectorSize;
fseek(drive->file, offset, SEEK_SET);
fwrite(buf, sizeof(char), sectorSize, drive->file);
// this is probably not needed but i believe someone isn't running the deinit
fflush(drive->file);
}
int keycode_to_oc(int keycode) { int keycode_to_oc(int keycode) {
switch (keycode) { switch (keycode) {
case KEY_NULL: case KEY_NULL:
@ -533,6 +574,27 @@ int main() {
}; };
nn_addFileSystem(computer, "OpenOS", 1, &genericFS); nn_addFileSystem(computer, "OpenOS", 1, &genericFS);
ne_drive drive = {
.file = fopen("data/drive.img", "r+")
};
assert(drive.file != NULL);
nn_drive genericDrive = {
.refc = 0,
.userdata = &drive,
.deinit = (void *)ne_drive_close,
.control = (void *)ne_drive_getControl,
.getLabel = ne_eeprom_getLabel,
.setLabel = ne_eeprom_setLabel,
.getPlatterCount = (void *)ne_drive_getPlatterCount,
.getSectorSize = (void *)ne_drive_getSectorSize,
.getCapacity = (void *)ne_drive_getCapacity,
.readSector = (void *)ne_drive_readSector,
.writeSector = (void *)ne_drive_writeSector,
};
nn_addDrive(computer, "drive.img", 4, &genericDrive);
nn_screen *s = nn_newScreen(&alloc, 80, 32, 16, 16, 256); nn_screen *s = nn_newScreen(&alloc, 80, 32, 16, 16, 256);
nn_addKeyboard(s, "shitty keyboard"); nn_addKeyboard(s, "shitty keyboard");
nn_mountKeyboard(computer, "shitty keyboard", 2); nn_mountKeyboard(computer, "shitty keyboard", 2);