Эмуляция GMC-4

 


Дошли руки до этой игрушки. Скачал эмулятор, документацию и стал изучать. Компьютер 4битный, поэтому регистры 4битные. Это регистры A,B и индексные Y,Z, заодно A',B',Y',Z'. На программу отведено 79 байт по адресам $00-$4F. Следующие адреса $50-$5F это память, которая может быть использована для данных. $66-$6F предназначены для хранения регистров.

При изучении описания команд встретится флаг результата F, который может измениться в зависимости от результата.

Всего 31 команда. 

KA(опкод 0) - чтение нажатой клавиши, код помещается в A, флаг F устанавливается в 1, если клавиша нажата, 0 - если нет.

простой цикл опроса нажатия клавишей:

L: KA
 JUMP L

Команда JUMP(опкод F, затем два значения адреса)выполняет переход по адресу, если флаг F=1. Если F=0, то переход игнорируется. Чем-то напоминает skip-опкоды от PDP1.

AO(опкод 1) отображение значения A на 7-сегментном цифровом индикаторе.

Поэтому программа будет простой:

L: KA
 AO
 JUMP L

Следует заметить, что после выполнения некоторых команд флаг F устанавливается в значение 1, поэтому здесь произойдет вечный цикл. Запустить программу просто - набрать текст, выбрать Simulator->Build, Simulator-Run Mode.

Кроме вывода данных есть еще команда, которую опишу позже. Следующие две - команды обмена регистров:

CH(опкод 2) обмен A и B, Y и Z

CY(опкод 3) обмен A  и Y

Обратите внимание, что для этих команд F=1.

Операции с памятью.

AM(опкод 4) запись A по адресу $50+Y

MA(опкод 5) чтение A по адресу $50+Y

M+(опкод 6) сложение  содержимого ячейки памяти по адресу $50+Y с A. флаг F=1, если переполнение.

M-(опкод 7) вычитание  A из ячейки $50+Y. Если результат A отрицательный, то F=1

Загрузка  регистров и сложение

TIA(опкод 8, число) помещение значение в A

AIA(опкод 8, число) сложение A с числом

TIY(опкод A, число) помещение значение в Y

AIY(опкод B, число) сложение Y с числом

Сравнение

CIA(опкод C, число) сравнение A с числом. Если A равно числу, то флаг F=0, иначе =1.

CIY(опкод D, число) сравнение Y с числом. Если Y равно числу, то флаг F=0, иначе =1.

Расширенные операции

CAL RSTO(E0) очистка 7 сегментного индикатора

CAL SETR(E1) зажечь светодиод Y=номер

CAL RSTR(E2) сбросить светодиод Y=номер

-(E3) не используется

CAL CMPL(E4) A=-A

CAL CHNG(E5) обмен A/B/Y/Z с A'/B'/Y'/Z'

CAL SIFT(E6) сдвиг A вправо на 1 бит. С описанием состояния флага F неясно - то ли 0, то ли 1.

CAL ENDS(E7) проигрывает звук конца(не проверил)

CAL ERRS(E8) проигрывает звук ошибки

CAL SHTS(E9) проигрывает короткий звук

CAL LONS(EA) проигрывает длинный звук

CAL SUND(EB) проигрывает звук нот, значение A(1-E)

CAL TIMR(EC) пауза (A+1)*0.1 секунды

CAL DSPR(ED) установка светодиодов в зависимости от состояния памяти: старшие три бита из ячейки $5F (биты 0-2), младшие 4 - из $5E(биты 0-3)

CAL DEM-(EE) трудности с переводом: DEC((Y)-Ar)→(Y),Y--

CAL DEM+(EF) трудности с переводом: DEC((Y)+Ar)→(Y),Y--

Переход

JUMP (опкод F, да ниббла адрес) переход, если флаг F=1, иначе игнорируется.


Теперь можно сделать из компьютера пианино:

L: KA
 JUMP L
 CAL SUND
 JUMP L

Теперь я решил написать программу для тренировки, хотя сам мало что понимал. Позже я нашел подобную программу:

I: 
TIY 0
L:CAL SETR;Y=number
 TIA 10
 CAL TIMR
 CAL RSTR
 AIY 1
 CIY 7;if Y=7, F=1 else F=0
 JUMP L; jump if F=1
 JUMP I

Программу можно отладить. После  выполнения команды Build  надо нажать кнопки RESET,6,RUN и нажимать INCR для выполнения команд.

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

;50 - N(0)
;51 - dN(1)
;set variables
 CAL RSTO
 TIA 1
 TIY 1
 AM;poke($50+Y),A
 TIA 0
 TIY 0
 AM;poke($50+Y),A
M:
 TIY 0
 MA;A=peek($50+Y)
 CY ;A<>Y
 CAL RSTR
 CY
 TIY 1; Y=1
 M+ ;A=A+peek($50+Y)
 TIY 0
 AM;poke($50+Y),A
 CY
 CAL SETR
 CY
 CIA 6;if A<>6, F=1 else F=0
 JUMP T
 JUMP C_H; jump if F=1
T:
 CIA 0 ;if A<>0, F=1 else F=0
 JUMP N
C_H: ;change dn
 TIY 1
 MA;A=peek($50+Y)
 CAL CMPL
 AIA 1
; CIA 1 изменения в программе
; JUMP S
; TIA 15
; JUMP PU
;S: TIA 1
PU: AM;poke($50+Y),A
N:
 TIA 1
 CAL TIMR
 JUMP M


И напоследок еще одна программа - отображение кодов в бинарном виде:


;key input loop
K: KA
 JUMP K
 AO
 TIY 3
L:
 CAL RSTR
 AM
 M+ ;F=1 if overflow
 JUMP SE; jump if F=1
 JUMP N
SE: CAL SETR
N:AIY F ; Y=y-1
 CIY F; if Y=f then F=0
 JUMP L
 JUMP K

Здесь файл с доками и примерами. К коду еще вернусь, есть пара задумок.

Комментарии