nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 03:45



Reply to topic  [ 55 posts ]  Go to page Previous  1, 2, 3, 4
Операционная система ShaOS 
Author Message
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Shaos wrote:
EXE и DLL отличаются тем, что у EXE только одна точка входа (может быть где угодно по ходу файла) и он выгружается при возврате, а у DLL точек входа много и такой файл остаётся в памяти пока его не выгрузят программно.

На самом деле EXE-файлы тоже могут оставаться после загрузки - например если это был командный процессор, который остаётся и поверх него может быть вызвано что-то ещё.

Ну и EXE файл может подвешиваться резидентом, подменяя некоторые системные вызовы в векторе переходов - например такими резидентами могут быть разные текстовые драйвера - на 42 символа в строке, на 64 символа в строке и т.д.

_________________
:dj: https://mastodon.social/@Shaos


26 Jan 2023 21:23
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Вспомнил, что изначально в 90х я задумывал именно такое кодирование для расширения файлов, чтобы первые несколько вариантов использовались для поиска исполняемого файла для выполнения команды, если она была задана без расширения - сначала ищется файл .BAT, потом .SYS, потом .COM и уже в самом конце - .EXE:
Shaos wrote:
Вот "осовремененный" список стандартных расширений ShaOS (добавил специфические для ZX форматы в конец и SHJ):
0 - (три пробела) будет означать имя директория (точка при этом не печатается);
1 - .BAT для пакетных файлов;
2 - .SYS для перемещаемых "системных" программ (точность перемещения 1 байт, могут быть перенесены после загрузки);
3 - .COM для неперемещаемых программ, оттранслированных для какого-то конкретного адреса;
4 - .EXE для перемещаемых программ (точность перемещения 256 байт, не могут быть перенесены после загрузки);
6 - .OVL для оверлеев, оттранслированных в какой-то конкретный адрес (загружаются из COM);
6 - .DLL для перемещаемых библиотек (точность перемещения 256 байт, не могут быть перенесены после загрузки);
7 - .BAS для программ на языке Бейсик (не ZX);
8 - .INI для текстовых файлов конфигураций в интуитивно-понятном формате INI;
9 - .INC для включаемых ассемблерных файлов (не RASM);
A - .ASM для ассемблерных файлов (не RASM);
B - .BIN для бинарных данных, не привязанных к конкретным адресам;
C - .CPP для программ на Си++ (так было задумано в 1996 году)
D - .DAT для произвольных данных, которые могут быть перемещаемы по памяти;
E - .TXT для обычных досовских текстовых файлов в альтернативной кодировке;
F - .TMP для временных файлов;
Потом можно ещё 16 кодов добавить - от #10 до #1F:
#10 - .SCR для ZX-экранов (включая таймекс);
#11 - .ATR для ZX-атрибутов;
#12 - .IMG для ZX-экранов в формате Gigascreen;
#13 - .SNA для ZX-образов;
#14 - .Z80 для ZX-образов;
#15 - .SZX для ZX-образов;
#16 - .TAP для ZX-лент;
#17 - .TRD для обрезанных образов TR-DOS;
...

Кроме того если код расширения файла представляет из себя код печатного символа (#20...#7E), то он будет считаться однобуквенным расширением - примеры:
.A - текст программы для RASM;
.B - бейсик программа ZX;
.C - код для ZX;
.D - данные для ZX;
.L - файл статической библиотеки (для будущих версий nedoPC SDK);
.O - объектный файл (для будущих версий nedoPC SDK);
.R - текст программы на языке Robby (для nedoPC SDK);
.N - скрипт для nedoPC SDK (бывший SHJ).
В будущем могут быть .c и .h (для программ на языке Си), но пока ограничимся только большими буквами...


Attachments:
ShaOS-extensions.jpg
ShaOS-extensions.jpg [ 130.61 KiB | Viewed 3310 times ]

_________________
:dj: https://mastodon.social/@Shaos
27 Jan 2023 22:31
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Shaos wrote:
Смотрю в свои старые тетрадки - весной 1994 я выдумал способ писать перемещаемые программы для 8080 под названием SYS-TRANS - суть в том, что переходы и вызовы подпрограмм по конкретным адресам (а также обращение к памяти за данными) происходят не напрямую, а через специальные подпрограммы, которые модифицируют адрес в соответствии с тем, в каком месте памяти загружена такая программа. Вот слегка переработанный вариант такого подхода, который можно вставить в новую ShaOS:

Предположим у нас есть подпрограмма SYS по адресу #CCFC, которая при вызове залезает по адресу возврата и берёт один или более байтов идущих следом за вызовом, чтобы сделать сдедующее:
CD FC CC 00 - корректировка регистровой пары BC путём прибавления к ней базового адреса загрузки SYS-программы;
CD FC CC 10 - корректировка регистровой пары DE путём прибавления к ней базового адреса загрузки SYS-программы;
CD FC CC 20 - корректировка регистровой пары HL путём прибавления к ней базового адреса загрузки SYS-программы;
CD FC CC 30 - по адресу HL находитя имя SYS-программы (с аргументами), которую надо загрузить (если ещё не загружена) и выполнить;
CD FC CC xx yy zz - во всех остальных случаях базовый адрес прибавляется к zzyy и оно вместе с xx копируется в специальную область памяти, где находятся 6 байтов:
xx yy' zz' C3 aa bb - где bbaa это адрес следующего за zz байта, т.е. таким образом можно корректировать адреса в трёхбайтовых командах 8080 - таких как условные переходы или условная передача управления.
К сожалению такой способ не будет работать с вызовом подпрограмм - по видимому надо сделать отдельный спец.вызов для CALL:
CD FC CC CD aa bb - вызов подпрограммы с возвратом на следующий адрес после bb (надо ли такой же подход распространять на условные вызовы подпрограмм?).
В этом случае всё также надо скорректировать адрес aa bb, но вместо вызова инструкции CALL надо засунуть в стек адрес байта после bb и сделать JMP на модифицированный адрес bbaa.
Если аналогично поддержать условые вызовы подпрограмм (C4,D4,E4,F4,CC,DC,EC,FC) то там кроме первого условного джампа (соответствующего условию вызова подпрограммы) в специальную область памяти надо будет вписывать и второй безусловный JMP на адрес возврата, если условие не выполнится. Можно относительно быстро проверить что требуется сделать с кодом идущим следом за CD FC CC по его младшему нибблу:
x0 - простая корректировка регистровой пары BC,DE или HL, а также загрузка SYS-программ по имени, как описано выше (никаких инструкций с аргументами с этим кодом нет, поэтому ничего больше применяться не будет);
x1 - общий случай для инструкций 01 (LXI B, ...), 11 (LXI D, ...), 21 (LXI H, ...) и 31 (LXI SP, ...);
x2 - общий случай для инструкций 22 (SHLD ...), 32 (STA ...), C2 (JNZ ...), D2 (JNC ...), E2 (JPO ...) и F2 (JP ...);
x3 - общий случай только для инструкции C3 (JMP ...);
x4 - специальный случай для инструкций C4 (CNZ ...), D4 (CNC ...), E4 (CPO ...) и F4 (CP ...), которые при транслировании превращаются в C2 (JNZ ...), D2 (JNC ...), E2 (JPO ...) и F2 (JP ...) соответственно (т.е. минус 2);
x5...x9 - инструкций с 2-байтовым аргументом среди таких кодов нет;
xA - общий случай для инструкций 2A (LHLD ...), 3A (LDA ...), CA (JZ ...), DA (JC ...), EA (JPE ...) и FA (JM ...);
xB - инструкций с 2-байтовым аргументом среди таких кодов нет;
xC - специальный случай для инструкций CC (CZ ...), DC (CC ...), EC (CPE ...) и FC (CM ...), которые при транслировании превращаются в CA (JZ ...), DA (JC ...), EA (JPE ...) и FA (JM ...) соответственно (т.е. минус 2);
xD - специальный случай только для инструкции CD (CALL ...), которая при транслировании превращается в C3 (JMP) или минус 10;
xE...xF - инструкций с 2-байтовым аргументом среди таких кодов нет.
Соответственно можно одним массивом из 16 байт определить все наши действия (там будет либо величина смещения кода инструкции, либо #FF для идентификации ошибочного выбора):
Code:
SYS_ACTION DB #00,#00,#00,#00,#02,#FF,#FF,#FF,#FF,#FF,#00,#FF,#02,#0A,#FF,#FF
Если вдруг по ошибке программист применит неприемлиемый код, например FE (CPI n) типа CD FC CC FE n ... то при обработке такого вызова можно завершить исполнение с печатью ошибки в терминале. А вот если кто-то воспользуется неправильной командой из покрываемой колонки (например OUT n с кодом D3), то последствия могут быть непредсказуемыми, т.к. транслятор будет ожидать 2-байтовый аргумент и произведёт с ним соответствующие манипуляции (прибавит базовый адрес SYS-программы).

Такой подход может упростить ассемблирование т.к. теперь можно просто писать программу с ORG 0 и обычными мнемониками типа JMP, CALL и т.д.:
Code:
SYS EQU #CCFC

 ORG 0
....
 CALL @SYS
 CALL SUB1 \ вышестоящий вызов прочитает эти 3 байта и передаст управление на PUSH L1+base;JMP SUB1+base
L1:
...
SUB1:
 ...
 CALL @SYS
 CZ SUB2 \ вышестоящий вызов прочитает эти 3 байта и передаст управление на PUSH L2+base;JZ SUB1+base; JMP L2+base
L2:
 RET
SUB2:
 ...
 RET

Для спец.кодов #00, #10, #20 и #30 можно завести макросы:
Code:
SYS_TRANS_BC EQU #00
SYS_TRANS_DE EQU #10
SYS_TRANS_HL EQU #20
SYS_TRANS_RUN EQU #30
...
  LXI_H, VAR
  CALL @SYS
  DB @SYS_TRANS_HL
  \ тут в HL будет реальный адрес VAR с учётом смещения
...
VAR DB 0
Вроде ничего не перепутал и все варианты учёл - есть у кого какие мысли по этому поводу?

Таким образом можно реализовать подгружаемые команды ОС в частности CD.SYS и DIR.SYS - будучи единожды запущены они останутся в памяти (в перемещённом виде) для более быстрого дальнейшего запуска.

Для вывода списка загруженных SYS-программ, а также для их выборочного удаления из памяти с компактированием, можно сделать отдельную COM или EXE программу, чтобы не нагружать этим функционалом ядро ОС.

_________________
:dj: https://mastodon.social/@Shaos


27 Jan 2023 23:23
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
У меня была мысль задавать имя подгружаемой SYS-программы (с возможными аргументами) не через указатель HL, а следом за вызовом подпрограммы загрузки:

CD FC CC #30 'D' 'I' 'R' #00

Но потом я таки остановился на варианте с HL:
Code:
   LXI_H, SYSFILE
   CALL @SYS
   DB @SYS_TRANS_RUN
   ...
SYSFILE DB "DIR",0
Если этот код запущен изнутри другой SYS-программы, то ненулевой адрес смешения SYS_BASE (адрес начала текущей SYS-программы) будет использован чтобы модифицировать HL для чтения имени.
Если же этот код запущен из обычной EXE или COM программы (или из ядра ОС), то SYS_BASE в данном случае будет нулевым и никакой коррекции не произоёдёт.
Кстати при вызове SYS-программы из SYS-программы надо в стек возвратов затолкать ещё и предыдущее значение SYS_BASE, чтобы по возврату его можно было восстановить.
Ещё один момент - у SYS-программ нет своего стека - вся работа происходит в стеке программы вызвавшей SYS-программу.

_________________
:dj: https://mastodon.social/@Shaos


28 Jan 2023 01:21
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
На сегодняшний момент существует ядро ОС с большинством функций, способное подгружать из внешнего ПЗУ программы с расширением .COM и запускать их. В моей операционной системе COM-файлы не обязательно оттранслированы с адреса #0100 - они могут быть оттранслированы с любого адреса (адрес начала указывается в заголовке файла), но этот адрес должен быть согласован с конкретной реализацией ShaOS - например в случае РК86 таким адресом может быть #0000 (ну или #0100, чтобы была возможность "симулировать" CP/M-80), а в тесте, что я запускал на своём Урала-64К, этот адрес был #E800. Для дальнейшей разработки можно принять такой план, чтобы система оставалась работоспособной в каждом пункте:

  1. COM-файлы (уже есть);
  2. SYS-файлы (обсуждение выше);
  3. OVL-файлы (может понадобиться в скором будущем);
  4. EXE-файлы (перемещаемые с битовой маской);
  5. BAT-файлы (простой командный процессор);
  6. DLL-файлы (по аналогии со спринтеровским либманом);
  7. BAT-файлы (продвинутый командный процессор).

Для версии под ZX-спектрум я могу задействовать свою платку Romulus 32K, с которой система будет "бутаться" и на которой может содержаться ромдиск с файлами. Можно вернутся к тому, что я делал в 1997 году - Урал-48К с внешним ромдиском, подключаемым к бортовой ВВ55. Для российских клонов ZX с диском можно сделать тестовую сборку в формате TRD чтобы демонстрировать возможностей системы ShaOS на эмулях и реалах с TR-DOS. Также можно реанимировать nedoPC-85-A и сделать версию для него (всё должно уместиться в ПЗУ 8 Кб либо придётся цеплять внешний SPI EEPROM для хранения файлов). Ну и Radio-86RK 128KB надо дособирать - там тоже ShaOS может заработать. :rotate:

_________________
:dj: https://mastodon.social/@Shaos


28 Jan 2023 02:27
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Shaos wrote:
Такой подход может упростить ассемблирование т.к. теперь можно просто писать программу с ORG 0 и обычными мнемониками типа JMP, CALL и т.д.:
Code:
SYS EQU #CC0F

 ORG 0
....
 CALL @SYS
 CALL SUB1 \ вышестоящий вызов прочитает эти 3 байта и передаст управление на PUSH L1+base;JMP SUB1+base
L1:
...
SUB1:
 ...
 CALL @SYS
 CZ SUB2 \ вышестоящий вызов прочитает эти 3 байта и передаст управление на PUSH L2+base;JZ SUB1+base; JMP L2+base
L2:
 RET
SUB2:
 ...
 RET
Более того - можно даже условную компиляцию применить, чтобы можно было собирать один и тот же исходник и как SYS файл, и как COM файл (и даже как EXE):
Code:
#ifdef SYSTRANS
 ORG 0
#else
 ORG #E800
#endif
....
#ifdef SYSTRANS
 CALL @SYS
#endif
 CALL SUB1 \ вышестоящий вызов прочитает эти 3 байта и передаст управление на PUSH L1+base;JMP SUB1+base
L1:
...
SUB1:
 ...
#ifdef SYSTRANS
 CALL @SYS
#endif
 CZ SUB2 \ вышестоящий вызов прочитает эти 3 байта и передаст управление на PUSH L2+base;JZ SUB1+base; JMP L2+base
L2:
 RET
SUB2:
 ...
 RET

Самодельный простой препроцессор у меня уже с 2008 года имеется: https://gitlab.com/nedopc/sdk/-/blob/master/utils/minicpp.c
(я его делал для собственной досовской сборки тунгуски, а потом включил в состав nedoPC SDK)

_________________
:dj: https://mastodon.social/@Shaos


28 Jan 2023 14:45
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Ещё мысль о совместимости.

В данный момент подразумевается, что флаги в заголовке файла будут иметь биты совместимости:
00 - 8080
01 - 8085
10 - Z80
11 - см.расширенный заголовок (а там будет Z180 и т.д.)
Система будет понимать, что можно будет запускать на целевой платформе, а что нет.

Однако кроме процессора ещё должна быть совместимость по железу - в частности по графике.
Думаю должно быть достаточно задавать тип компьютера где-то в недрах ShaOS с возможность выдать строку по запросу:
ZX
ZX128K
ZX2068
ZXATM
NPC85A
RK86
ORION
SPETS
SPETSMX (максимум 7 байт плюс ноль?)
т.е. скажем программа, использующая графику ZX-спектрума, при запуске проверит слово-описатель компьютера, и если первые 2 буквы в нём не ZX, то программа выйдет с ошибкой.

_________________
:dj: https://mastodon.social/@Shaos


29 Jan 2023 04:57
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Shaos wrote:
Shaos wrote:
Смотрю в свои старые тетрадки - весной 1994 я выдумал способ писать перемещаемые программы для 8080 под названием SYS-TRANS - суть в том, что переходы и вызовы подпрограмм по конкретным адресам (а также обращение к памяти за данными) происходят не напрямую, а через специальные подпрограммы, которые модифицируют адрес в соответствии с тем, в каком месте памяти загружена такая программа. Вот слегка переработанный вариант такого подхода, который можно вставить в новую ShaOS:

Предположим у нас есть подпрограмма SYS по адресу #CCFC, которая при вызове залезает по адресу возврата и берёт один или более байтов идущих следом за вызовом, чтобы сделать сдедующее:
CD FC CC 00 - корректировка регистровой пары BC путём прибавления к ней базового адреса загрузки SYS-программы;
CD FC CC 10 - корректировка регистровой пары DE путём прибавления к ней базового адреса загрузки SYS-программы;
CD FC CC 20 - корректировка регистровой пары HL путём прибавления к ней базового адреса загрузки SYS-программы;
CD FC CC 30 - по адресу HL находитя имя SYS-программы (с аргументами), которую надо загрузить (если ещё не загружена) и выполнить;
CD FC CC xx yy zz - во всех остальных случаях базовый адрес прибавляется к zzyy и оно вместе с xx копируется в специальную область памяти, где находятся 6 байтов:
xx yy' zz' C3 aa bb - где bbaa это адрес следующего за zz байта, т.е. таким образом можно корректировать адреса в трёхбайтовых командах 8080 - таких как условные переходы или условная передача управления.
К сожалению такой способ не будет работать с вызовом подпрограмм - по видимому надо сделать отдельный спец.вызов для CALL:
CD FC CC CD aa bb - вызов подпрограммы с возвратом на следующий адрес после bb (надо ли такой же подход распространять на условные вызовы подпрограмм?).
В этом случае всё также надо скорректировать адрес aa bb, но вместо вызова инструкции CALL надо засунуть в стек адрес байта после bb и сделать JMP на модифицированный адрес bbaa...
Пытаюсь вспомнить почему я год назад решил, что озвученный выше подход не будет работать с вызовами подпрограмм :roll:

Допустим у нас есть SYS-TRANS программа, оттранслированная с адреса #6000 и по смещению #1000 там стоит транс-вызов подпрограммы:
Code:
7000 CD FC CC CD FF 07 ; тут мы хотим вызвать подпрограмму по смещению 7FF
7006 ; сюда должно вернутся управление после завершения подрограммы
По старому подходу в специальной области памяти генерируется следующий код, на который и будет передано управление:
Code:
CD FF 67 C3 06 70 ; вызов подпрограммы по скорректированному адресу #67FF и дальнейшая передача управления на #7006
И почему это не будет работать? По-моему очень даже будет! Причём даже с условными вызовами...

P.S. PUSH работает быстрее, чем SHLD, так что наверное спец область должна иметь не JMP NN, а RET (а правильный адрес возврата будет предварительно записан в стек).

P.P.S. Заодно везде исправил адрес подпрограммы SYS на #CCFC (последний адрес в векторе переходов ShaOS), в котором эта подпрограмма скорее всего в итоге и будет сидеть...

_________________
:dj: https://mastodon.social/@Shaos


24 Feb 2024 23:09
Profile WWW
Devil

Joined: 26 May 2003 06:57
Posts: 859
Reply with quote
Shaos wrote:
Пытаюсь вспомнить почему я год назад решил, что озвученный выше подход не будет работать с вызовами подпрограмм

Видимо потому, что очень хотелось оставить возможность передавать параметры следом за командой CALL.

_________________
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/


26 Feb 2024 06:37
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
b2m wrote:
Shaos wrote:
Пытаюсь вспомнить почему я год назад решил, что озвученный выше подход не будет работать с вызовами подпрограмм

Видимо потому, что очень хотелось оставить возможность передавать параметры следом за командой CALL.

Да вроде не хотелось :roll:

Надо оставить себе заметочку на полях - более расширенно описывать проблему и процесс обдумывания тех или иных решений, чтобы потом спустя годы не ломать голову зачем я это написал :oops:

_________________
:dj: https://mastodon.social/@Shaos


26 Feb 2024 08:42
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 55 posts ]  Go to page Previous  1, 2, 3, 4

Who is online

Users browsing this forum: No registered users and 21 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.