Максагор, NedoPC group
ПК ATM-turbo 2+ 1024Kb RAM, 1,7Gb HDD, CD-ROM, Turbo FM, GS-512
[ZX rulezzz 4reva!!!]
http://atmturbo.nedopc.com
http://vk.com/atmturbo
http://maksagor.livejournal.com
http://moskprf.ru
[СССР][Коммунизм][КПРФ] ну [ZX], естественно...
Если не экономить память, то есть очень дубовый способ. Пусть программа в памяти, набираем в строке редактирования RUN (без enter). Сохраняем системные переменные и саму программу. Теперь когда надо запустить возвращаем системные переменные и программу на место и переходим по адресу 12DDh. Несомненно этот способ можно улучшить и оптимизировать, но если других вариантов пока нет, то он работает.
я кстати делал похожим способом, только кажется в первой строке исполнялось pause 0,
запустив сохранял память, потом сжимал ну и после разжима делал jp в ПЗУ
Для сохранения памяти нужно входить в TR-DOS и делать сохранение области с #5B00 и до конца памяти. Но при этом же не сохранится команда RUN, она же не будет набрана.
Заяц-прусак
zxbyte.ru- компьютер Байт и прочий хлам
я сохранял память под эмулем.
в ZXreview скорее всего делали автостарт программы в составе кодового блока.
первая строка бейсика что-то типа
1 save "test" code 23552,1704
2 текст программы
на момент отгрузки в переменных будет следующая строка/оператор
но это явно не твой случай
..........
вспомнил. я делал перехват на адресе #2D2B; BC=№номер строки
загрузив программу на бейсике ставил BreakPoint и выполнял gotoX
после этого сохранял всю память, сжимал и после загрузки/разжатия (важно правильно выставить стек)
делал jp #2d2b
..........
этот способ я подсмотрел в игре I of the Mask
Последний раз редактировалось goodboy; 09.10.2020 в 23:08.
Если программа на бейсике занимает не всю память, то стоит ограничиться только ей (посмотреть в отладчике эмулятора где она оканчивается) + системные переменные до нее.
Сохранение из TR-DOS обязательное условие (его не было в посте с вопросом)? Если нет, то goodboy написал про сохранение из эмулятора.
Еще я забыл важный момент. Стартовые условия могут быть разные, поэтому лучше задать ld iy,5C3Ah. Содержимое стека, насколько помню, в "моем" варианте сохранять не обязательно.
Последний раз редактировалось ivagor; 10.10.2020 в 07:30.
Способов запустить бейсик-программу из ассемблера существует великое множество, но все они должны быть основаны на анализе дизассемблера бейсика (Ian Logan, Frank O'Hara, "The complete ZX Spectrum ROM disassembly"). Потому, что документированных и облегчённых способов запуска нет, а остальные подразумевают "обман" в той или иной форме, подстановка бейсику того, что он увидит так, как хочется автору.
Вариент - изучить процедуру "Load" с кассеты. Там после загрузки заголовка сначала ликвидируется "старая", находящаяся в памяти, программа. Затем выделяется память под новую программу и её переменные. И, наконец, загружается и запускается новая программа.
Изучив процедуру "Load", можно реализовать её заново в своём коде, выбросив оттуда лишнее и вставив недостающее.
Что я только что и проделал. Для понимания изложенного ниже требуется скачать и открыть Логана и ОХару.
Интересующая нас часть процедуры "Load" находится по адресу 0x0873 под названием "LD-PROG".
Сначала вызовом процедуры "RECLAIM-1" освобождается память от "старой" программы. Затем вызовом "MAKE-ROOM" выделяется память под новую программу и её переменные. Освобождение и выделение памяти через "RECLAIM-1" и "MAKE-ROOM" освобождают программиста от заботы о системных переменных в этих процессах.
После этого из кассетного заголовка извлекается длина программы без учёта длины её переменных и устанавливается системная переменная "VARS" на начало области переменных.
Далее номер строки, с которой программа должна запуститься, заносится в системную переменную "NEWPPC", а номер оператора в строке (системная переменная NSPPC) - обнуляется.
Остальное - дело техники. В подготовленную память просто загружается блок с кассеты и идёт возврат в основной цикл интерпретации, где загруженная программа начинает исполняться.
Если ассемблерная программа была вызвана из бейсика (например, по RANDOMIZE USR) - то больше ничего делать не надо, можно просто вернуться из USR.
- - - Добавлено - - -
Добавка. Если ассемблерная программа была вызвана не через USR, а каким-то другим способом - то точка входа в интерпретатор для начала исполнения программы - это 0x1B7d, "STMT-R-1".
Перед переходом на неё необходимо загрузить указатель стека из системной переменной ERR-SP: LD SP,(23613)
- - - Добавлено - - -
Если же системные переменные испорчены, и требуется их полная инициализация - то она находится в бейсике по адресам 11EF-12A2. Объём этого кода короче, чем сохранённая копия всех системных переменных.
- - - Добавлено - - -
Ещё немного подумал. Возврат из USR, описанный выше, может привести к сбою, так как USR - это функция, являющаяся частью выражения. Если для команды LOAD допустимо возвращаться с подменой программы, то для USR - нет.
В случае LOAD идёт возврат из исполнения команды на цикл исполнения программы. Так как системная переменная NSPPC была обнулена, то поиск строки к исполнению начинается заново, что и приводит к запуску загруженной программы без учёта того, что находилось в области памяти, где была команда LOAD и что следовало за ней.
Но вызов ассемблерной программы через USR - это не команда, а часть выражения. USR - это функция, а выражение может продолжаться после неё. Таким образом, если ассемблерная программа перепахала память, где находился вызов функции USR - то вычисление выражения будет продолжено с того же места, а так как там уже находится другая программа - то скорее всего это приведёт к ошибке C Nonsense in BASIC.
Так что запуск программы только через STMT-R-1 и инициализацию стека.
Prusak (11.10.2020)
Кое-какие результаты есть: программа работает, но при попытке её остановка и выхода в бейсик, всё подвисает.
Заяц-прусак
zxbyte.ru- компьютер Байт и прочий хлам
Вероятнее всего, адрес возврата в стеке (ERR_SP) неправильный. Каким образом ты добился запуска программы?
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)