From 3c13c50cbbb7c5e514f806819aab5a224e98987b Mon Sep 17 00:00:00 2001 From: speedy-lex <78314533+speedy-lex@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:08:35 +0200 Subject: [PATCH 1/4] WIP: drive component --- build.zig | 9 ++-- src/components/drive.c | 96 ++++++++++++++++++++++++++++++++++++++++++ src/universe.c | 2 +- 3 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 src/components/drive.c diff --git a/build.zig b/build.zig index 3544698..127d871 100644 --- a/build.zig +++ b/build.zig @@ -17,6 +17,7 @@ fn addEngineSources(c: *std.Build.Step.Compile) void { // components "src/components/eeprom.c", "src/components/filesystem.c", + "src/components/drive.c", "src/components/screen.c", "src/components/gpu.c", "src/components/keyboard.c", @@ -37,7 +38,7 @@ fn compileTheRightLua(b: *std.Build, c: *std.Build.Step.Compile, version: LuaVer const alloc = b.allocator; const dirName = @tagName(version); - const rootPath = try std.mem.join(alloc, std.fs.path.sep_str, &.{"foreign", dirName}); + const rootPath = try std.mem.join(alloc, std.fs.path.sep_str, &.{ "foreign", dirName }); c.addIncludePath(b.path(rootPath)); @@ -45,13 +46,13 @@ fn compileTheRightLua(b: *std.Build, c: *std.Build.Step.Compile, version: LuaVer var files = std.ArrayList([]const u8).init(alloc); errdefer files.deinit(); - var dir = try std.fs.cwd().openDir(rootPath, std.fs.Dir.OpenDirOptions {.iterate = true}); + var dir = try std.fs.cwd().openDir(rootPath, std.fs.Dir.OpenDirOptions{ .iterate = true }); defer dir.close(); var iter = dir.iterate(); - while(try iter.next()) |e| { - if(std.mem.startsWith(u8, e.name, "l") and std.mem.endsWith(u8, e.name, ".c") and !std.mem.eql(u8, e.name, "lua.c")) { + while (try iter.next()) |e| { + if (std.mem.startsWith(u8, e.name, "l") and std.mem.endsWith(u8, e.name, ".c") and !std.mem.eql(u8, e.name, "lua.c")) { const name = try alloc.dupe(u8, e.name); try files.append(name); } diff --git a/src/components/drive.c b/src/components/drive.c new file mode 100644 index 0000000..82254de --- /dev/null +++ b/src/components/drive.c @@ -0,0 +1,96 @@ +#include "../neonucleus.h" +#include +#include + +void nn_drive_destroy(void *_, nn_component *component, nn_drive *drive) { + if(!nn_decRef(&drive->refc)) return; + + if(drive->deinit == NULL) { + drive->deinit(component, drive->userdata); + } +} + +nn_driveControl nn_drive_getControl(nn_component *component, nn_drive *drive) { + return drive->control(component, drive->userdata); +} + +void nn_drive_getLabel(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + char buf[NN_LABEL_SIZE]; + size_t l = NN_LABEL_SIZE; + drive->getLabel(component, drive->userdata, buf, &l); + if(l == 0) { + nn_return(computer, nn_values_nil()); + } else { + nn_return(computer, nn_values_string(buf, l)); + } +} +void nn_drive_setLabel(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + size_t l = 0; + nn_value label = nn_getArgument(computer, 0); + const char *buf = nn_toString(label, &l); + if(buf == NULL) { + nn_setCError(computer, "bad label (string expected)"); + return; + } + l = drive->setLabel(component, drive->userdata, buf, l); + nn_return(computer, nn_values_string(buf, l)); +} +void nn_drive_getSectorSize(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + size_t sector_size = drive->getSectorSize(component, drive->userdata); + nn_return(computer, nn_values_integer(sector_size)); +} +void nn_drive_getPlatterCount(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + size_t platter_count = drive->getPlatterCount(component, drive->userdata); + nn_return(computer, nn_values_integer(platter_count)); +} +void nn_drive_getCapacity(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + size_t capacity = drive->getCapacity(component, drive->userdata); + nn_return(computer, nn_values_integer(capacity)); +} +void nn_drive_readSector(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + 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]; + drive->readSector(component, drive->userdata, sector, &buf); + nn_return(computer, nn_values_string(buf, sector_size)); +} +void nn_drive_writeSector(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { + nn_value sectorValue = nn_getArgument(computer, 0); + int sector = nn_toInt(sectorValue); + size_t sector_size = drive->getSectorSize(component, drive->userdata); + nn_value bufValue = nn_getArgument(computer, 1); + char *buf = nn_toString(bufValue, sector_size); + 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); + size_t disk_offset = nn_toInt(offsetValue); + size_t sector_size = drive->getSectorSize(component, drive->userdata); + int sector = disk_offset / sector_size; + size_t sector_offset = disk_offset % sector_size; + + char buf[sector_size]; + drive->readSector(component, drive->userdata, sector, &buf); + + nn_return(computer, nn_values_integer(buf[sector_offset])); +} + +void nn_loadDriveTable(nn_universe *universe) { + nn_componentTable *driveTable = nn_newComponentTable("drive", NULL, NULL, (void *)nn_drive_destroy); + nn_storeUserdata(universe, "NN:DRIVE", driveTable); + + nn_defineMethod(driveTable, "getLabel", false, (void *)nn_drive_getLabel, NULL, "getLabel():string - Get the current label of the drive."); + nn_defineMethod(driveTable, "setLabel", false, (void *)nn_drive_setLabel, NULL, "setLabel(value:string):string - Sets the label of the drive. Returns the new value, which may be truncated."); + nn_defineMethod(driveTable, "getSectorSize", true, (void *)nn_drive_getSectorSize, NULL, "getSectorSize():number - Returns the size of a single sector on the drive, in bytes."); + nn_defineMethod(driveTable, "getPlatterCounter", true, (void *)nn_drive_getPlatterCount, NULL, "getPlatterCount():number - Returns the number of platters in the drive."); + nn_defineMethod(driveTable, "getCapacity", true, (void *)nn_drive_getCapacity, NULL, "getCapacity():number - Returns the total capacity of the drive, in bytes."); + nn_defineMethod(driveTable, "readSector", false, (void *)nn_drive_readSector, NULL, "readSector(sector:number):string - Read the current contents of the specified sector."); + nn_defineMethod(driveTable, "writeSector", false, (void *)nn_drive_writeSector, NULL, "writeSector(sector:number, value:string) - Write the specified contents to the specified sector."); +} + +nn_component *nn_addDrive(nn_computer *computer, nn_address address, int slot, nn_drive *drive) { + nn_componentTable *driveTable = nn_queryUserdata(nn_getUniverse(computer), "NN:DRIVE"); + return nn_newComponent(computer, address, slot, driveTable, drive); +} + diff --git a/src/universe.c b/src/universe.c index 50056e5..439cd28 100644 --- a/src/universe.c +++ b/src/universe.c @@ -47,7 +47,7 @@ double nn_getTime(nn_universe *universe) { void nn_loadCoreComponentTables(nn_universe *universe) { nn_loadEepromTable(universe); nn_loadFilesystemTable(universe); - //nn_loadDriveTable(universe); + nn_loadDriveTable(universe); nn_loadScreenTable(universe); nn_loadGraphicsCardTable(universe); nn_loadKeyboardTable(universe); From a8c94ed70ec3032247e8386a3eb6ce645fcb3d2a Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:29:13 +0200 Subject: [PATCH 2/4] fix bugs --- src/components/drive.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/drive.c b/src/components/drive.c index 82254de..589873b 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -52,7 +52,7 @@ 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]; - drive->readSector(component, drive->userdata, sector, &buf); + drive->readSector(component, drive->userdata, sector, buf); nn_return(computer, nn_values_string(buf, sector_size)); } void nn_drive_writeSector(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { @@ -60,7 +60,7 @@ 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); - char *buf = nn_toString(bufValue, sector_size); + char *buf = nn_toString(bufValue, §or_size); drive->writeSector(component, drive->userdata, sector, buf); } void nn_drive_readByte(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) { From b92e71bfc9e14ac5a3566e9461db64d1125bc4f0 Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:39:07 +0200 Subject: [PATCH 3/4] drive component impl --- src/components/drive.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/components/drive.c b/src/components/drive.c index 589873b..8ebeaef 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -75,6 +75,22 @@ 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) { + nn_value offsetValue = nn_getArgument(computer, 0); + nn_value writeValue = nn_getArgument(computer, 1); + size_t disk_offset = nn_toInt(offsetValue); + char write = nn_toInt(writeValue); + size_t sector_size = drive->getSectorSize(component, drive->userdata); + int sector = disk_offset / sector_size; + size_t sector_offset = disk_offset % sector_size; + + char buf[sector_size]; + drive->readSector(component, drive->userdata, sector, &buf); + + buf[sector_offset] = write; + + drive->writeSector(component, drive->userdata, sector, buf); +} void nn_loadDriveTable(nn_universe *universe) { nn_componentTable *driveTable = nn_newComponentTable("drive", NULL, NULL, (void *)nn_drive_destroy); @@ -87,6 +103,8 @@ void nn_loadDriveTable(nn_universe *universe) { nn_defineMethod(driveTable, "getCapacity", true, (void *)nn_drive_getCapacity, NULL, "getCapacity():number - Returns the total capacity of the drive, in bytes."); nn_defineMethod(driveTable, "readSector", false, (void *)nn_drive_readSector, NULL, "readSector(sector:number):string - Read the current contents of the specified sector."); nn_defineMethod(driveTable, "writeSector", false, (void *)nn_drive_writeSector, NULL, "writeSector(sector:number, value:string) - Write the specified contents to the specified sector."); + nn_defineMethod(driveTable, "readByte", false, (void *)nn_drive_readByte, NULL, "readByte(offset:number):number - Read a single byte at the specified offset."); + nn_defineMethod(driveTable, "writeByte", false, (void *)nn_drive_writeByte, NULL, "writeByte(offset:number, value:number) - Write a single byte to the specified offset."); } nn_component *nn_addDrive(nn_computer *computer, nn_address address, int slot, nn_drive *drive) { From dff0ee020c1a7a9ef12713dcfc226c3f463f4671 Mon Sep 17 00:00:00 2001 From: Speedy_Lex <78314533+speedy-lex@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:43:29 +0200 Subject: [PATCH 4/4] fix windows build --- run.bat | 1 - 1 file changed, 1 deletion(-) diff --git a/run.bat b/run.bat index 8c99458..620dd00 100644 --- a/run.bat +++ b/run.bat @@ -1,5 +1,4 @@ @echo off zig build -copy lua\lua54.dll zig-out\bin\ copy raylib\lib\raylib.dll zig-out\bin zig build run \ No newline at end of file