×
Previous Entry Share Next Entry
vinxru

Ассемблер для КР1801ВМ1 (БК0010 / БК0011 / УКНЦ / ДВК / PDP11)

Windows-версия и исходники: http://github.com/vinxru/pdp11asm

Представляю вам первую версию ассемблера для процессора КР1801ВМ1. Этот процессор совместим с системой команд PDP11 и используется в компьютерах БК001x и ДВК. Отдаю скомпилированным под Windows, с исходниками и его можно скомпилировать под другие ОС. В комплекте игра. Лицензия GPL, но как это оформить, я пока не понял. Эмулятор-отладчик можно скачать тут.

Когда то давно я уже писал этот ассемблер. В LJ можно найти про это заметку. Но та версия была потеряна и я не мог опубликовать её исходники, так как несколько файлов были использованы из закрытого проекта. Несколько дней назад ко мне обратился Lasoft со словами: "Видел что ты написал компилятор для Windows, респект! Можешь как-то помочь, может исходники? я хочу попробовать его и если что доработать". И я решил переписать ассемблер заново, да так, что бы он был кросс-платформенным. Наверное не стоило работать бесплатно, ради одного человека, который и не обещал пользоваться и вообще просил исходники. Ну да ладно. Всего два вечера работы. И быть может эта программа пойдет в резюме.

Я знаю, что для PDP-11 стандартом является ассемблер MACRO11. Я его не видел и не трогал. И уверен, что мой ассемблер сильно не совместим с ним. Многое пока не реализовано. Из арифметики поддерживается только сложение и вычитание. Без скобок. Нет макросов, нет условной компиляции, нет include.

Ассемблер формирует BIN файл, который умеет запускать эмулятор B2M. Первые два слова - адрес загрузки, длина. Далее идет двоичный код. А так же формирует LST файл, который эмулятор B2M использует для отладки. В отладчике будут отображаться имена переменных и комментарии, что очень сильно облегчает работу. Но! Почему то LST файл используется только для самых первых строк программы, дальше эмулятор всё забывает. Надо разбираться.

Если кому то потребуются новые возможности, я безвозмездно доработаю ассемблер. А пока пусть будет так. Ну действительно, зачем дорабатывать то, что никому не будет нужно.

Ниже следует краткое описание всех команд ассемблера:

Команды программы


ORG N
.LINK N
Устанавливает адрес, куда будет выводится код после этой команды. По умолчанию используется адрес 0.
DB
.BYTE
Записать байты. Через запятую можно указывать числа в формате: 10 - десятичный, 010 - восьмеричный, 0x10 - шестнадцатеричный, 10b - десятичный, 'A' - код символа, "ABCD" - несколько кодов символов. Так же поддерживается конструкция N DUP(C) записывающая N раз байт C.
DW
.WORD
Записать слова.
.ASCII /text/Вывести текст.
.ENDИгнорируется
.BLKB NВывести N байт 0.
.BLKW NВывести N слов 0.
name EQU value
name = value
Установить константу. Во всем файле name будет автоматически заменяться на value.
name:Метка. Во всем файле name будет заменяться на адрес метки.
N:Числовая метка. Область действия метки ограничивается символьными метками. Такая метка может быть использована только в командах условного перехода B? и SOB.
MAKE_BK0010_ROM "filename", start, endСформировать файл поддерживаемый эмулятором B2M. start, end - начальный и конечный адрес программы. Можно использовать метки.
MAKE_BINARY_FILE "filename", start, endВыгрузить образ памяти в файл. start, end - начальный и конечный адрес. Можно использовать метки.
INSERT_FILE "filename", offset, sizeВставить двоичный файл. Можно вставить часть файла, задав размер и смещение в исходном файле.
ALIGN NВыровнять адрес следующей команды на N-байт.
CONVERT1251TOKOI8RВключить преобразование строк из кодировки 1251 в KOI8R.
CONVERT1251TOKOI8R OFFВыключить преобразование строк из кодировки 1251 в KOI8R.
DECIMALNUMBERSДалее все числа по умолчанию 10-ричные. В стандарте C.
DECIMALNUMBERS OFFДалее все числа по умолчанию 8-ричные. В конце 10-чных чисел необходимо ставить точку.
INSERT_BITMAP1 "name", width, heightВставить изображение преобразовав его в формат видеопамяти БК0010 2 цвета. Изображение должно быть в формате BMP 24 бита. width, height должны соответствовать размеру изображения в файле.
INSERT_BITMAP2 "name", width, heightВставить изображение преобразовав его в формат видеопамяти БК0010 4 цвета. Изображение должно быть в формате BMP 24 бита. width, height должны соответствовать размеру изображения в файле.
INSERT_BITMAP1T "name", width, heightВставить изображение преобразовав его в NAND и OR маски 2 цвета. В качестве прозрачного цвета используется #FF00FF.
INSERT_BITMAP2T "name", width, heightВставить изображение преобразовав его в NAND и OR маски 4 цвета. В качестве прозрачного цвета используется #FF00FF.
; text
// text
Комментарий
.Адрес этой команды

Команды процессора без аргументов


HALTОстанавливает ЦП
WAITОстанавливает ЦП до прерывания
BPTВызов прерывания
IOTВызов прерывания
EMT 0..255Вызов прерывания
TRAP 0..255Вызов прерывания
MARK 0..63Вызов прерывания
RESETПерезагрузка процессора
RTIВыход из прерывания (Загружает PC, PS из стека)
RTTВыход из прерывания пошаговой отладки.
NOPНичего не делает
CLCСбрасывает флаг C
CLVСбрасывает флаг V
CLZСбрасывает флаг Z
CLNСбрасывает флаг N
СCCСбрасывает все флаги
SECУстанавливает флаг C
SEVУстанавливает флаг V
SEZУстанавливает флаг Z
SENУстанавливает флаг N
SCCУстанавливает все флаги
RETСиноним RTS PC

Команды процессора с одним аргументом


(B) описании значит, что существует две версии команды CLRB - обрабатывающей байты и CLR - обрабатывающей слова.


JMP rПереход по адресу
SWAB rПоменять старший и младший байты местами
CLR(B) rЗаписать 0
COM(B) rИнверсия (заменть все биты на противоположные)
INC(B) rУвеличить на единицу
DEC(B) rУменьшить на единицу
NEG(B) rИзменить знак
ADC(B) rУвеличить на единицу, если C=1
SBC(B) rУменьшить на единицу, если С=1
TST(B) rСравнить с нулем
ROR(B) rЦиклический сдвиг вправо через флаг C
ROL(B) rЦиклический сдвиг влево через флаг C
ASR(B) rCдвиг вправо, старший бит дублируется
ASL(B) rCдвиг вправо, младший бит равен 0
SXT rРасширение знака. Если N=0 записывает 0, иначе -1
MTPS rУстановка регистра флагов
MFPS rЧтение регистра флагов
CALL rСиноним JSR PC,

Аргументы команды


R0, R1, R2, R3, R4, R5, SP, PCРегистр. Все регистры 16 битные. 8 битные команды будут работать с младшими их половинами.
(REG) или @REGЗначение по адресу
@(REG)Значение по адресу по адресу.
-(REG)Значение по адресу. Уменьшить регистр до выполнения команды на 1 для байта. И на 2 для слова.
@-(REG)Значение по адресу по адресу. Уменьшить регистр до выполнения команды.
(REG)+Значение по адресу. Увеличить регистр после выполнения команды на 1 для байта. И на 2 для слова.
@(REG)+Значение по адресу по адресу. Увеличить регистр после выполнения команды.
IMM(REG)Значение по адресу, который рассчитывается как сумма регистра и числа.
@IMM(REG)Значение по адресу по адресу, который рассчитывается как сумма регистра и числа.
#AЧисло или адрес переменной.
@#AЗначение по адресу или переменная. Абсолютная адресация.
AЗначение по адресу или переменная. Адрес относительно PC.
@AЗначение по адресу по адресу. Первый адрес относительно PC.

Команды процессора с двумя аргументами


MOV(B) a, bСкопировать
CMP(B) a, bСравнить A и B
BIS(B) a, bЛогическое ИЛИ
BIС(B) a, bЛогическое И-НЕ (B = B & ~A)
BIT(B) a, bЛогическое И без сохранения результата
ADD a, bСложение
SUB a, bВычитание

Команды условного перехода


Могут переходить только в пределах -256..+254 байта, относительно адреса следующей команды. Числа указанные в аргументе команды интерпретируются как числовые метки.


BR immВсегда
BNE immНе равно (Z=0)
BEQ immРавно (Z=1)
BGE immБольше равно для знаковых типов (N^V=0)
BLT immМеньше для знаковых типов (N^V=1)
BGT immБольше для знаковых типов (Z|(N^V)=0)
BLE immМеньше равно для знаковых типов (Z|(N^V)=1)
BPL immРезультат положительный (N=0)
BMI immРезультат отрицательный (N=1)
BHI immБольше (C|Z=0)
BVC immНет знакового переполнения (V=0)
BVS immЗнаковое переполнение (V=1)
BHIS imm / BCC immБольше или равно / нет переполнения (C=0)
BLO imm / BCS immМеньше / переполнение (C=1)

Необычные команды процессора


JSR reg, aВызвать подпрограмму (REG - только регистр, A - любой аргумент)
RTS regВыход из подпрограммы (REG - только регистр)
XOR reg, aИсключающее ИЛИ (REG - только регистр, A - любой аргумент)
SOB reg, immЦикл (REG - только регистр, IMM - адрес). Числа указанные в аргументе IMM команды интерпретируются как числовые метки.

Вообще-то есть опенсорсные компиляторы, GCC и LLVM, например. Зачем изобретать велосипед? Насколько он, например, может оптимизировать код?

> Насколько он, например, может оптимизировать код?
Вообще никак не оптимизирует. Это же ассемблер. Но ни к коем случае не должен ничего оптимизировать.

> Вообще-то есть опенсорсные компиляторы, GCC и LLVM, например.
GCC и LLVM - это совсем другие вещи. А такого компилятора ассемблера нет совсем. А если и есть, то пусть будет еще один.

> Зачем изобретать велосипед?
Между прочим новые модели велосипедом, из новых материалов, с новой конструкцией разрабатывают и появляются постоянно.

А, так это ассемблер.
Ассемблеры вообще-то, компиляторами не называют. Ну тогда ладно, вопросы снимаются.

Компилирует же из текста в машкод, всегда называли компилятором.

Википедия:

Компиля́тор — программа, выполняющая компиляцию[1][2][3].
Компиляция — трансляция программы, составленной на исходном языке высокого уровня, в эквивалентную программу на низкоуровневом языке, близком машинному коду (абсолютный код, объектный модуль, иногда на язык ассемблера)


Исходник должен быть на языке высокого уровня.

Edited at 2015-01-16 02:25 pm (UTC)

Ок :) Переименовал.

Оптимизировать АССЕМБЛЕРНЫЙ код? GCC это умеет?

Я уже написал, что вопросы снимаются. Это не компилятор, это ассемблер.

Это для 8080 и Z80

Слушай, а как у тебя с С++/С#? Шеф вчера обмолвился, что хочет взять еще 1-2 девелоперов.

Я просто в архив с исходниками своих проектов прилагаю лицензии GPL v.3.0 - файл COPYING.
http://www.gnu.org/licenses/gpl-howto.html

Edited at 2015-01-16 02:44 pm (UTC)

Вот один кросс-ассемблер с исходниками:
http://retrocmp.com/tools/macro-11-on-windows

Ну и ссылка на известный форум:
http://zx-pk.ru/archive/index.php/t-20626.html


Отлично, значит мне дописывать будет не нужно.

Транслятор, за два вечера - для меня буквально противоречие в терминах, не думал, что так быстро его можно написать!

Я же его уже писал. Второй раз то же самое изобретать не сложно )

Ну да, как считает Кнут - это лучшее, что может случиться - в какой-то момент потерять код и написать все по-новой, но уже понимая, как это надо сделать)

> и его можно скомпилировать под другие ОС

неа, не соберется. там полно микрософтизмов, начиная от 'safe' string functions и заканчивая попыткой работать с iostreams с wchar_t параметрами.

Это все проблемы?

По поводу safe я думал, это стандарт C++ новый такой.

это то место, где мне надоело :-) там еще пару экранов ошибок.

микрософт, похоже, единственный кто реализовал tr24731, пушо стандарт достаточно бестолковый.


Надо будет мне gcc для windows скачать. Буду проверять.

А стандарт мне понравился. Идея автоматически передавать размер буфера в функцию очень хороша. Как то так

template strcpy_s(char dest[destSize], char* src) { strcpy_s(dest, destSize, src); }

char buf[4];
strcpy_s(buf, "HELLO WORLD");

ну вот это и называется бестолковый стандарт — покрывает один редкий частный случай, причем гарантирует только то, что программа не разнесет свой собственный стек. корректнее с длинными строками она от этого работать не начнет.

в реальности же приходится бороться с чем-то вида:
err_t expandstr(char *template, char **env, char **result /*out*/)
{
   char *res = malloc(...);
   for(char *text = segment_first(template); text!=NULL; text = segment_next(template))
   {
        strcat(res,....);
   }
}


рецепт тут только один — явно отслеживать все размеры.

вощем, если интересно, то вот
https://mega.co.nz/#!E8NSmSJR!loNb57hOnfH98OVw4LzCqK68BOFycMcV4pkSnLW4aoU
это где я остановился. там почти все пофикшено кроме wide strings, с ними оченно много кода надо писать, либо переделывать всю концепцию нафиг.

Спасибо. Я сегодня весь день ликунсы качаю, хотел сам попробовать скомпилировать.

Поставил Ubuntu 10. В комплекте нет C++, из инета автоматически не качается, так как "Больше не поддерживается". Скачал последнюю Ubuntu. Тормозит - ужас! Разрешение только 640x480. Хрен с ним, мне только проверить компиляцию. C++ в комплекте нет. Написал "sudo apt-get install g++" C++ не ставит, пишет миллион строк "Конфликтует...", "Зависит, но не будет установлен", "Рекомендуется, но не может быть установлен". А в конце требует переустановить Убунту. Начал качать Linux Mint 17, на последнем мегабайте упал FireFox. Сейчас качаю еще раз, но уже хромом.

Такие вот дела.

скорее всего сначала надо было distupgrade сделать, там образы дисков несколько окаменевшие по сравнению с тем что в репозиториях — неудивительно что оно конфликтует и не ставится.

но вообще убунта она такая, бардачная немного, поэтому я дебиан предпочитаю.

Что то не могу сообразить, как восстановить твой git bundle.

бандл для гита выглядит просто как еще один внешний remote, поэтому надо просто из него пофетчить что нужно, и смерджить к себе в рабочую ветку тем или иным способом:

$ cd myproject
$ git bundle list-heads ../external.bundle
29fc393d731f0d8257904858ae336a1478251d6a refs/heads/build/linux
$ git fetch ../external.bundle build/linux:external/build/linux
Receiving objects: 100% (57/57), 6.01 KiB | 0 bytes/s, done.
Resolving deltas: 100% (43/43), completed with 10 local objects.
From ../pdp11asm/pdp11asm-portability.bundle
 * [new branch]      build/linux -> external/build/linux


дальше можно с веткой external/build/linux работать обычным образом.

Прочел комменты, так и не понял - будет версия под Линукс или нет?

Да, будет. Я уже скомпилировал под Линукс. Завтра выгружу и заметку про это напишу.