From d3e6ffab309d72c4e9b4718c98a74aff91d665dc Mon Sep 17 00:00:00 2001 From: sShemet Date: Fri, 18 Apr 2025 22:40:53 +0500 Subject: [PATCH] vault backup: 2025-04-18 22:40:53 --- .obsidian/workspace.json | 8 +- .../PSX code - modules load and exec.md | 206 ++++++++++++++++++ 2 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 PERSONAL PROJECTS/PSX code - modules load and exec.md diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 15bb888..683388f 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -41,12 +41,12 @@ "state": { "type": "markdown", "state": { - "file": "PERSONAL PROJECTS/PSX code texture load unpack show and fade.md", + "file": "PERSONAL PROJECTS/PSX code - modules load and exec.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "PSX code texture load unpack show and fade" + "title": "PSX code - modules load and exec" } } ], @@ -207,8 +207,9 @@ }, "active": "dd912cc876184c4f", "lastOpenFiles": [ - "PERSONAL PROJECTS/PS1 Gamepad.md", "PERSONAL PROJECTS/PSX code texture load unpack show and fade.md", + "PERSONAL PROJECTS/PSX code - modules load and exec.md", + "PERSONAL PROJECTS/PS1 Gamepad.md", "PERSONAL PROJECTS/PSX code - Load texture from SECTOR!.md", "PERSONAL PROJECTS/PSX code - Texture show from file.md", "PERSONAL PROJECTS/PS1 Vblank.md", @@ -250,7 +251,6 @@ "WORK & PROJECTS/Ulab/Автобан/песок природный.xls", "WORK & PROJECTS/Ulab/Автобан/грунт песчаный.xlsx", "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_f3d0e9a6d4d8e6a7_fromCanvas.md", - "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_f7aa319103f9c366_fromCanvas.md", "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod.canvas", "PERSONAL PROJECTS/P2EP/cdRead.canvas", "P2EP/cdRead.canvas", diff --git a/PERSONAL PROJECTS/PSX code - modules load and exec.md b/PERSONAL PROJECTS/PSX code - modules load and exec.md new file mode 100644 index 0000000..4cdc414 --- /dev/null +++ b/PERSONAL PROJECTS/PSX code - modules load and exec.md @@ -0,0 +1,206 @@ +Вот реализация вашей задачи для **PlayStation 1**, состоящая из трёх частей: +1. **Основная программа** (MAIN.C) - загружает и запускает дополнительные модули. +2. **Модуль 1** (MODULE1.C) - выводит сообщение и изменяет общую переменную. +3. **Модуль 2** (MODULE2.C) - читает ту же переменную и выводит изменённое значение. + +Все модули загружаются в **один адрес RAM (0x80030000)** и используют общие переменные через специальный заголовок. + +--- + +### **1. Структура проекта** +``` +project/ +├── MAIN.C (Основная программа) +├── MODULE1.C (Модуль 1) +├── MODULE2.C (Модуль 2) +├── SHARED.H (Общие определения) +└── SYSTEM.CNF +``` + +--- + +### **2. Общий заголовок (SHARED.H)** +```c +// Структура для общих переменных +typedef struct { + int counter; + char message[32]; +} SharedData; + +// Заголовок модуля (должен быть одинаковым во всех модулях) +typedef void (*ModuleFunc)(SharedData*); + +typedef struct { + uint32_t magic; // Магическое число 0x55AA1234 + ModuleFunc entry_point; // Точка входа + uint32_t size; // Размер модуля +} ModuleHeader; +``` + +--- + +### **3. Основная программа (MAIN.C)** +```c +#include +#include +#include +#include +#include "SHARED.H" + +#define MODULE_LOAD_ADDR 0x80030000 // Фиксированный адрес загрузки +#define MODULE1_SECTOR 1000 // Сектор начала MODULE1.BIN +#define MODULE1_SIZE 50 // Размер MODULE1.BIN в секторах +#define MODULE2_SECTOR 1100 // Сектор начала MODULE2.BIN +#define MODULE2_SIZE 50 // Размер MODULE2.BIN в секторах + +SharedData shared_data; // Общие данные + +void load_and_run_module(int sector, int size) { + // 1. Загрузка модуля в фиксированный адрес + CdRead(sector, (uint32_t*)MODULE_LOAD_ADDR, size); + CdReadSync(0); + + // 2. Проверка заголовка + ModuleHeader *header = (ModuleHeader*)MODULE_LOAD_ADDR; + if (header->magic != 0x55AA1234) { + FntPrint("Invalid module!\n"); + return; + } + + // 3. Вызов точки входа модуля + header->entry_point(&shared_data); +} + +int main() { + ResetGraph(0); + InitPad(NULL, 0, NULL, 0); + CdInit(); + SetVideoMode(MODE_NTSC); + FntLoad(960, 256); + FntOpen(16, 16, 256, 224, 0, 512); + + // Инициализация общих данных + shared_data.counter = 0; + sprintf(shared_data.message, "Initial message"); + + // Загрузка и выполнение модулей по очереди + while (1) { + FntPrint("Main program running...\n"); + + // Загрузить и выполнить MODULE1 + FntPrint("Loading MODULE1...\n"); + load_and_run_module(MODULE1_SECTOR, MODULE1_SIZE); + VSync(0); + + // Загрузить и выполнить MODULE2 + FntPrint("Loading MODULE2...\n"); + load_and_run_module(MODULE2_SECTOR, MODULE2_SIZE); + VSync(0); + + FntFlush(-1); + VSync(0); + } + + return 0; +} +``` + +--- + +### **4. Модуль 1 (MODULE1.C)** +```c +#include "SHARED.H" + +void module_entry(SharedData *shared) { + // Изменяем общие данные + shared->counter++; + sprintf(shared->message, "MODULE1 was here!"); + + // Выводим сообщение (в реальности используйте FntPrint из основной программы) + // Здесь просто пример доступа к данным +} +// Важно: заголовок должен быть в конце файла! +ModuleHeader __header__ __attribute__((section(".header"))) = { + .magic = 0x55AA1234, + .entry_point = module_entry, + .size = 0 // Заполнит компоновщик +}; +``` + +--- + +### **5. Модуль 2 (MODULE2.C)** +```c +#include "SHARED.H" + +void module_entry(SharedData *shared) { + // Читаем изменённые данные + shared->counter += 10; + sprintf(shared->message + 8, " + MODULE2!"); + + // Выводим сообщение +} +ModuleHeader __header__ __attribute__((section(".header"))) = { + .magic = 0x55AA1234, + .entry_point = module_entry, + .size = 0 +}; +``` + +--- + +### **6. Компиляция и запись на диск** +1. Скомпилируйте каждый модуль **отдельно**: + ```bash + ccpsx MAIN.C -o MAIN.EXE + ccpsx MODULE1.C -o MODULE1.BIN + ccpsx MODULE2.C -o MODULE2.BIN + ``` + +2. Запишите на диск, указав **точные сектора**: + ``` + MAIN.EXE -> Сектор 0 + MODULE1.BIN -> Сектор 1000 (как указано в MAIN.C) + MODULE2.BIN -> Сектор 1100 + ``` + +3. В `SYSTEM.CNF` укажите: + ``` + BOOT = cdrom:\MAIN.EXE;1 + ``` + +--- + +### **7. Как это работает** +1. **Основная программа**: + - Загружает модули в `0x80030000` через `CdRead()`. + - Проверяет магическое число в заголовке. + - Вызывает `entry_point`, передавая указатель на общие данные. + +2. **Модули**: + - Компилируются с **заголовком** в начале. + - Имеют доступ к `SharedData` через переданный указатель. + - Разрешены **только операции с данными** (нельзя использовать PsyQ напрямую). + +3. **Общие переменные**: + - Расположены в основной программе. + - Модули получают к ним доступ через указатель. + +--- + +### **8. Ограничения безопасности** +- Все модули **должны доверять** друг другу. +- Нет защиты от **переполнения буфера** (адрес загрузки фиксирован). +- Модули не должны **переопределять системные вызовы**. + +--- + +### **9. Оптимизации** +- Используйте **DMA** для ускорения загрузки. +- Добавьте **CRC-проверку** модулей в заголовке. +- Для сложных модулей применяйте **релокацию** (но это сложнее). + +Этот подход используется в таких играх, как **Metal Gear Solid** (для загрузки скриптовых модулей). + +________________ +