Эмуляция Sinclair zx80/zx81

от автора

image

Многие согласятся, что возникшая пандемия COVID-19 изрядно попортила жизнь IT-сообществу. Но речь пойдет не о темной полосе, а о другом эпизоде.

Уже в марте была отменена известная demoparty Forever 2020, а позже мероприятие перенесено на осень. Задолго до отмены, я общался с организаторами. Они отказались принять одну мою работу, мотивируя тем, что нет Apple II, попросили взамен видео работы с реального компьютера.

Что же, получить запись мне не удалось, поэтому я обратил внимание на список платформ:
Amstrad CPC, Thomson, PMD-85, MSX, ZX81, Sam Coupe, all non-C=64 8-bit Commodores or any other 8-bit system

Меня привлек ZX81, так как я уже пытался изучить компьютер, но потерпел крах.

Исследования пошли по привычной для меня схеме:

Эмулятор

Я выбрал EightyOne
взял версию 1.6.1. У версии удобный отладчик, но программа не эмулирует другую модель — ZX80, позже я нашел другой билд 3.7.

Кросс-средства

Поиск вывел на FASM(топик на форуме, адаптированный для платформы. Однако, скомпилированные примеры не запускались. Я попробовал и другие варианты ассемблера — Pasmo и другие, но так и не собрал рабочую программу.

Долгие поиски вывели на пример печати Hello, world!

О, чудо! получилось! Теперь пришел черед к третьему эпизоду.

Документация

Часть информации нашлась тут
Дизассемблер ПЗУ здесь

Карта памяти:

0000-1FFF - ROM 2000-3FFF - Shadow ROM. Назначение не описано, иногда упоминается Interface 1 4000-7FFF - память 16К 

Часть памяти отведена для системных переменных.

Далее по адресу 16509 хранится программа на Бейсике и её переменные.

Программа на Бейсике содержит формат:

2 байта номер строки в формате big endian 2 байта длина строки ... сама программа 1 байт ($76) - новая строка

Для кассеты возможны только программы на Бейсике, был предложен такой способ:

1 REM (бинарные данные или машинный код) 2 RANDOMIZE USR(16514) - тот самый адрес программы, хранящейся после REM 

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

В указанном примере это реализовано так:

D_FILE:     defw    display_file  display_file:   defb    _NL         defs    32 ...         defs    32         defb    _NL 

Первый байт — признак начала строки, затем 32 байта пробелы.

Так получилось 24 строки, что выглядело громоздко.

Первая программа, которую я написал:

image

;compile with sjasmplus 	device zxspectrum128  p_start:    org 0x4009 begin  VERSN:      defb    0 E_PPC:      defw    20      ; BASIC line number of line with cursor. D_FILE:     defw    display_file2 DF_CC:      defw    display_file2+1 VARS:       defw    variables DEST:       defw    0 E_LINE:     defw    edit_line CH_ADD:     defw    p_end-1 X_PTR:      defw    0 STKBOT:     defw    p_end STKEND:     defw    p_end BERG:       defb    0 MEM:        defw    MEMBOT SPARE1:     defb    0 DF_SZ:      defb    2       ; Number of lines in lower part of screen. S_TOP:      defw    10      ; BASIC line number of line at top of screen. LAST_K:     defw    0xffff DB_ST:      defb    0 MARGIN:     defb    55      ; Blank lines above/below TV picture: US = 31, UK = 55. NXTLIN:     defw    display_file    ; Memory address of next program line to be executed. OLDPPC:     defw    0 FLAGX:      defb    0 STRLEN:     defw    0 T_ADDR:     defw    0x0c8d SEED:       defw    0 FRAMES:     defw    0       ; Updated once for every TV frame displayed. COORDS:     defw    0 PR_CC:      defb    0xbc S_POSN:     defb    0x21,0x18 CDFLAG:     defb    0x40 PRBUF:      defs    0x20         defb    _NL MEMBOT:     defs    0x1e SPARE2:     defw    0  ; Start of the BASIC area for user programs.  basic_0001: defb    0,1     ; 1 REM         defw    basic_0010-basic_0001-4         defb    _REM  ; Start of user machine code program mem_16514: 	ld hl,p_end;display_file2 	push hl ;cls 	ld c,25 c1: 	ld b,32 	ld (hl),$76:inc hl c2: 	ld (hl),0:inc hl 	djnz c2 	dec c 	jr nz,c1  	pop hl 	push hl 	ld c,$0 ylp: 	ld (hl),$76 	inc hl 	ld b,32 xlp: 	ld (hl),c 	inc hl 	inc c  	bit 6,c 	jr nz,endp;ret nz 	djnz xlp 	jr ylp endp: 	pop hl 	ld (D_FILE),hl 	jr $ display_file2:  dup 25  defb _NL  edup   end 	display /d,end-begin 	savebin "prb.p",begin,end-begin 

Укороченный вариант подсказал этот топик.

Один недостаток: после загрузки программа не отображается нижняя строка. Это неудивительно, ведь строки пустые.Чтение руководств подсказало на еще одно изменение:

NXTLIN:     defw    basic_0010 ; адрес памяти выполняемой строки

Получился такой простой трюк: после загрузки не нужно набирать RUN, программа запустится сама.

Если коротко, то я опишу суть программы: сначала заполнение видеопамяти по образцу, как было в программе печати «Hello, world», затем заполнение строк символами с кодами 00-63.

image

При первой разработке я ошибся и написал заполнение символов с кодами 00-255, но программа не заработала, так как часть кодов не используется
Результатом исследований стала работа kerr, которая покажется неинтересной, но для меня сама программа — большое достижение.

А до проведения demoparty есть масса времени, которое будет потрачено на разработку программу в номинацию 1k.

Остался ZX80.

Для него есть другой порядок системных переменных.

Софт хранится здесь.

Поэтому я набрал программу и посмотрел в отладчике:

image

Здесь есть небольшое ограничение — память 1к, поэтому нужно подумать, какую программу написать.

Может быть, я напишу когда-нибудь.

ссылка на оригинал статьи https://habr.com/ru/post/497930/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *