Решил проблему. Похоже, нумерация логических страниц в блоке с единицы...
Заменил номера страниц с 0 и 1 на 1 и 2 - заработал правильный выход в ОС.
¡Un momento, señor fiscal!
нумерация страниц в блоке таки с нуля (0,1,2...)
а возврат в DSS у нас такой:
либо RST 0 который вызывает тоже самоеКод:; Exit program exit: ld bc,0041h rst 10h
- - - Updated - - -
и зачем SP переставлять вручную, если DSS при загрузке EXE всё равно ставит в тот SP который в хедере? и соответственно при выходе в DSS через 41h всё вернётся туда где было
Администратор сетевого сообщества nedoPC.org
Урал 8/64К, Sp2000, ZX48K+, ZX16K (спалил), TS1000 (американский ZX81), TS2068, Дельта-С, 20 лет собираю ATM Turbo 2+
Неспектрумы: Электроника МК-85 и МК-85М, ПК-01 Львов, БК-0011, Вектор-06Ц, Лик (спец), Апогеи, Radio-86RK SRAM 32K & 128K (всё ещё собираю)
Хотел сделать обработку клавиатуры в прерывании через функцию ОС scankey. Вот так:
Почему-то это не работало...;здесь обработка клавиатуры
Ld a,(OldWin0Page); восстанавливаем системную страницу
out (0x82),a
ld a,0
ld (scankey),a
LD C,0x31 ;Функция опроса клавиатуры без ожидания
RST 0x10
JR Z,int2body1
ld a,d
and 127 ;убираем седьмой бит
ld (scankey),a
int2body1:
Ld a,(Win0Page)
out (0x82),a
Пришлось писать обработку AT-клавиатуры самому. Вот код:
Работает. Программа реагирует на клавиши направлений(стрелки) и ескейп. В каждое отдельное прерывание работает только треть кода: либо фиксация в переменной кода нажатой клавиши, либо отлов отжатия F0, или отлов отжатия расширенного кода E0F0. Прошу потестить на реале, так как есть подозрение что эмулятор не пропускает клавиши PrintScreen и Pause\Break. Нужно проверить - нажатие этих клавиш не приведёт ли к отключению реакции на клавиши? Алгоритм обработки нажатий реагирует на обычные( однобайтовые коды нажатий и двубайтовые отпусканий) и расширенные( двубайтовые для нажатий и трёхбайтовые для отпусканий) коды, но не на дополнительные. Вот, нажатие ПринтСкрин и Паузы может привести к непредсказуемым результатам, так как они имеют дополнительные коды( 4-6 байт). Есть подозрение, что нажатие Паузы заблокирует клавиатуру.;Клавиатура
SerialChAData EQU #18 ;регистр данных канала A последовательного порта контроллера Z84
SerialChACtrl EQU #19 ;контролирующий регистр канала A последовательного порта контроллера Z84
kbMoveUp EQU 0x75 ;стрелка вверх
kbMoveDown EQU 0x72 ;стрелка вниз
kbMoveLeft EQU 0x6B ;стрелка влево
kbMoveRight EQU 0x74 ;стрелка вправо
kbEsc EQU 0x76 ;ескейп
target defb 0 ;код нажатой клавиши
scankey defb 0
pflag defb 0
eflag defb 0 ;флаг расширенных кодов
fflag defb 0 ;флаг заполнения буфера
;_____________________________
;обработчик прерывания
int2m:
di
push af
push bc
push de
push hl
ld a,(tick)
cp 2
jr nc, int2body
inc a
ld (tick),a
int2body:
;здесь обработка клавиатуры AT[ps/2 scan set 2]
keys:
ld a,(target) ; проверяем переменную со сканкодом нажатой клавиши
or a
jp nz, keystep2 ;если не ноль, то переходим к отлову отжатия клавиши
;иначе проверяем сканкод нажатой клавиши
call scan
ld d,a
ld a,(fflag) ;проверяем буфер клавиатуры по флагу заполнения
or a
jp z, player ;если пуст - выходим
ld a,d
cp 0xF0; ;клавиша отжата?
jr nz, keystep11 ;нет - проверяем на байт расширения
call scan; ;иначе, освождаем буфер и выходим
jp player
keystep11:
cp 0xE0; ;проверка на байт расширения
jr nz,keystep12 ;если нерасширенный код, то переходим на обработку нерасширенных кодов
call scan ;иначе, читаем буфер и сравниваем с
cp 0xF0 ;кодом отжатия расширенного кода
jr nz,keystep13 ;если не отжатие, то расширенный код, переходим на обработку расширенных кодов
call scan ;иначе, освобождаем буфер и выходим
jp player
keystep13:
ld (target),a ;запоминаем расширенный код
ld a,1
ld (eflag),a ;устанавливаем флаг расширенного кода и выходим
jp player
keystep12:
ld (target),a ;запоминаем нерасширенный код
xor a
ld (eflag),a ;сбрасываем флаг расширенного кода и выходим
jp player
keystep2:
ld a,(eflag) ;по флагу расширенных кодов определяем какое отжатие ловить
or a
jr z, keystep_for_F0 ;если флаг сброшен, ловим простое отжатие F0 нерасширенных кодов
;иначе, отлов расширенного отжатия EOFO расширенных кодов
call scan
ld d,a
ld a,(fflag)
or a
jp z, player ;буфер пуст? да - выход
ld a,d
cp 0xE0 ;расширенный код?
jr nz,F0compare ;нет - проверка на обычное отжатие
call scan ;иначе,читаем буфер
cp 0xF0 ;проверка на расширенное отжатие
jr nz, player ;если не расширренное отжатие, то освобождаем буфер и выход
call scan ;иначе, читаем расширенный код клавиши, которая была отжата
ld b,a
ld a,(target)
cp b ;сравниваем код отжатой клавиши с клавишей, которая была нажата
jr nz, player ;если коды не совпадают - выход
;ld (scankey),a
xor a
ld (target),a ;иначе, сбрасываем переменную для кода нажатой клавиши
ld (eflag),a ; и сбрасываем флаг расширенных кодов
jr player ;выход
F0compare:
cp 0xF0 ;обычное отжатие?
jr nz, player ;нет -выход
call scan ;да - освобождаем буфер и выход
jr player
;отлов F0 (обычного отжатия нерасширенных кодов)
keystep_for_F0:
call scan ;читаем буфер
ld d,a
ld a,(fflag)
or a
jp z, player ;если буфер пуст - выход
ld a,d
cp 0xF0 ;обычное отжатие?
jr nz, E0compare ;если нет - проверка расширенных кодов
call scan ;иначе, читаем код отжатой клавиши
ld b,a
ld a,(target)
cp b ;сравниваем код отжатой клавиши с клавишей, которая была нажата
jr nz, player ;если коды не совпадают - выход
;ld (scankey),a
xor a
ld (target),a ;иначе, сбрасываем переменную для кода нажатой клавиши
jr player ;выход
E0compare: ;отлов расширенных кодов для освобождения буфера
cp 0xE0 ;расширенный код?
jr nz, player ;если нет - выход
call scan ;иначе, читаем буфер
cp 0xF0 ;расширенное отжатие?
jr nz, player ;если нет - выход
call scan ;иначе, освобождаем буфер от кода отжатой клавиши и выход
jr player
;работа c плеером
player:
pop hl
pop de
pop bc
pop af
ei
reti
;_______________________________
scan:
;проверка есть ли данные от клавиатуры
IN a,(SerialChACtrl) ;бит0 = 0 - нет данных;бит0 = 1 - есть данные
and 1
ld (fflag),a
JR z,scanexit
;если данные есть
IN a,(SerialChAData)
scanexit:
ret
Ссылка на образ диска https://dropmefiles.com/9jsV5
Может, кто приведёт пример более оптимального кода обработки нажатий клавиш клавиатуры? У меня слишком громоздкий получился.
Полезные ссылки по теме:
https://dvsav.ru/at-ps2-keyboard/
https://ru.wikipedia.org/wiki/%D0%A1...BA%D0%BE%D0%B4
Смотрел ещё исходники Клада от CHRV. Там обработчик совсем другой и для других целей( обработка нажатий нескольких клавиш). Мне не подойдёт.
Последний раз редактировалось Smalovsky; 01.09.2021 в 16:42.
¡Un momento, señor fiscal!
в обработчике прерываний DSS лучше не вызывать
тем более клавишные подпрограммы - DSS ведь само по прерыванию инфу про кнопки берёт
говорят, что клавиатуру можно по ZX-спектрумовски читать даже в режиме Спринтера - я не пробовал, ну и там естественно без курсорных и расширенных клавиш будет...
Администратор сетевого сообщества nedoPC.org
Урал 8/64К, Sp2000, ZX48K+, ZX16K (спалил), TS1000 (американский ZX81), TS2068, Дельта-С, 20 лет собираю ATM Turbo 2+
Неспектрумы: Электроника МК-85 и МК-85М, ПК-01 Львов, БК-0011, Вектор-06Ц, Лик (спец), Апогеи, Radio-86RK SRAM 32K & 128K (всё ещё собираю)
Shaos, мне бы кто на реале посмотрел тест клавитуры и отписался, клавиши ПринтСкрин и Пауза блокируют ли программу. Нужно стрелки понажимать чтоб квадратик подвигался, а затем нажать ПринтСкрин и Паузу в любом порядке, и затем снова стрелки. Эмулятор клавиши Принтскрин и Паузы не передаёт программе,поэтому я не знаю что будет на реале при нажатии этих клавиш.
Просто, если есть возможность, погоняй на реале, напиши на форум какой результат. Нужно узнать работают ли стрелки после нажатия клавиш ПринтСкрин и Пауза. Обработку клавиатуры я делаю для игры.
Образ диска https://dropmefiles.com/9jsV5
Последний раз редактировалось Smalovsky; 02.09.2021 в 14:16.
¡Un momento, señor fiscal!
У меня сейчас Спринтер в разобранном виде (переезжает со стола в ПЦ-корпус) - может Сайман или RomanRom2 смогут позапускать
Администратор сетевого сообщества nedoPC.org
Урал 8/64К, Sp2000, ZX48K+, ZX16K (спалил), TS1000 (американский ZX81), TS2068, Дельта-С, 20 лет собираю ATM Turbo 2+
Неспектрумы: Электроника МК-85 и МК-85М, ПК-01 Львов, БК-0011, Вектор-06Ц, Лик (спец), Апогеи, Radio-86RK SRAM 32K & 128K (всё ещё собираю)
Smalovsky, проверил. после запуска нажал на стрелку вправо. кубик начал движение. как его остановить? при нажатии на esc реакции нет. кубик доезжает до (почти) границы экрана и всё зависает. кубик за собой оставляет какие то полоски, с шагом и возрастанием. потом после ребута запустил снова. нажал на курсор вниз. кубик поехал вниз. далее всё аналогично. реакции на pause или print screen никакой нет.
Не знаю почему у тебя не работает опрос на прерываниях.
У меня опрос клавиатуры нормально работал, я делал так:
Обработчик прерваний в конце вызывает RST #38 (досовский обработчик прерываний IM1):
В коде проверка клавиатуры:Im2Handler:
di
push all
...
pop all
ei
rst #38
CheckKeys:
ld c,Dss.ScanKey
rst #10
ret z ;ничего не нажато
;определение нажатой кнопки
ret
Непонятно. В эмуляторе всё работает. Надо бы, что бы ещё кто на спринтере проверил.
Это исправил.
Вот видео работы обновленной программы на эмуляторе( теперь уже спрайт двигается на фоне):
Возможно проблемы с клавиатурой в этом кусочке программы:
Это надо разбираться с последовательным портом будет.scan:
;проверка есть ли данные от клавиатуры
IN a,(SerialChACtrl) ;бит0 = 0 - нет данных;бит0 = 1 - есть данные
and 1
ld (fflag),a
JR z,scanexit
;если данные есть
IN a,(SerialChAData)
;вот тут возможно нужно что-то отправить в порт SerialChACtrl, что бы разрешить дальнейшую пересылку данных от клавиатуры
scanexit:
ret
Программа для тестирования:
https://dropmefiles.com/4hFOg
Последний раз редактировалось Smalovsky; 09.09.2021 в 17:50.
¡Un momento, señor fiscal!
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)