Усть у кого-нибудь есть исходник правильного резидента ПП?
Чтобы в диспетчер процессов прописывался, обменивался с ЦП и корректно завершался....
Вид для печати
Усть у кого-нибудь есть исходник правильного резидента ПП?
Чтобы в диспетчер процессов прописывался, обменивался с ЦП и корректно завершался....
Я для своего примера утащил код из теста палитры. Там всё корректно завершается.
/* диспетчер процессов прописывался */
Я имел в виду немого другой резидент.. о котором пишет Худяков.. но довольно поверхностно:
"На мой взгляд, наиболее удобен третий путь, когда после выполнения каких-то действий программа в ПП отдает управление обратно диспетчеру процессов, предварительно поставив себя в очередь процессов в ПП. После этого программа из ЦП может получать команды с клавиатуры, печатать информацию на экране или принтере, работать с диском — все, как обычно. Но программа из ЦП может посылать команды также «спящей» программе в ПП, записывая их, например, в какую-то заранее определенную область ОЗУ ЦП."
чтобы не RTS PC в конце пп было, а
MOV AdrPgm,@#7124 ; Поставить в очередь процессов
MOV #1,@#7100 ; Потребовать обслуживания
MOV (SP)+,R0 ; Восстановить
JMP @#174170 ; Перейти к диспетчеру процессов
извиняюсь за офф-топ, но с образовательной целью и просто видео не без интересное
смотреть
Отконвертировал и добавил в формате УКНЦ все спрайты (пока в память влезают, убрал повторы и лишние фреймы), разобрался с описанием объектов..
Пока суть-да дело может кто подкинет идеи (исходники) по звуку? Типа в ячейку ЦП кладешь № звука - воспроизводит, ноль - молчит..
Заранее благодарен :)
S_V_B, есть звуковой генератор для спека. надо?
/* есть звуковой генератор для спека */
Вообще неплохо бы для УКНЦ, с его периферийным процессором.. но для общего развития.. буду рад ознакомится.
Бро ты много хочешь :)
освой хоть это
Код:;Steve Turner / Hewson Cons
;sfx engine
;used in Ranarama, Quazatron,IronMan
;можно вешать на прерывания или вызывать в основном цикле
;you can use this routine on interrupts (as autor)
;or in main game cicle
sound
ld a,(sonreq) ;новый звук играем?
and a
jr z,nonew ;нет
;да
ld (sonnow),a
dec a
jr z,noise ;#01 шум
ld hl,sfx_data
dec a
add a,a
add a,a
add a,a
ld e,a
xor a
ld (sonreq),a
ld d,a
add hl,de
ld bc,08
ld de,sonfrq
ldir
jr process
nonew ld a,(sonnow) ;а старый звук есть?
and a
ret z
dec a ;продолжать шум?
jr nz,process ;продолжать звук
jr cnois
noise ld a,0ah
ld (sonlen),a
xor a
ld (sonreq),a
cnois ld b,30h
gain call random
and 10h
out (0feh),a
ld c,02h
make dec c
jr nz,make
djnz gain
ld hl,sonlen
dec (hl)
ret nz
xor a
ld (sonnow),a
ret
process ld a,(sonfrq)
ld h,a
ld a,10h
ld d,0ffh
sonlp ld e,h
out (0feh),a
xor 10h
freq dec d
jr z,mod
dec e
jr nz,freq
jr sonlp
mod ld a,(soncfg)
add a,h
ld (sonfrq),a
ld hl,sonmod
dec (hl)
ret nz
ld hl,sonlen
dec (hl)
jr nz,modify
xor a
ld (sonnow),a
ld a,(sonnex)
and a
ret z
ld (sonreq),a
ret
modify ld a,(sobrsf)
ld c,a
ld a,(sontyp)
and a
jr z,reset
dec a
jr z,typ1
dec a
jr z,typ2
typoth ld a,(soncfg)
neg
ld (soncfg),a
jr mode
typ2 inc c
inc c
ld a,c
ld (sobrsf),a
jr reset
typ1 dec c
dec c
ld a,c
ld (sobrsf),a
jr reset
reset ld a,c
ld (sonfrq),a
mode ld a,(sonrnd)
ld (sonmod),a
ret
random push hl
ld hl,(rnseed)
inc hl
ld a,h
and 03
ld h,a
rok ld (rnseed),a
ld a,r
xor (hl)
pop hl
ret
rnseed defw 1000h
sonfrq defb 00 ;начальная частота
;start frequency
soncfg defb 00 ;скорость изменения частоты
;frequency change
sonmod defb 00 ;количество модуляций в звуке
;change times
sonlen defb 00 ;количество повторений звука
;repeat times
sontyp defb 00 ;вид модуляции
;modulate type
;0 sawtooth
;1 2nd mod down
;2 2nd mod up
;3+ triangle
sobrsf defb 00 ;частота сброса
;reset frequency
sonrnd defb 00 ;темп изменения частоты сброса
;change reset temp
sonnex defb 00 ;приклеенный эффект
;linked sfx
sonnow defb 00 ;что играем
;
sonreq defb 00 ;меняем эффект
;
sfx_data
;here all souned excepts number 1 reserved for random noise
; defb 0, 5, 5, 1, 0, 0, 0, 0
; defb 28h, 5, 0Ah, 1, 0, 0, 0, 0
; defb 0, 80h, 1Eh, 1, 0, 0, 0, 0
; defb 0, 2, 1Eh, 1, 0, 0, 0, 0
; defb 0, 7Dh, 20h, 1, 0, 0, 0, 0
; defb 0FFh, 83h, 20h, 1, 0, 0, 0, 0
; defb 0FFh, 83h, 28h, 20h, 1, 3Ch, 1, 0
; defb 0F0h,0F0h, 8, 3, 0, 3Ch, 6, 0
; defb 2, 80h, 0Ah, 1, 0, 0, 0, 0
; defb 28h,0FAh, 8, 1, 0, 0, 0, 0
; defb 0FAh, 2Ch, 6, 0Ah, 1, 5Ah, 1, 0
; defb 0,0FCh, 14h, 8, 1, 50h, 8, 0
; defb 0E6h,0E6h, 4, 1, 1, 0, 0, 0
; defb 2Dh, 43h, 14h, 1, 1, 0, 0, 0
; defb 0, 0, 0, 0, 0, 0, 0, 0
; defb 0, 0, 0, 0, 0, 0, 0, 0
; defb 0, 0, 0, 0, 0, 0, 0, 0
; defb 0, 0, 0, 0, 0, 0, 0, 0
; defb 0, 0, 0, 0, 0, 0, 0, 0
; defb 0, 0, 0, 0, 0, 0, 0, 0
Да как бэ я в курсе.. и на PC уже давно бы написал.. проблема в освоении как раз УКНЦ :)
Освою конечно.. но много времени на это уходит.. как раз из-за малого "комьюнити" УКНЦ.. все приходится придумывать считай заново.
Мне бы тоже помогло наличие такого решения, в котором:
1. В память ПП запуливается свой код, который встаёт в цикл задач ПП
2. Этот код принимает команды от ЦП через ячейку памяти или через канал ЦП->ПП
3. По команде от ЦП начинает проигрывание мелодии или звукового эффекта, с зацикливанием или без
4. По команде от ЦП корректно убирается из цикла задач ПП и освобождает память ПП
Я примерно так и представляю.. только вот про "который встаёт в цикл задач ПП" можно поподробнее..
То что я до этого видел.. циклится в ПП пока не выполнит все что нужно.. потом уничтожается..
Я выше спрашивал.. но пока то что нужно не нашел..
ТО что писал Худяков.. мягко говоря урывками.. и некоторые фразы вводят в ступор.. типа "вы можете выбрать другую пару адресов.."как ? исходя из чего?... ну типа итак понятно.. все же знают но молчат :)
...
Сейчас занят "расстановкой врагов и их поведением".....
Но собрать инфу на будущее будет не лишним.. в ту же задачу (цикл задач ПП) можно много чего запихать.. например изменение палитры и др..
Вообще организовать некий протокол для общения с ПП.. там глядишь и до "полноцветных" спрайтов дойдем..
По проигрыванию мелодий в качестве примера можно привести игрушку "Замок гоблинов". Программа в ПП висит там на сетевом таймере, и анализирует ячейку с адресом 0300 в ОЗУ ЦП. Сам код в SAV-файле расположен с 072700 по 074302. Можно дизассемблировать и разобраться.
Что быстрее на ВМ2: ASL R1 или ADD R1,R1?
ИМХО, и та, и другая команды занимают ровно один цикл МПИ.
По таким вопросам курить тему: https://zx-pk.ru/threads/14702-rasch...ry-pdp-11.html
Потеряные картинки можно найти тут: http://www.emuverse.ru/wiki/%D0%A3%D...B0%D0%BD%D0%B4
например CLR R0 медленнее MOV #0,R0
..
ищу все что может ускорить код..(оптимизирующие замены даже в ущерб размеру) пишите все что вспомните :)
Где-то вычитал, вроде как связано с архитектурными особенностями.. (возможно это относится к ВМ1)
По моему на Хабре.. статейка была про процы начиная с 8080.. про достоинства и недостатки..
- - - Добавлено - - -
ASL - 14, ADD 13.. не принципиально.
Наверное, имелось в виду что CLR (R1) выполняется медленней чем MOV R0,(R1) когда в R0 ноль. По крайней мере на процессоре ВМ1 это так, и кто-то писал, что на ВМ2 не исправили. Возможно, внутри процессора CLR делается как-то типа XOR dst,dst и это требует двух обращений к памяти, в отличии от MOV.
Не знаю, почему, но CLR, в отличие от MOV, делается посредством цикла шины "Ввод-пауза-вывод", который, естественно, длиннее обычного цикла "Вывод", на длительность фазы ввода. Непонятно зачем оно так сделано, но это идет еще от Э-60.
Alex_K недавно же все обьяснил: CLR на ВМ2
Почти разобрался с резидентами (диспетчером процессов).
В принципе в ПК УКНЦ 1-94 правильно написано, но с ошибками и неполно..
; Подпрограмма для выполнения в памяти ПП;
STARTPP:
MOV PC,R1 ; Найти адрес
ADD #PGM1-.,R1 ; программы-процесса
MOV R1,AdrPgm ; Запомнить его
MOV R1,@#7124 ; Записать в таблицу процессов
MOV #1,@#7100 ; Записать в таблицу запуска
RETURN ; Завершить эту программу
AdrPgm: 0
PGM1: ; Сама программа-процесс
MOV R0,-(SP) ; Сохранение R0
.......
Наш процесс
MOV #COMMW/2,@#177010 ; Управлять можно через ячейку в памяти ЦП
MOV @#177014,R0 ;
.........
MOV AdrPgm,@#7124 ; Поставить в очередь процессов
MOV #1,@#7100 ; Потребовать обслуживания
MOV (SP)+,R0 ; Восстановить
JMP @#174170 ; Перейти к диспетчеру процессов
ENDPP:
Доступных пар ячеек всего 2:
007076 SCPP:: .WORD 0 ;- счетчик процесса пользователя
007100 SCPTST:: .WORD 0 ;- счетчик процесса тестирования
и то с "процесса пользователя" не получилось, так что фраза "вы можете использовать другую пару" только вводит в заблуждение.
список ячеек диспетчера процессов:
007060 SCPKL:: .WORD 0 ;- счетчик процесса клавиатуры
007062 SCPKFO:: .WORD 0 ;- счетчик процесса канала файлового обмена
007064 SCPD:: .WORD 0 ;- счетчик процесса дисплея
007066 SCPK:: .WORD 0 ;- счетчик процесса курсора
007070 SCPKR:: .WORD 0 ;- счетчик процесса режима установок
007072 SCPMZ:: .WORD 0 ;- счетчик процесса меню загрузки ЦП
007074 SCPPC:: .WORD 0 ;- счетчик процесса печати
007076 SCPP:: .WORD 0 ;- счетчик процесса пользователя
007100 SCPTST:: .WORD 0 ;- счетчик процесса тестирования
007102 SCDPRC:: .WORD 0 ;- счетчик диспетчера процессов
....
пока еще не разобрался как правильно освобождать память.. в случае с резидентом..
S_V_B, предлагаю для усовершенствования вашего "движка" такие переменные для кнопок заиметь
SHIFT$ - НАЖАТ ЛИ ШИФТ ПРОВЕРКА ПО TST
И ДАЛЕЕ ПО ТОМУ ЖЕ ПРИНЦ.
UP$
DOWN$
LEFT$
и так по всем управляющим кнопкам )
пример со скан-кодами для УК-НЦ есть на образе Alex_K
Сделал переключение экранов при выводе спрайтов:
https://yadi.sk/d/ZHVD8eUWDyIlmA
Не нравится влияние прерываний на скорость вывода, придется отключать. В связи с этим вопрос, подскажите правильный опрос клавиатуры без прерываний и ЕМТов, и прочих TTYIn.
правильным считается как раз опрос через системный вызов )
я всегда опрашивал раньше с регистры адреса и данных
полистайте тему ПАСКАЛЬ\МАКРО-11 и программирование на УК-НЦ как?
комок шпор
Код:Вопрос:
Подскажите, как правильно по системному запретить
передачу кодов клавиш от клавиатуры на терминал,
но при этом самому эти коды получать?
Приведу пример: я вывожу какую-то информацию на экран,
после чего спрашиваю "Continue?".
Тут человек должен нажать любую клавишу, и программа
продолжится. Если делать опрос клавиш через EMT 340,
то коды клавиш отображаются на экране, а мне этого не надо.
Если же делать через чтение данных напрямую из канала 0
(канал клавиатуры), то символы все равно отправляются в
монитор и потом печатаются. Т.е. какая-то должна быть
системная функция, запрещающая выводить на терминал коды
приходящих клавиш, но я ее не знаю.
Ответ:
Для этого надо установить бит TTSPC$ (12й) в $JSW (44).
к примеру:
Код:
.MCALL .TTYIN,.PRINT,.EXIT
$JSW = 44
TTSPC$ = 10000
TEST: BIS #TTSPC$,@#$JSW
.PRINT #PROMPT
.TTYIN
.EXIT
PROMPT: .ASCII /--->/<200>
печатает подсказку, ждет нажатия клавиши, выходит
Другой вариант - запретить прерывания от клавиатуры
и работать напрямую с регистрами, но этот вариант
несовместим с виртуальными программами и не будет
работать в системах с поддержкой многотерминальности.
---------- Post added at 17:57 ---------- Previous post was at 17:46 ----------
Еще дополнение - иногда полезен бит TCBIT$ (6й) - при его установке
TTINR (EMT 340) не останавливается в ожидании символа, а проходит
дальше с установленным битом C если ничего не нажато.
-------------------------------------------------------------------------------
.Print #NextPage ;Печатаем сообщение "Next page?"
.Print #KeyON ;Включить клавиатуру
BIS #TTSPC$,@#$JSW ;Запрет отображения символов на экране
.TTYIN ;Ожидание нажатия клавиши
CMP R0,#13 ;Если код = 13 (Возврат каретки),
BNE 6$ ;то ожидаем еще один код = 10 (перевод строки)
.TTYIN ;
6$:
.Print #KeyOFF ;Отключить клавиатуру
.Print #NextLine ;Переходим на следующую строку
...
NextPage: .ASCII "Next page?"<128>
NextLine: .ASCII <13><10><128>
KeyOFF: .ASCII <27><91><50><104><128>
KeyON: .ASCII <27><91><50><108><128>
++++++++++++++++++++++++++++++++
К слову коды клавиш/символов вообще
удобнее выносить в начало - к примеру так:
Код:
ESC = ^O33
CR = ^O15
LF = ^O12
================================
^B - Binary
^C - Complement
^D - Decimal
^F - Floating
^O - Octal
^R - Radix50
^X - 16-ричные???
================================
.TITLE TXT -- ПЕЧАТЬ ТЕКСТОВЫХ СТРОК
.MCALL .PRINT
TXT:: MOV (R5)+,R1 ;ЧИСЛО АРГУМЕНТОВ
BEQ 30$ ;EQ - НЕТ АРГУМЕНТОВ
10$: MOV (R5)+,R0 ;АДРЕС ОЧЕРЕДНОГО АРГУМЕНТА
CMP #-1,R0 ;ЕСЛИ -1 - АРГУМЕНТ ПРОПУЩЕН
BEQ 20$ ;...ПРОПУСКАЕМ
.PRINT ;ПЕЧАТАЕМ СТРОКУ
20$: SOB R1,10$ ;ЦИКЛИМСЯ ПОКА ЕСТЬ АРГУМЕНТЫ
30$: RETURN ;ВОЗВРАЩАЕМ УПРАВЛЕНИЕ
.END
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Раз уж есть тема по программированию, предлагаю сюда же
свалить всякие хитрости какие кто пользует
Например такие:
Код:
JSR Rx,@PC ;СОХРАНИТЬ Rx В СТЕКЕ, НЕ ТРОГАЯ PSW
MOV #160000,SP ;ПОЛНАЯ ОЧИСТКА ПАМЯТИ (56Kb)
MOV #4747,@#0 ;И ЧИСТЫЙ ОСТАНОВ БЕЗ ОШИБОК
CLR PC ;В КОНЦЕ
CALL @(SP)+ ;ВЫЗОВ СОПРОГРАММЫ
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
И я тоже добавлю - простой способ разворачивания цикла
2x:
1. Пусть есть цикл, выполняющийся N раз, типа:
mov N,r0
1$: cmd ! некая команда, например, clr(r1)+
sob r0,1$
2. Простой способ разворачивания того ж цикла в линейку:
mov N,r0
inc r0
asr r0
bcc 2$
1$: cmd
2$: cmd
sob r0,1$
Идея состоит в том, чтоб позаботиться о нечётном числе
итераций до начала цикла, и войти внутрь цикла в обход
стандартного начала.
========================================================
Устанавливает цвет курсора
8 цветов от 60 до 67 (третий параметр)
.TTYOUT #33
.TTYOUT #247
.TTYOUT #67
Цвет экрана
.TTYOUT #33
.TTYOUT #242
.TTYOUT #60
Цвет символов
.TTYOUT #33
.TTYOUT #241
.TTYOUT #67
Цвет знакоместа
.TTYOUT #33
.TTYOUT #240
.TTYOUT #60
Установка формата экрана
(61 - 80х24, 62 - 40х24, 63 - 20х24, 64 - 10х24)
.TTYOUT #33
.TTYOUT #246
.TTYOUT #61
Запускаем нужное приложение (на примере 'МЗ1:ДИГГЕР.САЖ')
.MCALL .CHAIN
MOV #^RMZ1,@#500
MOV #^RDIG,@#502
MOV #^RGER,@#504
MOV #^RSAV,@#506
.CHAIN
PROCEDURE WAITKEY;
VAR KEY ORIGIN 177560B: INTEGER;
BEGIN
REPEAT KEY:=0 UNTIL KEY>0
END;
Если завести глобальную переменную
INKEY ORIGIN 177562B: INTEGER;
там будет код последней нажатой клавиши
PROCEDURE gotoXY(X,Y: INTEGER);
BEGIN
WRITE(CHR(27),'Y',CHR(32+Y),CHR(32+X));
END;
---------------------------------------------
Ну да, если буфер переполнен, то устанавливается
бит C в PSW. Поэтому код должен быть таким:
Код:
EMT ^O341
BCS .-2
---------------------------------------------
Код:
.PRINT #TEXT1 ;БЕЗ <CR><LF>
.PRINT #TEXT2 ;<CR><LF> В КОНЦЕ
TEXT1: .ASCII /TEXT/<200>
TEXT2: .ASCIZ /TEXT/
_______________________________________________
[свернуть]
- - - Добавлено - - -
S_V_B, вам надо там свой драйвер загружать и подминать под свой контроль все упр. клавиши - только так )
- - - Добавлено - - -
S_V_B, вот эта авторская игра ведёт себя так как будто написана на движке УК-НЦ который я разыскиваю
https://www.old-games.ru/forum/threa...2#post-1238737
то есть подминает под себя всё и потом начинает игровые экраны выводить )
кстати автор иногда отвечает )
Можно посмотреть как это реализовал nzeemin в своем порте Highway Encounter
Метка GETKEY:
/* надо там свой драйвер загружать */
Зачем такие сложности, в любом случае драйвер от прерываний не спасет (поскольку они не только от клавы).
Игрушка не обязана интегрироваться в операционку главное чтобы корректно завершалась. Многозадачности нет и на время работы программы ты сам волен решать что делать. А драйверы и прочие навороты писались для программ на ЯВУ типа ВАСИК чтобы взаимодействовать с ПП.
- - - Добавлено - - -
Нашел:
; Подпрограмма: Опрос клавиатуры; клавиша есть: Z=0, клавиши нет: R0=0 и Z=1
Z34226:
TSTB @#177660 ; Нажали клавишу?
BPL 4$ ; нет символа => выходим
MOV @#177662, R0 ; код нажатой клавиши
2$: MOV R0, Z34224
RETURN
4$: CLR R0
MOV R0, Z34224 ; Стираем признак нажатой клавиши
SEZ ; Возвращаем признак Z=1 -- нажатия нет
RETURN
Есть у кого-нибудь пример правильной работы с FIS (FDIV,FADD)?
Эмулятор их не понимает (в режиме трассировки), а в слепую я не пойму что не так.
На примере FADD
07500R FADD
Регистр R - как указатель стека (если R6 - то стек и получаем)
После сложенияКод:R-> операнд B биты 16-31 ; (R+00)
операнд B биты 0-15 ; (R+02)
операнд A биты 16-31 ; (R+04)
операнд A биты 0-15 ; (R+06)
результат=A+BКод:R-> операнд B биты 16-31 ; (R+00)
операнд B биты 0-15 ; (R+02)
результат биты 16-31 ; (R+04)
результат биты 0-15 ; (R+06)
Так и делал, вылетает исключение.., я подумал, что в доках перепутали старший и младший байты.. т.к. делю 23. на 24.
- - - Добавлено - - -
хотя пробовал только в эмуляторе т.к. хотел в дебаге посмотреть
старший и младший байты или СЛОВА?
- - - Добавлено - - -
По идее - в эмуляторе simh должно быть правильно
- - - Добавлено - - -
Кстати, посмотреть правильное представление и положение слов в памяти можно директивами .FLT2 и FLT4 (хотя вторая - это уже под FPP, FIS только с .FLT2 работает)
/* старший и младший байты или СЛОВА? */
слова конечно
Про правильно положение слов в памяти - ответ выше
MOV #BS,R2
MOV R2,-(SP)
MOV #0,(R2)+
MOV #23.,(R2)+
MOV #0,(R2)+
MOV #24.,(R2)
MOV (SP)+,R2
FDIV R2
вот что делаю
понял
- - - Добавлено - - -
с примером было бы проще, как переводить в эти мантиссы
24. - это 24(10)
24 - это 24(8)
И это ещё если по умолчанию. Поэтому стараюсь писать ^O<24> и ^D<24>
- - - Добавлено - - -
A: .FLT2 1
B: .FLT2 1
C: .FLT2 2
RES: .BLKW 2
...
MOV B+2, -(SP)
MOV B, -(SP)
MOV A+2, -(SP)
MOV A, -(SP)
FADD SP
CMP (SP)+, (SP)+
MOV (SP)+, RES+2
MOV (SP)+, RES
и сравнить RES RES+2 c C и C+2
а если нам нужно во время выполнения перевести из целочисленного в плавучую и наоборот?
Короче мне нужен итератор меньше нуля например:
float iterator=0.0245;
float a;
x=int (a+itrerator);
Подпрограмма