Возвращаюсь в BasicНе знаю даже зачем, в ZX-играх часто выход - это кнопка reset. Хотя если углубиться, то надо делать возможность выхода в TR-DOS.
Возвращаюсь в BasicНе знаю даже зачем, в ZX-играх часто выход - это кнопка reset. Хотя если углубиться, то надо делать возможность выхода в TR-DOS.
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Ну, собсна, если отказаться от выхода, то никакого специального кода для перехода в "48 с открытым портом" не надо. Просто не шли ничего в #7ffd и будет тебе щастье. А можешь и слать, лишь бы не включал 5-й бит, не писал в буфер принтера и на выходе была бы впечатана 0-я страница.
Собсна, изначальная твой проблема (про то, что мог оставить коммандер после себя) решается так: ld a,#10: out (#7ffd),a, больше ничего и не надо. Кстати, я загнался по поводу стека и обработки ошибок. SDCC же на старте программы выставляет стек сам? А как выглядит код завернешния программы, что там со стеком происходит? Что будет, если функциями модуля Basic сделать PRINT AT 255,255 или INK 255?
ZX Evolution Rev C + ZXM-SoundCard Extreme + NeoGS.
Алекс, SDCC использует код инициализации в crt0, который в ZXDev выглядит так:
Библиотека Basic имеет процедуры Init и Quit, причём по варианту для каждого режима прерываний - DI, IM1 и IM2. Исходники живут в ZXDev/Lib/C/Basic.c, но продублирую:Код:.module crt0 .globl _main jp _main
Модуль Basic мог бы инициализироваться автоматически, но я тогда сделал так, и уже потом не стал менять, оправдываясь тем, что некоторым процедурам не нужна инициализация.Код:void Basic_Init_DI (void) { __asm DI // LD IY,#0x5C3A RES 4,1(IY) /* RESET OF 128K FLAG */ __endasm; } //Basic_Init_DI /*--------------------------------- Cut here ---------------------------------*/ void Basic_Init_IM1 (void) { __asm RES 4,1(IY) /* RESET OF 128K FLAG */ __endasm; } //Basic_Init_IM1 /*--------------------------------- Cut here ---------------------------------*/ void Basic_Init_IM2 (void) __naked { __asm RES 4,1(IY) /* RESET OF 128K FLAG */ ; ************************************************ ; * Set IM2 mode (need for correct work with IY) * ; ************************************************ LD HL,#IM2PROC$ IMON$: LD A,#24 ; код команды JR LD (#65535),A LD A,#195 ; код команды JP LD (#65524),A LD (#65525),HL ; в HL - адрес обработчика прерываний LD HL,#0xFE00 ; построение таблицы для векторов прерываний LD DE,#0xFE01 LD BC,#256 ; размер таблицы минус 1 LD (HL),#0xFF ; адрес перехода #FFFF (65535) LD A,H ; запоминаем старший байт адреса таблицы LDIR ; заполняем таблицу DI ; запрещаем прерывания на время ; установки второго режима LD I,A ; задаем в регистре I старший байт адреса ; таблицы для векторов прерываний IM 2 ; назначаем второй режим прерываний EI ; разрешаем прерывания RET IM2PROC$: PUSH AF PUSH BC PUSH DE PUSH HL PUSH IX PUSH IY __endasm; } void Basic__IM2ADR (void) { __asm CALL IM2RET$ POP IY POP IX POP HL POP DE POP BC POP AF EI IM2RET$: __endasm; } //Basic_Init_IM2 /*--------------------------------- Cut here ---------------------------------*/ void Basic_Quit_DI (void) { __asm LD HL,#0x2758 EXX LD IY,#0x5C3A EI __endasm; } //Basic_Quit_DI /*--------------------------------- Cut here ---------------------------------*/ void Basic_Quit_IM1 (void) { __asm LD HL,#0x2758 EXX LD IY,#0x5C3A __endasm; } //Basic_Quit_IM1 /*--------------------------------- Cut here ---------------------------------*/ void Basic_Quit_IM2 (void) { __asm DI LD HL,#0x2758 EXX LD IY,#0x5C3A LD A,#0x3F LD I,A IM 1 EI __endasm; } //Basic_Quit_IM2
Советуешь в Basic.Init добавить команды ld a,#10: out (#7ffd),a ?
Корректность аргумента INK я не проверяю (для скорости). А ПЗУ'шный вариант AT работает через RST 16:
Последний раз редактировалось Oleg N. Cher; 07.11.2015 в 13:49.
Странный синтаксис записи чисел...
Последний раз редактировалось drbars; 07.11.2015 в 14:08.
# во встроенном ассемблере SDCC - обязательный признак литерала. Это не я придумал.![]()
Все там почти хорошо. Я бы вот только не стал бы сбрасывать флаг 128-го BASIC'а, при обработке ошибок можно словить ахтунг. Кстати сказать, он при запуске скорее всего сброшен - USR работает в ПЗУ 48. Вместо этого лучше действительно принудительно впечатывать 0-ю страницу как минимум перед установкой IM 2 (а лучше всегда, она гарантированно быстрая). Перед впечтаыванием должно быть SP < #c000, это, я полагаю, делает BASIC-загрузчик командой CLEAR.
Последний раз редактировалось Alex Rider; 07.11.2015 в 16:32.
ZX Evolution Rev C + ZXM-SoundCard Extreme + NeoGS.
Скорее всего, флаг 128-го BASIC'а сбрасывается здесь чтобы спокойно использовать память буфера принтера.
А почему нельзя оставить активную страницу? Просто я подумал: а вдруг машкод программы юзера перекроет границу #C000? Значит впечатывать 0-ю страницу нужно до загрузки машкода в память, т.е. не иначе как из лоадера, а не из уже загруженного и запущенного кода.
Случай видится требующим особого подхода. Т.е. если пишется программа для >=128k, нужно разработать специальную библиотеку для работы со страницами, вторым экраном и т.д.
Последний раз редактировалось Oleg N. Cher; 08.11.2015 в 08:25.
В общем, поковырялся я в коде ПЗУ по поводу этого флага. Давай все же сначала поймем какую цель ты преследуешь. Из программы на Обероне можно выйти обычным способом, по ret на стеке с продолжением исполнения программы на BASIC'е? Если да, то принудительный переход в BASIC - это не дело. Если выход только по Halt(N), то можно перейти в 48K, только переход надо сделать тем кодом, который прислал тебе Wlodek. Кстати, а буфер принтера так критичен?
По большому счету, можно. Мы пришли к этому из-за того, что вектор прерывания лежит в #fe00...#feff, поэтому с #с000 должна быть впечатана быстрая страница. Во всем зоопарке фирменный машин быстрые страницы - только 0 и 2, а коммандер может оставить после себя впечатанной любую, в том числе и медленную страницу, то есть, есть небольшой риск получить на фирменной машине снег.
Итого: Принудительно впечатывать страницу 0 есть смысл только при использовании IM 2.
Да, это я облажался. Впечатывать страницу надо в загрузчике после CLEAR и перед загрузкой машкода (POKE 23388,16: OUT (32765),16).
ZX Evolution Rev C + ZXM-SoundCard Extreme + NeoGS.
Да, можно.
Тут играет роль мой специфический подход к кодированию для Спектрума, который, видимо, сформировался так потому что у меня не было 128k и я не ставил цели поддержать верхнюю память, но активно пользовался буфером принтера - для хранения переменных или как временный буфер, например, для скроллинга. Поэтому закономерно желание использовать буфер для этих целей вместо нахождения там непонятных для меня переменных 128k-BASIC'а. Я специально пишу про свой субъективный взгляд на эти вещи, чтобы вы видели перспективу. Дизайн библиотеки Basic нужно менять под 128k.
Да, притом из лоадера. Либо же использовать для этого специальную библиотеку, которую, быть может, кто-то разработает, если она ему понадобится.
Я начал разрабатывать утилиту makezx (на Обероне) - аналог bin2tap, порождающую Basic-лоадер, надо бы предусмотреть в ней такое впечатывание.
Ну как бы в целом общая рекомендация: коли ZXDev - инструмент разработки и набор библиотек, то использовать буфер принтера и отключать 128К явно не стоит. Потенциально может появиться продукт на 128-м BASIC'е, который захочет использовать код на Обероне или C или просто библиотеки ZXDev как подпрограммы - он обидится, если машкод принудительно включит 48К. Не надо делать втихаря неожиданнх для разработчика вещей.
- - - Добавлено - - -
Не получится. На Спектруме нельзя гарантированно узнать какая страница впечатана на момент вызова кода.
- - - Добавлено - - -
А лучше сразу под менеджер памяти с кастомными драйверами. Например, будет неплохо смотреться расширение - возможность печати симвла (строки) с указанием номера (адреса) шрифта и логического номера страницы, в которой шрифт лежит. Или запуск AY-проигрывателя с кодом и музыкой в произвольной странице. Или хотя бы просто загрузка некой более-менее самостоятельной библиотеки (как вариант - быстрая математика из Beta Basic) в страницу и вызов кода из нее.
ZX Evolution Rev C + ZXM-SoundCard Extreme + NeoGS.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)