PDA

Просмотр полной версии : Вопросы по МК-90



Yprit
12.01.2022, 21:55
Решил я изучить МК-90, и у меня возникли вопросы.
1. Есть ли где карта памяти сего калькулятора?
2. Какие есть системные переменные у его Бейсика (и 1.0, и 2.0)? Где они находятся?
3. Почему программа в кодах нормально загружается с СМП в Бейсике 2.0, но не загружается (вообще никак) в Бейсике 1.0?

Radon17
13.01.2022, 00:08
Вот эту страничку читали? http://www.pisi.com.pl/piotr433/index.htm#mk90
Автор есть на этом форуме

Yprit
13.01.2022, 08:27
Читал, но не нашел ответов на эти вопросы (на многие другие -- нашел)

Oleg N. Cher
13.01.2022, 17:40
3. Почему программа в кодах нормально загружается с СМП в Бейсике 2.0, но не загружается (вообще никак) в Бейсике 1.0?Насчёт этого вопроса вроде разобрались. Если на эмуле стоит rom Бейсика 1, то при запуске СМП0 адрес экрана 3000H, а если Бейсика 2, тогда 200H. Есть системная переменная #F800, которая задаёт адрес экрана.

Такой вопрос: какой размер и с какого адреса можно юзать в МК90 кусок непрерывной (не фрагментированной) памяти, чтобы разместить там машинный код пользовательской программы? (хотим GCC приспособить)

piotr433
13.01.2022, 20:03
2. Какие есть системные переменные у его Бейсика (и 1.0, и 2.0)? Где они находятся?
Некоторые системные переменные приведены в начале листингов ПЗУ:
http://www.pisi.com.pl/piotr433/mk90ro10.zip
http://www.pisi.com.pl/piotr433/mk90ro20.zip


Такой вопрос: какой размер и с какого адреса можно юзать в МК90 кусок непрерывной (не фрагментированной) памяти, чтобы разместить там машинный код пользовательской программы?
При запущенном Бейсике начало свободной памяти указывает регистр R5 (0x0100 для версии 1.0 и 0x0F59 для версии 2.0).
Конец определяет SP (~0x2F00 для версии 1.0 и ~0x3F00 для версии 2.0).


хотим GCC приспособить
Интересно! А этот проект вам известный? МК90 - пишем программы на Си (https://embedded.icu/479)

Yprit
14.01.2022, 13:41
Спасибо!
Нет, к сожалению, раньше не видели. Но интересно.
Еще остались вопросы:
1. Как опрашивается клавиатура?
2. Можно ли с СМП загружать больше 3.5 килобайт сразу?
3. Влияет ли Бейсик на работу после загрузки кодов?
4. Есть ли ограничения на вызов подпрограмм из ПЗУ?
Уточню насчет второго. В описании к игре "Жизнь" написано:

Because its size exceeds 512 bytes, it has to be stored in the cartridge data area. In order to prevent the system from overwriting it, the value at the location 0x0412 (in the cartridge directory area) is changed from 0x10 to 0x0D. This step allocates three last sectors for machine code programs of size up to 1.5 kBytes, leaving the remaining space of 6.5 kBytes available for the system.
Можно ли оставить на машинный код больше, чем 4.5 килобайт? И имеются в виду ведь сектора СМП?

Oleg N. Cher
14.01.2022, 17:21
Интересно! А этот проект вам известный? МК90 - пишем программы на Си (https://embedded.icu/479)Весьма интересно и необычно, но тут как-то слишком всё сложно делается. И у GCC кодогенерация будет сильно получше, чем у старинного компилятора.

Мы уже добились от GCC базовой генерации бинаря, сумели запустить его на эмуляторе в первых 512 байтах на месте загрузчика. Даже адаптировали Ваш код для точки, линии и круга. Теперь хочется понять с какого адреса мы можем юзать непрерывный кусок памяти под сгенеренный сишкой код, где лучше разместить экранную область, как именно Бейсик влияет на машинный код, запущенный из СМП и не дающий управление Бейсику. Также конечно интересно можно ли пользоваться подпрограммами из ПЗУ, как выводить символы, как опрашивать клавиатуру. Да и вообще как лучше загружать код из СМП в ОЗУ, т.к. пока что не очень понятно как устроен загрузчик.

Наработки по мере освоения будут выкладываться в подсистеме Pdp11Dev (https://github.com/Oleg-N-Cher/Pdp11Dev), да и вообще, если честно, то нас больше интересует Оберон, чем Си. Цель в том, чтобы можно было получить программу для МК90 одним нажатием кнопки. Ну и чтобы под рукой были полезные рабочие примеры кода.

piotr433
14.01.2022, 22:32
Постараюсь постепенно отвечать.


1. Как опрашивается клавиатура?

1. Пример использования подпрограмм из ПЗУ версии 1.0, ассемблер MACRO11:


.asect
.radix 10

GETCH = ^O131120
PUTCH = ^O116542

.= 0

nop ;obligatory
jsr pc,@#^O153700
jsr pc,@#^O120536
mov @#^O034022,@#^O164000
mov #^O104306,@#^O164002
again: jsr pc,GETCH ;R2 = ASCII code of the pressed key
jsr pc,PUTCH ;display the character R2
br again

.= ^O000310

.word ^O130514, 0 ;keyboard interrupt vector

2. Программа отображает скан-код нажатой клавиши. ПЗУ не используется. Ассемблер PDPXASM (http://www.dbit.com/pub/ibmpc/pdpxasm/):


; reading the keyboard using interrupts

.radix 16

.loc 0

nop ;obligatory!
mtps #E0 ;disable interrupts
mov #scr,r0 ;display RAM
mov r0,@#E800
mov #88C6,@#E802
; clear the display RAM
mov #1E0,r1
cls: clr (r0)+
sob r1,cls
br cont

.loc 100

cont: mov #keysr,@#C8 ;keyboard controller interrupt vector
clr @#CA
mov #36,@#E812 ;slow clock
mov #EA,@#E814
mtps #0

; continuously read and display the keyboard scan code
again: wait ;wait for a pressed key
mov keycod,r3
mov #scr,r0
jsr pc,hex
br again

; keyboard interrupt handle routine
keysr: mov #^XF2,@#E814
clr @#E816
keyb1: tstb @#E814
bpl keyb1
mov @#E816,keycod
keyb2: tstb @#E814
bpl keyb2
mov #EA,@#E814
rti

; display the byte R3 at the screen address R0
hex: jsr pc,hex1
hex1: mov #4,r4
clr r1
hex2: rolb r3
rol r1
sob r4,hex2
jsr pc,putc
rts pc

; display the character R1 at the screen address R0,
; advance the pointer R0 to the next column
putc:
; R1 <- 6 * R1
asl r1 ;* 2
mov r1,-(sp)
asl r1 ;* 4
add (sp)+,r1 ;* 6
add #chars,r1
mov #6,r2
putc1: movb (r1)+,(r0)
add #1E,r0
sob r2,putc1
sub #B2,r0 ;6 * 1E - 2 = B2
rts pc

; characters, width = 8 pixels, height = 6 pixels
chars: .byte 3C, 46, 4A, 52, 62, 3C ;digit '0'
.byte 18, 28, 8, 8, 8, 3E ;digit '1'
.byte 3C, 42, 2, 3C, 40, 7E ;digit '2'
.byte 3C, 42, C, 2, 42, 3C ;digit '3'
.byte 8, 18, 28, 48, 7E, 8 ;digit '4'
.byte 7E, 40, 7C, 2, 42, 3C ;digit '5'
.byte 3C, 40, 7C, 42, 42, 3C ;digit '6'
.byte 7E, 2, 4, 8, 10, 10 ;digit '7'
.byte 3C, 42, 3C, 42, 42, 3C ;digit '8'
.byte 3C, 42, 42, 3E, 2, 3C ;digit '9'
.byte 3C, 42, 42, 7E, 42, 42 ;'A'
.byte 7C, 42, 7C, 42, 42, 7C ;'B'
.byte 3C, 42, 40, 40, 42, 3C ;'C'
.byte 78, 44, 42, 42, 44, 78 ;'D'
.byte 7E, 40, 7C, 40, 40, 7E ;'E'
.byte 7E, 40, 7C, 40, 40, 40 ;'F'

keycod: .blkw 1

.loc 200

scr:

- - - Добавлено - - -


2. Можно ли с СМП загружать больше 3.5 килобайт сразу?
Да, можно, ограничений нет.


Можно ли оставить на машинный код больше, чем 4.5 килобайт?
В игре "Жизнь" я хотел чтобы модул СМП можно было одновременно использовать для хранения машинного кода и программ на Бейсике. Если такого требования нет, можно все 10 килобайт оставить на машинный код.

Кстати, встречаются разные загрузчики. В игре "Жизнь" был скопирован с ПЗУ 1.0, примерно с адреса 0xF8EC. А вот "Эмулятор терминала" (https://zx-pk.ru/threads/29333-po-dlya-mk-90.html?p=971924&viewfull=1#post971924) использует подпрограмму ПЗУ по адресу 0xBBBA.


3. Влияет ли Бейсик на работу после загрузки кодов?
Думаю, что только если вызывать связанные с ним подпрограммы из ПЗУ.


4. Есть ли ограничения на вызов подпрограмм из ПЗУ?
Возможно есть, в зависимости от подпрограммы. Например GETCH из первого примера выводит на экран статус кнопок Р/Л и В/Н. Наверно можно это предотвратить изменяя какую-то системную переменную.
Точно тяжело сказать. Пока я разобрал только небольшой фрагмент кода ПЗУ :(

Oleg N. Cher
15.01.2022, 00:06
Пётр, спасибо за Ваши подробные ответы.

Попутно возник ещё такой вопрос: что это за команда запрещения прерываний в загрузчике?


MTPS $0xE0

(синтаксис изменён для асма GCC, но $ это #, а код шестнадцатеричный, это и так понятно)

Зачем нужно запрещать прерывания? Зачем нужно их потом разрешать? Где хранятся векторы прерываний? В нижних адресах или где-то ещё?

В загрузчике видел выравнивание для пропуска байт. Тоже не очень понятно, зачем их пропускать. Ну типа такого:


nop
br loader

.= 32
loader:
mtps #^O340

nzeemin
15.01.2022, 01:11
Смотрю на код загрузки из SMP, ПЗУ BASIC 2.0 - дизасм, полученный Петром.

Процесс загрузки вполне стандартный:
1. Сначала с СМП загружается бут-сектор, размером 0x200 = 512 байт, начиная с адреса ОЗУ 000000.
2. Проверяется, что первое слово равно 0xA0 = 000240 - инструкция NOP
3. Загрузчик запускается с адреса 000000

При форматировании СМП, туда записывается стандартный загрузчик, показывающий фразу "БЕЗ ЗАГРУЗЧИКА", при этом пропуска слов в начале там нет.

Предполагаю, что в приведённом выше коде загрузчика, пропущенные в начале слова оставлены для векторов прерываний.

- - - Updated - - -


Где хранятся векторы прерываний? В нижних адресах или где-то ещё?

Мои предположения, что прерывания в начале памяти такие же как на Немиге (процессор тоже на 588 комплекте), плюс из того что написано у Петра в дизасме ПЗУ:

000004 — нечётный адрес при обращении по слову; ошибка обращения к каналу; HALT в режиме USER; неверная адресация JMP/JSR
000010 — резерный код команды
000014 — прерывание по T-разряду или команда BPT
000020 — команда IOT
000030 — команда EMT
000034 — команда TRAP
000100 — прерывание EVNT
000310 — прерывание от клавиатуры

Вектора прерываний в ПЗУ:

160002 — сигнал/команда HALT в режиме HALT
160006 — двойное зависание
160012 — ошибка при приёме вектора прерывания

Hunta
15.01.2022, 11:02
Мои предположения, что прерывания в начале памяти
Если это прерывания самого процессора (нечётный адрес, резервный код, BPT, IOT и т.п.) - их адреса фиксированные.
Если это прерывания от внешнего устройства - что выдаст устройство - то и вектор (вроде как должно быть меньше 1000, но.. не помню в доках по процессорам, что так ДОЛЖНО БЫТЬ). Чисто формально - может быть любой, хоть 177774.
Отдельный вопрос, когда запрос прерывания имеет отдельную линию (типа EVNT) - тогда тоже фиксированные

piotr433
15.01.2022, 12:46
Зачем нужно запрещать прерывания? Зачем нужно их потом разрешать?
Безопаснее вводить изменения в системе прерываний (установление векторов, программирование контроллера прерываний) при запрещённых прерываниях и разрешать их только когда всё готово.
Операнд MTPS должен быть действительно #E0 вместо #E00. Исправил ошибку.


Где хранятся векторы прерываний? В нижних адресах или где-то ещё?
В диапазоне адресов 0x0004-0x00FF.


В загрузчике видел выравнивание для пропуска байт. Тоже не очень понятно, зачем их пропускать.
Загрузчик занимает область памяти предназначенную для векторов прерываний. Необходимо пропустить адреса используемых векторов. Автор данного фрагмента кода видимо считал векторы по адресам 4..31 важными.

Кстати, можно также опрашивать клавиатуру не используя прерываний:


; attempt to poll the keyboard without using interrupts

.radix 16

.loc 0

nop ;obligatory!
mtps #E0
mov #scr,r0 ;display RAM
mov r0,@#E800
mov #88C6,@#E802
; clear the display RAM
mov #1E0,r1
cls: clr (r0)+
sob r1,cls
br cont

.loc 100

cont: mov #100,@#E812 ;slow clock

; continuously read and display the keyboard scan code
again: jsr pc,keyb
mov #scr,r0
jsr pc,hex
br again

; read the keyboard scan code to R3
keyb: mov #^XF2,@#E814
clr @#E816
keyb1: tstb @#E814
bpl keyb1
mov @#E816,r3
keyb2: tstb @#E814
bpl keyb2
mov #E2,@#E814
rts pc

; display the byte R3 at the screen address R0
hex: jsr pc,hex1
hex1: mov #4,r4
clr r1
hex2: rolb r3
rol r1
sob r4,hex2
jsr pc,putc
rts pc

; display the character R1 at the screen address R0,
; advance the pointer R0 to the next column
putc:
; R1 <- 6 * R1
asl r1 ;* 2
mov r1,-(sp)
asl r1 ;* 4
add (sp)+,r1 ;* 6
add #chars,r1
mov #6,r2
putc1: movb (r1)+,(r0)
add #1E,r0
sob r2,putc1
sub #B2,r0 ;6 * 1E - 2 = B2
rts pc

; characters, width = 8 pixels, height = 6 pixels
chars: .byte 3C, 46, 4A, 52, 62, 3C ;digit '0'
.byte 18, 28, 8, 8, 8, 3E ;digit '1'
.byte 3C, 42, 2, 3C, 40, 7E ;digit '2'
.byte 3C, 42, C, 2, 42, 3C ;digit '3'
.byte 8, 18, 28, 48, 7E, 8 ;digit '4'
.byte 7E, 40, 7C, 2, 42, 3C ;digit '5'
.byte 3C, 40, 7C, 42, 42, 3C ;digit '6'
.byte 7E, 2, 4, 8, 10, 10 ;digit '7'
.byte 3C, 42, 3C, 42, 42, 3C ;digit '8'
.byte 3C, 42, 42, 3E, 2, 3C ;digit '9'
.byte 3C, 42, 42, 7E, 42, 42 ;'A'
.byte 7C, 42, 7C, 42, 42, 7C ;'B'
.byte 3C, 42, 40, 40, 42, 3C ;'C'
.byte 78, 44, 42, 42, 44, 78 ;'D'
.byte 7E, 40, 7C, 40, 40, 7E ;'E'
.byte 7E, 40, 7C, 40, 40, 40 ;'F'

.loc 200

scr:

- - - Добавлено - - -


Если это прерывания самого процессора (нечётный адрес, резервный код, BPT, IOT и т.п.) - их адреса фиксированные.
Если это прерывания от внешнего устройства - что выдаст устройство - то и вектор (вроде как должно быть меньше 1000, но.. не помню в доках по процессорам, что так ДОЛЖНО БЫТЬ). Чисто формально - может быть любой, хоть 177774.
Отдельный вопрос, когда запрос прерывания имеет отдельную линию (типа EVNT) - тогда тоже фиксированные
Насколко мне известно, в самом МК-90 все адреса прерываний меньше 001000, также выдаваемые внешними устройствами.

Hunta
15.01.2022, 14:34
в самом МК-90 все адреса прерываний меньше 001000
Обычно они даже меньше 400, но понятие - вектор прерывания - используется не только в МК-90.

Ну и никто не мешает сделать своё устройство с вектором, который будет выше. И кстати, интересный вопрос - как себя поведёт МК-90 в частности и конкретные модели PDP-11 в общем.