мои опыты с "Электроника МК-90"

 


Давно видел этот эмулятор и решил познакомиться. Саму машинку когда-то видел в магазине Зеленограда, но цена была запредельной и недоступной. Естественно, с наскока так и не удалось разобраться с разработкой. В этот раз все оказалось сложнее. Начну с того, что на пшекском сайте разработчика эмуль не нашелся. Но есть запас. Информация об ассемблере мало что проясняет, стал искать и набрел на опубликованные исходники. Остался ассемблер, БК-шный TurboBK8 не подходит. Взял старый MACRO-11. Но вот засада - из исходников получается .obj, а мне нужен .bin. Автор на github упомянул скрипт на Perl'e, и опять мне не улыбается перспектива юзать этот скриптовый язык. Нашел исходник obj2bin.c на форуме nedoPC, собрал с дополнительными сырками от ассемблера, и на мое удивление компилятор tinyC проглотил исходники и выплюнул .exe.

И понеслось, выделил фрагмент кода из игрули T-Rex, и начал работу. MACRO-11 вытошнил кучу строк со словами ERROR. Гугл подбросил ссылку на документацию - AA-KX10A-TC_PDP-11_MACRO-11_Reference_Manual_May88.pdf,стал читать: не нравятся метки с подчеркиванием(как оно компилировалось?) Вот мой исходник:

.ENABL AMA
.ASECT
.RADIX 10
.= 0
PRINTATTRS = ^O34072
PRINTNUM = ^O153360 
PRINT = ^O153414 
INITRAM = ^O153700
INITTTY = ^O120536
LCDINA = ^O164000
LCDINB = ^O164002
WAITCOMM = ^O174506
SMPCMD = ^O164026
SMPBAUD = ^O164022
SMPCS = ^O164024
SMPIO = ^O164020
GETCH = ^O131120
PUTCH = ^O116542
RTCSEC = ^O165000
RTCMIN = ^O165004
SCREEN = 10240
SCRBUF = 11200
SCREENWB = 30
SCREENWW = SCREENWB/2
SCREENSB = 960
SCREENSW = SCREENSB/2
SCREENH = 64
SCREENW = 120
nop
br loader
.= 32
loader:
; mov #SCREEN, r4
; mov #SCREENSW, r3
;lClearScreenLoop:
; clr (r4)+
; sob r3, lClearScreenLoop
mov #^O24000, @#LCDINA
mov #^B1000100011000110, @#LCDINB ;26Hz

;Loader copyed from Game of Life app of Piotr Piatek
; specify the SMP address
mtps #^O340 ;disable interrupts
bis #8, r5 ;writing to the SMP
mov r5,(r1)
mov #^O240, @#SMPCMD ;Write Address
jsr pc,(r2)
mov #start/256, @#SMPIO ;high address byte
jsr pc,(r2)
mov #start, @#SMPIO ;high address byte
jsr pc, (r2)
tst @#SMPCMD
jsr pc, (r2)
; load data
mov #END-START, r4 ;number of bytes
mov #START, r3
mov #^O320, @#SMPCMD ;Read Postincrement
jsr pc, (r2)
bic #8, r5 ;reading from the SMP
mov r5, (r1)
jsr pc, (r2)
nxtb:
movb @#SMPIO, (r3)+ ;read data byte from the SMP to the RAM
jsr pc, (r2)
sob r4, nxtb ;next data byte
tst @#SMPCMD
jsr pc, (r2)
; start the loaded program
mov #^O340, -(sp) ;user mode, interrupts disabled
;mov #^O000, -(sp) ;user mode, interrupts enable
mov #start, -(sp)
rti



.= 200
.word 0, 0
.= 512
START:
bic #^B00010000, @#SMPCS ;enables external interrupts to the vector $00C8
movb #^B01010111, @#^O165024 ;32 fps
clrb @#^O165026 ;Without IRQ 
mov #^O24000, r4
mov #^O12000, r3
cls:
clr (r4)+
sob r3, cls
mov #^O24000, r4
mov #^O100, r3 ;64
lp: mov r4,(r4)
add #^O36,r4 ; +30
sob r3,lp
kk:
 br kk
END:

Начало - это стандартный загрузчик, моя программа начинается с метки START. Кое-как собралось:

macro11 proga.mac -o smp0.obj -l prg.lst
obj2bin smp0.obj smp0.bin

Но программа не запускается. Хвала разработчику, есть отладчик(F3-запуск),запускаю и смотрю - первая программа расположена в памяти не полностью. Убрал первый кусок - очистка экрана, снова не работает полностью. Снова отладчик показывает слабое звено: я написал kk br kk, не разделив метку двоеточием! Здесь будет нудный рассказ про исследования, а мат остался только вчера. MACRO-11, падшая самка человека,интерпретировал это по-своему, вышло halt / br adr.
Дальше еще веселее - на экране появляется мусор, отладчик показывает, что проц ускакал в никуда. Стал смотреть, нашел ошибку - в регистры R4 и R3 заносится неверные значения, ассемблер числа не воспринял, поэтом обнуляет саму программу. Хрен с тобой, золотая рыбка, исправил. Программа запустилась, но на экране новый мусор. Заморочка в том, что адреса видеопамяти указываются разные в зависимости от версии Бейсика.
Стал смотреть исходники, нашел причину: mov #^O24000, @#LCDINA - здесь задается адрес $2800. Исправил, экран очистился!
Дописал простой код заполнения памяти, экспериментально определил длину строки в байтах - 30 байт. Неясно, почему такое значение, ведь разрешение 120х64. простая математика дает 120/8=15. А вот результат:
Странно, я использовал код для рисования 64 строк, а вышла половина. Вечерком посидел за эмулятором, внося данные, пытаясь вычислить структуру:

Красным выделены верхние 5 байт. значение $77 унесло вниз, явно на 32 строки. байт $0A хранится рядом с байтом 1. Кажется, теперь понятно, можно продолжить:

.ENABL AMA
.ASECT
.RADIX 10
.= 0
PRINTATTRS = ^O34072
PRINTNUM = ^O153360 
PRINT = ^O153414 
INITRAM = ^O153700
INITTTY = ^O120536
LCDINA = ^O164000
LCDINB = ^O164002
WAITCOMM = ^O174506
SMPCMD = ^O164026
SMPBAUD = ^O164022
SMPCS = ^O164024
SMPIO = ^O164020
GETCH = ^O131120
PUTCH = ^O116542
RTCSEC = ^O165000
RTCMIN = ^O165004
SCREEN = 10240
SCRBUF = 11200
SCREENWB = 30
SCREENWW = SCREENWB/2
SCREENSB = 960
SCREENSW = SCREENSB/2
SCREENH = 64
SCREENW = 120
nop
br loader
.= 32
loader:
; mov #SCREEN, r4
; mov #SCREENSW, r3
;lClearScreenLoop:
; clr (r4)+
; sob r3, lClearScreenLoop
mov #^O24000, @#LCDINA; определить адрес видеопамяти
mov #^B1000100011000110, @#LCDINB ;26Hz

;Loader copyed from Game of Life app of Piotr Piatek
; specify the SMP address
mtps #^O340 ;disable interrupts
bis #8, r5 ;writing to the SMP
mov r5,(r1)
mov #^O240, @#SMPCMD ;Write Address
jsr pc,(r2)
mov #start/256, @#SMPIO ;high address byte
jsr pc,(r2)
mov #start, @#SMPIO ;high address byte
jsr pc, (r2)
tst @#SMPCMD
jsr pc, (r2)
; load data
mov #END-START, r4 ;number of bytes
mov #START, r3
mov #^O320, @#SMPCMD ;Read Postincrement
jsr pc, (r2)
bic #8, r5 ;reading from the SMP
mov r5, (r1)
jsr pc, (r2)
nxtb:
movb @#SMPIO, (r3)+ ;read data byte from the SMP to the RAM
jsr pc, (r2)
sob r4, nxtb ;next data byte
tst @#SMPCMD
jsr pc, (r2)
; start the loaded program
mov #^O340, -(sp) ;user mode, interrupts disabled
;mov #^O000, -(sp) ;user mode, interrupts enable
mov #start, -(sp)
rti



.= 200
.word 0, 0
.= 512
START:
bic #^B00010000, @#SMPCS ;enables external interrupts to the vector $00C8
movb #^B01010111, @#^O165024 ;32 fps
clrb @#^O165026 ;Without IRQ 

;очистка экрана
mov #^O24000, r4
mov #^O12000, r3
cls:
clr (r4)+
sob r3, cls

;верхная половина
mov #^O24000, r4
mov #1,r0
jsr pc,row

;и нижняя
mov #^O24001, r4
jsr pc,row


kk: ; тупо заглушка
 br kk


row:
mov #^O40, r3 ;32
lp: movb r0,(r4)
add #^O36,r4 ; +30
inc r0
sob r3,lp
rts pc
END:



Ну вот и все, запись пока останется, чтобы не вспоминать про нюансы и не хранить сведения.
Здесь эмулятор, ассемблер и примеры вместе со сканом руководства(стянул с дохлого сайта)

Комментарии