From 20fecebb90de55262bc9349a8b4d38af3cb07420 Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Wed, 2 Jul 2025 01:15:36 +0200 Subject: [PATCH 1/6] emulator drive --- data/drive.img | Bin 0 -> 65536 bytes src/components/drive.c | 15 +++++++- src/emulator.c | 83 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 data/drive.img diff --git a/data/drive.img b/data/drive.img new file mode 100644 index 0000000000000000000000000000000000000000..c97c12f9b0a24bfc19c74a2b265a97c924137775 GIT binary patch literal 65536 zcmeIufdBvi0Dz$VsTV1P3IhfV7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ u0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFi-;k4*&rG literal 0 HcmV?d00001 diff --git a/src/components/drive.c b/src/components/drive.c index 3af2046..a089182 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -60,10 +60,20 @@ void nn_drive_writeSector(nn_drive *drive, void *_, nn_component *component, nn_ int sector = nn_toInt(sectorValue); size_t sector_size = drive->getSectorSize(component, drive->userdata); nn_value bufValue = nn_getArgument(computer, 1); - const char *buf = nn_toString(bufValue, §or_size); - drive->writeSector(component, drive->userdata, sector, buf); + + size_t buf_size = 0; + const char *buf = nn_toString(bufValue, &buf_size); + if (buf_size < sector_size) { + char padded[sector_size]; + memset(padded, 0, sector_size); + memcpy(padded, buf, buf_size); + drive->writeSector(component, drive->userdata, sector, padded); + } else { + drive->writeSector(component, drive->userdata, sector, buf); + } } void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + // TODO: calculate the right index aaaaargh nn_value offsetValue = nn_getArgument(computer, 0); size_t disk_offset = nn_toInt(offsetValue); size_t sector_size = drive->getSectorSize(component, drive->userdata); @@ -76,6 +86,7 @@ void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_com nn_return(computer, nn_values_integer(buf[sector_offset])); } void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + // TODO: calculate the right index aaaaargh nn_value offsetValue = nn_getArgument(computer, 0); nn_value writeValue = nn_getArgument(computer, 1); size_t disk_offset = nn_toInt(offsetValue); diff --git a/src/emulator.c b/src/emulator.c index 141ac9b..4817318 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -238,6 +238,47 @@ bool ne_fs_exists(nn_component *component, ne_fs *fs, const char *path) { 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) { switch (keycode) { case KEY_NULL: @@ -533,6 +574,48 @@ int main() { }; 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); + + 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_addKeyboard(s, "shitty keyboard"); nn_mountKeyboard(computer, "shitty keyboard", 2); From 7c15adc305f8ea973bb1750b9d8e4d57a2c3b559 Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Wed, 2 Jul 2025 01:25:41 +0200 Subject: [PATCH 2/6] fix byte indexing for drives --- src/components/drive.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/drive.c b/src/components/drive.c index a089182..c4652a2 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -73,11 +73,10 @@ void nn_drive_writeSector(nn_drive *drive, void *_, nn_component *component, nn_ } } void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { - // TODO: calculate the right index aaaaargh 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); - int sector = disk_offset / sector_size; + int sector = (disk_offset / sector_size) + 1; size_t sector_offset = disk_offset % sector_size; char buf[sector_size]; @@ -86,13 +85,12 @@ void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_com nn_return(computer, nn_values_integer(buf[sector_offset])); } void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { - // TODO: calculate the right index aaaaargh nn_value offsetValue = nn_getArgument(computer, 0); 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); 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; char buf[sector_size]; From b809a079820f9786b4d18d59d582eb0a47d9ad3d Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:12:38 +0200 Subject: [PATCH 3/6] drive now err's on an invalid sector/buffer --- src/components/drive.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/components/drive.c b/src/components/drive.c index c4652a2..70a48c7 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -52,6 +52,11 @@ void nn_drive_readSector(nn_drive *drive, void *_, nn_component *component, nn_c int sector = nn_toInt(sectorValue); size_t sector_size = drive->getSectorSize(component, drive->userdata); char buf[sector_size]; + // 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->readSector(component, drive->userdata, sector, buf); nn_return_string(computer, buf, sector_size); } @@ -63,14 +68,16 @@ void nn_drive_writeSector(nn_drive *drive, void *_, nn_component *component, nn_ size_t buf_size = 0; const char *buf = nn_toString(bufValue, &buf_size); - if (buf_size < sector_size) { - char padded[sector_size]; - memset(padded, 0, sector_size); - memcpy(padded, buf, buf_size); - drive->writeSector(component, drive->userdata, sector, padded); - } else { - drive->writeSector(component, drive->userdata, sector, buf); + 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); } void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { nn_value offsetValue = nn_getArgument(computer, 0); From 051019e8f48e5492f28d184034aec467528f8aa3 Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:27:48 +0200 Subject: [PATCH 4/6] bounds check for read/write Byte --- src/components/drive.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/drive.c b/src/components/drive.c index 70a48c7..2a4ea23 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -51,12 +51,12 @@ void nn_drive_readSector(nn_drive *drive, void *_, nn_component *component, nn_c nn_value sectorValue = nn_getArgument(computer, 0); int sector = nn_toInt(sectorValue); size_t sector_size = drive->getSectorSize(component, drive->userdata); - char buf[sector_size]; // 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]; drive->readSector(component, drive->userdata, sector, buf); nn_return_string(computer, buf, sector_size); } @@ -86,6 +86,10 @@ void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_com int sector = (disk_offset / sector_size) + 1; 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]; drive->readSector(component, drive->userdata, sector, buf); @@ -95,11 +99,19 @@ void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_co nn_value offsetValue = nn_getArgument(computer, 0); nn_value writeValue = nn_getArgument(computer, 1); 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); int sector = (disk_offset / sector_size) + 1; 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]; drive->readSector(component, drive->userdata, sector, buf); From faf569391c36bad50761c4d33c23ac40ddd03d90 Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Wed, 2 Jul 2025 13:25:26 +0200 Subject: [PATCH 5/6] being safe for file open --- src/emulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emulator.c b/src/emulator.c index 4817318..3bb629f 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -575,7 +575,7 @@ int main() { nn_addFileSystem(computer, "OpenOS", 1, &genericFS); ne_drive drive = { - .file = fopen("data/drive.img", "r+") + .file = fopen("data/drive.img", "rb+") }; assert(drive.file != NULL); From c4eb2505e0262323ddf77198be3b0a3a86146a2f Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Wed, 2 Jul 2025 21:49:58 +0200 Subject: [PATCH 6/6] fix small merge mistake --- src/emulator.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/emulator.c b/src/emulator.c index 3bb629f..abe2f7b 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -574,27 +574,6 @@ int main() { }; nn_addFileSystem(computer, "OpenOS", 1, &genericFS); - ne_drive drive = { - .file = fopen("data/drive.img", "rb+") - }; - 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); - ne_drive drive = { .file = fopen("data/drive.img", "r+") };