Разработка и эмуляция МК-85

 


Жил-был один поляк, который писал эмуляторы калькуляторов. В один день гавкнулся хостинг, и сайт пропал. Позже часть калькуляторов исчезла из списка, но к счастью сохранилась копия сайта.

Сами эмуляторы допиливались на основе исходников. Мне попалась версия 49.

О программировании можно прочитать в приложенных доках к архиву - нажать кнопку [MODE],1 и вводить текст. [MODE],0 - возврат к выполнению программы. 

Пользователи калькулятора обнаружили один баг(или фича?), который описал разработчик калькулятора - баг позволяет выполнять машинный код. Проверено.

Отсюда я начал двигаться - взял подготовленный Starter program - это образ памяти ram.bin, который используется эмулятором. Проверил: ввожу RUN, жму Enter. На экране появляется ?, нажимаю [AC],[EXE], на экране появилась надпись HELLO,WORLD!. Стал искать точку запуска. У эмулятора есть некоторые изменения, F3-вызов отладчика. В отладчике в поле Breakpoints надо указать 8272, нажать кнопку Run.


Проделываю описанные действия, и перехожу на адрес 8272


Переход bmi 82B6 это и есть нужное значение.

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


Долго разбирался, как рисовать на экране, в описании указан адрес $8000. Ни ввод в отладчике, ни программный код, записывающий значения по адресу не дал результата. Взял дизассемблерованный код docs\ mk85.src и стал изучать процедуры. Внимание привлекло это

; print character r0 at position 8269
09F8: bic #FF00,r0
09FC: dec r0 ;character codes start from 1
09FE: mov r0,-(sp)
0A00: asl r0
0A02: asl r0
0A04: asl r0
0A06: sub (sp)+,r0 ;r0 = 7*r0
0A08: add #3AB0,r0 ;font table, each entry occupies 7 bytes
0A0C: cmp #3D49,r0 ;code 0x60 - user defined character
0A10: bne 0A16
0A12: mov #81AD,r0 ;user defined character
0A16: movb 8269,r1 ;cursor position
0A1A: asl r1
0A1C: asl r1
0A1E: asl r1
0A20: add #8001,r1 ;address in the display memory
; copy 7 rows to LCD RAM and display memory
0A24: movb (r0),8080(r1) ;send pattern to LCD RAM
0A28: movb (r0)+,(r1)+ ;write pattern to display memory

0A2A: bit #7,r1
0A2E: bne 0A24
0A30: rts pc

Получается, что нужно записать данные и по адресу $80 и по $8000. Или, очистка экрана:

; clear screen

0A32: mov r0,-(sp)

0A34: mov #80,r0

0A38: inc r0
0A3A: clrb 7F80(r0)
0A3E: clrb (r0)+
0A40: bit #7,r0
0A44: bne 0A3A
0A46: cmp r0,#E0
0A4A: bcs 0A38
0A4C: movb #C,(r0) ;hide cursor
0A50: mov (sp)+,r0
0A52: bisb #1,8264 ;long delay between scrollings
0A58: clrb 8269 ;cursor position
0A5C: rts pc


Вот только с рисованием и не особо разгуляешься - разрешение блоков 5 точек в ширину и 7 в высоту. Но, если посмотреть на написанные программы, то авторы умудрялись втиснуться в маленький размер.

Отдельно следует упоминать о команде SETC, которая позволяет задать вид пользовательского символа с кодом $60:


10 LETC "4DSTSD4" // сгенерить символ
20 CSR 11:PRINT CHR 96; // подать звуковой сигнал и зажечь светодиод

Символы преобразуются в данные так:

0 00000
1 00001
2 00010
3 00011
4 00100
5 00101
6 00110
7 00111
8 01000
9 01001
A 01010
B 01011
C 01100
D 01101
E 01110
F 01111
G 10000
H 10001
I 10010
J 10011
K 10100
L 10101
M 10110
N 10111
O 11000
P 11001
Q 11010
R 11011
S 11100
T 11101
U 11110
V 11111

Этих сведений и инструментов пока хватает.

Комментарии