Бульник. Странная, ничего не делающая игра

Наткнулся в каталоге игр для Радио 86РК на интересную строчку.
Игра Бульник
Странная, ничего не делающая игра.

Дизассемблированный код всего три строчки.
lxi h,$0109
call $f818
hltКонец истории?
Анализ выводимых данных пролил свет на то, как почти 40 лет назад делали картинки.
Для начала получил дамп строки в текстовом виде.
1F 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
7B 7B 7B 7B 0D 20 20 20 20 20 20 20 20 20 20 20Затем стал заменять коды символов на символы.
1F на f, 20 на знак подчеркивания.
f _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
7B 7B 7B 7B 0D _ _ _ _ _ _ _ _ _ _ _После замены всех кодов и удаления пробелов получилось представление выводимой строки.
f______
________________
ШШШШd___________
___________aШ__Ш
da______________
______ШШШШШШШШda
________________
____Ш______Шda__Сначала склеил кусочки строк и разрезал после символов d (код 0D, возврат каретки).
f______________________ШШШШd
______________________aШ__Шd
a____________________ШШШШШШШШd
a____________________Ш______Шd
a____________________ШШШШШШШШd
a__________________ШШ________ШШПервые строки завершались кодом 0D, но дальше стали встречаться строки без этого кода.
Так же видны символы a (код 1A). Логично было бы в этом месте видеть код 0A — перевод строки.
Дальше хуже — целые серии символов 8 (код 08) и 1 (код 18), которые не понятно что делают.
Для разъяснения нашел в листинге процедуры монитора, печатающей символ, обработку специальных кодов.
mov c, a
cpi 1Fh
jz PRINT_CHAR_CLS
cpi 0Ch
jz PRINT_CHAR_HOME
cpi 0Dh
jz PRINT_CHAR_CR
cpi 0Ah
jz PRINT_CHAR_LF
cpi 8
jz PRINT_CHAR_LEFT
cpi 18h
jz PRINT_CHAR_RIGHT
cpi 19h
jz PRINT_CHAR_UP
cpi 1Ah
jz PRINT_CHAR_DOWN
cpi 1Bh
jz PRINT_CHAR_AR2
cpi 7
jnz PRINT_CHAR_OTHERSС кодами стало всё ясно.
f (код 1F) — очистка экрана.
а (код 1A) — перемещение курсора вниз.
8 (код 08) — перемещение курсора влево.
1 (код 18) — перемещение курсора вправо.
Можно вставлять подготовленные строки в исходный код и экспериментировать.
В качестве кросс‑компилятора я использую WLA DX (Wzonka‑Lad Assembler Deluxe)
В нём есть удобный функционал для работы со строками.
В начале файла можно указать таблицу перекодировки.
.stringmaptable symbols "symbols.tbl"В тексте используется конструкция:
.stringmap symbols,"{CLS}"В таблице перекодировки каждый символ описывается в строке вида
1f={CLS}1 f — код, который скомпилируется
{CLS} — подстрока из исходного кода, которая скомпилируется в код.
В качестве подстроки хорошо работают строки в utf-8, в т.ч. на русском. Благодаря этому используемые в РК86 русские буквы кодируются так:
68=Х
6f=О
7b=ША в исходном коде используются так (по‑русски, в utf-8):
.stringmap symbols,"{CLS}______________________ШШШШ{CR}"
.stringmap symbols,"______________________{DOWN}Ш__Ш{CR}"
.stringmap symbols,"{DOWN}____________________ШШШШШШШШ{CR}"
.stringmap symbols,"{DOWN}____________________Ш______Ш{CR}"
.stringmap symbols,"{DOWN}____________________ШШШШШШШШ{CR}"
.stringmap symbols,"{DOWN}__________________ШШ________ШШ"Для удобства стрелки влево, вправо закодировал символами < >.
Итоговое сообщение стало выглядеть так:
.stringmap symbols,"{CLS}______________________ШШШШ{CR}"
.stringmap symbols,"______________________{DOWN}Ш__Ш{CR}"
.stringmap symbols,"{DOWN}____________________ШШШШШШШШ{CR}"
.stringmap symbols,"{DOWN}____________________Ш______Ш{CR}"
.stringmap symbols,"{DOWN}____________________ШШШШШШШШ{CR}"
.stringmap symbols,"{DOWN}__________________ШШ________ШШ"
.stringmap symbols,"{DOWN}<<<<<<<<<<<<<<<ШШШ____________ШШШ{DOWN}<<<<<<<<<<<<<<<<<<<<<"
.stringmap symbols,"<<<<<<<<ШШШШ_____ШШ__________________ШШ<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>_____ШШШШ__________{CR}{CR}"
.stringmap symbols,"_{DOWN}___Ш__Ш___ШШШ____________________ШШШ___Ш__Ш__________{CR}"
.stringmap symbols,"{DOWN}_____Ш__Ш__ШШ___ООО_________ООО____ШШ__Ш__Ш___________{CR}{CR}"
.stringmap symbols,"{DOWN}_____Ш__Ш__Ш____ООО_________ООО_____Ш__Ш__Ш_____________{CR}"
.stringmap symbols,"{DOWN}______Ш__Ш_ШШ____О___________О_____ШШ_Ш__Ш______________{CR}{CR}"
.stringmap symbols,"_{DOWN}_____ШШ__ШШШШ______ШШШШШШШ_______ШШШШ__ШШ____________{CR}"
.stringmap symbols,"{DOWN}_______ШШШШШШШШ____ШШШ___ШШШ_____ШШШШШШШШ_____________{CR}"
.stringmap symbols,"{DOWN}_____________ШШШ________________ШШШ_____________________{CR}"
.stringmap symbols,"{DOWN}_______________ШШШ___ООООО____ШШШ_____________________{CR}"
.stringmap symbols,"{DOWN}________________ШШШ___ООО____ШШШ______________________{CR}"
.stringmap symbols,"{DOWN}__________________ШШ___О____ШШ{CR}"
.stringmap symbols,"{DOWN}____________________ШШ____ШШ{DOWN}"
.stringmap symbols, "<<<<<<<ШШШШШШ__________________________{CR}"
.stringmap symbols,"{DOWN}ХХХХХХХХХХХХХХХХХХХХ________ХХХХХХХХХХХХХХХХХ!!!!!!!!"
.stringmap symbols,"{DOWN}{DOWN}"
.stringmap symbols,"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_______________________."Оформленный таким образом исходник скомпилировался и побайтно совпал с исходной игрой.
Предположительно эти символы были набраны в каком‑то терминале, записаны и вставлены в код игры.
Для анимации вводимых символов написал альтернативную версию:
ENTRY_POINT:
lxi h,MSG
PRINT_LOOP:
mov a,m
ana a
jz FIN
mov c,a
call 0xf809
inx h
lxi d,0x1388
mvi a,0x00
DELAY_LOOP:
dcx d
nop
nop
nop
nop
cmp d
jnz DELAY_LOOP
cmp e
jnz DELAY_LOOP
jmp PRINT_LOOP
FIN:
hltСтало видно, как оператор печатает символы, перемещает курсор.
Сначала не допечатал верхнюю часть правой ручки, но затем вернулся и допечатал.

Возможно, таким образом почти 40 лет назад готовили картинки для игр.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.