nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 09:31



Reply to topic  [ 129 posts ]  Go to page 1, 2, 3, 4, 5 ... 9  Next
Кросс-ассемблер для PDP11/8080 (Windows/Linux, open-source) 
Author Message
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Программа оказалась (относительно) востребованной, уже год просят доработать, поэтому я возрождаю разработку.

https://github.com/alemorf/pdp11asm

Изменения:
5-01-2017 Добавил директиву include.

Последняя информация по кросс-ассемблеру:

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

.INCLUDE "file"
Подключить файл

ORG N
.LINK N
Устанавливает адрес, куда будет выводится код после этой команды. По умолчанию используется адрес 0.

DB
.BYTE
Записать байты. Через запятую можно указывать числа, '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) r Cдвиг вправо, старший бит дублируется
ASL(B) r Cдвиг вправо, младший бит равен 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 команды интерпретируются как числовые метки.

Особенности

- Некоторая совместимость с транслятором MACRO11. Но макросов нет.

- Примитивная арифметика. Например текст 2+5-1 будет преобразован в число 6. Соответственно Label1 + 6 это адрес на 6 больше адреса метки Label1.

- Со скобками надо быть осторожнее, скобки вокруг аргумента так же обозначают режим адресации: (1+2) - это значение по адресу 3, (1+2)*1 - это значение 3.

- Числовые метки. Например "10:". Их область видимости ограничена символьными метками. И их можно использовать только с командами условного перехода: B? и SOB. Любое положительное число в аргументе этих команд интерпретируется как метка.

- При таком подходе любимая PDP-шниками команда "SOB R1, .-2" не работает, так как 2 интерпретируется как метка. Но благодаря исключению с отрицательными числами можно написать "SOB R1, .+-2". -2 в тут считается числом на уровне парсера. Похоже на костыль, но я не знаю как сделать красивее. (Знал, но проект давно остановлен и я опять забыл)

- По умолчанию числа 8-ричные. Что бы указать 10-чное число, необходимо в конец числа добавить точку. Например "16384.".

- C помощью команды DECIMALNUMBERS можно включить по умолчанию десятичные числа. Восьмиричные числа тогда начитаются с нуля, например 017666. Или можно добавить постфикс 17555o. Обратно включить по умолчанию 8-ричные числа можно командой DECIMALNUMBERS OFF.

- В одной строке может быть несколько команд. Перенос строки теперь не обязателен.

- Добавлены синонимы: RET = RTS PC, CALL = JSR PC.

- В примерах к компилятору игра Сапер.

- Команда .i8080 включает систему команд процессора Intel 8080 и можно писать программы для него. Это было сделано для написания прошивки для SMP компьютера на 8080 и ВМ1.

- Компилятор осилил исходники CP/M споткнувшись лишь на крайне странной строке "CCPSTACK:EQU $". Можно быть написать "CCPSTACK:" или "CCPSTACK EQU $", что идентично. Но не вместе же. Эту строку я поправил руками.


Last edited by alemorf on 05 Jan 2017 06:48, edited 1 time in total.



05 Jan 2017 06:21
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Баг 1

Image

Баг 2

Локальные метки не правильно компилируются, и похоже они в 8-ми ричном формате и просто через функцию парсятся, например 00 и 0 я так понял одно и тоже

Баг 3

не хватает команд типа SOB RN,.-2 - приходится ставить лишнюю не нужную метку (

Баг 4

ну и как ещё идеальный вариант типа MOV #10.*2,R0 - то есть умножения перед компиляцией, деление наверно не нужно, если только например целочисленное, если не целое число, чтобы warning выдавался

(арифметику сложно встроить в синтаксис ничего не поломав, надо думать)


05 Jan 2017 06:26
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
И еще пожелания пользователей

 Тубро-Ассемблер Макро 7М
Attachment:
Turbo7M.png
Turbo7M.png [ 277.82 KiB | Viewed 27221 times ]


Last edited by alemorf on 05 Jan 2017 06:56, edited 1 time in total.



05 Jan 2017 06:33
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Убрал про картинки диалог раз уж и так всё ок теперь...

P.S. В комментариях исходников всё ещё твой старый ник виднеется :roll:

P.P.S. В январе 2018 года адаптировал код для cygwin, исправил багу @NUMBER и поддержал создание образов ПЗУ для МК85

Комментарий первоначального автора по поводу лицензии см. тут (февраль 2018)

P.P.P.S. С июня 2018 прожэкт живёт в моей репе на GitLab:

https://gitlab.com/shaos/pdp11asm85

P.P.P.P.S. Архив с исходниками pdp11asm85-master.zip обновлён до версии от февраля 2024 года:

P.P.P.P.P.S. Обновлённый EXE-шник под WinXP приаттачен в архиве pdp11asm85.7z вместе с cygwin1.dll


Attachments:
pdp11asm85.7z [1.68 MiB]
Downloaded 17 times
pdp11asm85-master.zip [259.37 KiB]
Downloaded 16 times

_________________
:dj: https://mastodon.social/@Shaos
05 Jan 2017 09:04
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Если ассемблер встречает символ {, то дальше ведет себя как компилятор Си. Писал всего 5 часов, поэтому о серьзености компилятора СИ говорить рано.

Результат трансляции Си в Asm PDP11

Code:
; 23 i = (a->fattrib&0x10);
MOV 0(SP), R0
MOV 11(R0), R0
ANDB #16, R0
MOVB R0, 4(SP)
; 24 j = (b->fattrib&0x10);
MOV 2(SP), R0
MOV 11(R0), R0
ANDB #16, R0
MOVB R0, 5(SP)
; 25 if(i<j) return 1;
CMPB 5(SP), 4(SP)
BHIS 1
0:
; 25 return 1;
MOV #1., R0
RET
1:
; 26 if(j<i) return 0;
CMPB 4(SP), 5(SP)
BHIS 3
2:
; 26 return 0;
MOV #0., R0
RET
3:
; 27 if(1==memcmp(a->fname, b->fname, sizeof(a->fname))) return 1;
PUSH #11
PUSH 2(SP)
PUSH 0(SP)
CALL memcmp
ADD #6., SP
CMPB R0, #1
BNE 5
4:
; 27 return 1;
MOV #1., R0
RET
5:
; 28 return 0;
MOV #0., R0
RET


06 Jan 2017 19:47
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
А компилятор Си для 8080 сгинул?...

_________________
:dj: https://mastodon.social/@Shaos


06 Jan 2017 21:36
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Shaos wrote:
А компилятор Си для 8080 сгинул?...


Лежит у меня. Я ниего не удалял, просто на диск скачал. Я из старого компилятора кое что для нового компилятора вытащил.

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

Первую версию я не сохранил.

Сейчас опять делаю самый простой вараинт компиляции. Компиляция для PDP11 уже работает. Компилятор получился всего 30 Кб. Он компилирует "expression tree" (ну или типа того), который формируется при анализе C файла. Поэтому такой маленький.

Остались мелочи типа создания двоичного файла (а не текстового), выделение места в стеке под переменные, какие команды перехода использовать: far или short. Препроцессор. Всякие последовательности \r\n в строке.


09 Jan 2017 02:28
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Quote:
А во втором я начал делать супер-пупер оптимизатор, который переставляет коанды местами, размещает переменные в разных регистрах. Причем по ходу кода в разных регистрах могут храниться разные переменные. Но дописать и до отладить это у меня не было времени.

Ну выложил бы на гитхабе, что есть, а люди бы и дописали, и доотладили :roll:

_________________
:dj: https://mastodon.social/@Shaos


09 Jan 2017 07:27
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Shaos wrote:
Quote:
А во втором я начал делать супер-пупер оптимизатор, который переставляет коанды местами, размещает переменные в разных регистрах. Причем по ходу кода в разных регистрах могут храниться разные переменные. Но дописать и до отладить это у меня не было времени.

Ну выложил бы на гитхабе, что есть, а люди бы и дописали, и доотладили :roll:


А оно уже разлетелось по гитхабу. Вчера где то там нашел.

Я не в ту сторону оптимизировал. Конечно круто, когда программа работает быстро. Но оказалось куда важнее, что бы программа места немного занимала.
60 килобайт хватает далеко не на все хотелки. Хочется сделать еще лучше, но память уже закончилась.


09 Jan 2017 08:41
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Банки памяти поддержать :)
Пока банками умеет щелкать только z88dk и то надо свой код прописывать в заглушки переключалок (я сам не пробовал, просто читал)

_________________
:dj: https://mastodon.social/@Shaos


09 Jan 2017 09:04
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Shaos wrote:
Банки памяти поддержать :)
Пока банками умеет щелкать только z88dk и то надо свой код прописывать в заглушки переключалок (я сам не пробовал, просто читал)


Переключение страниц при обращении к статическим переменным сделать не сложно. Можно даже автоматически разместить эти переменные так, что бы переключений было меньше.

А вот с указателями придется делать по медленному. Как во времена MSDOS указатель будет представлять собой 2 слова: сегмент+смещение. Ну и каждое обращение по такому указателю, это дополнительная запись в регистр страницы.

Либо как было сделано для микроконтроллеров AVR. Добавить номер страницы в тип указателя.

uint8_t _page1[64]
void _page1* a
unsigned _page2* _page0* b;


09 Jan 2017 10:26
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
лучше как в досе - тип указателя far (и указатель становится 4 байта вместо 2), как минимум это логично (а указывать страницы при создании указателя - не очень)

_________________
:dj: https://mastodon.social/@Shaos


09 Jan 2017 11:16
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Shaos wrote:
лучше как в досе - тип указателя far (и указатель становится 4 байта вместо 2), как минимум это логично (а указывать страницы при создании указателя - не очень)


Ну это скорость уменьшит в 3 раза.

Сейчас *a = 0xAAAA; компилируется в

mov #0xAAAA, @2(SP)

а будет

mov 2(SP), R0
mov 4(SP), SYS_PAGE_REG
mov #0xAAAA, (R0)


09 Jan 2017 13:54
Profile WWW
Senior

Joined: 03 Jan 2017 08:58
Posts: 135
Location: SPb
Reply with quote
Сегодня потратил единственный час на добавление дизассемблера. Надо как то проверять, что там компилятор накомпилировал.

Code:
0023 0006                            //10 uint16_t* a = (uint16_t*)0x4000;
0023 0006 017266 040000 000002       mov #16384, 2(SP)
0023 000C                            //12 if(*a) test(23);
0023 000C 016700 000002              mov @2(SP), R0
0023 0010 005700                     tst R0
0023 0012 001400                     beq 5
0023 0014                            //12 test(23);
0023 0014 017264 000027              mov #23, -(SP)
0023 0018 004772 000000              jsr PC, test
0023 001C 067260 000002              add #2, SP
0023 0020                            5:
0023 0020                            //13 i=0x2000;
0023 0020 017266 020000 000004       mov #8192, 4(SP)
0023 0026                            4:
0023 0026                            //15 do {
0023 0026                            //16 *a = 0xAAAA;
0023 0026 017267 125252 000002       mov #43690, @2(SP)
0023 002C                            //17 a++;
0023 002C 067266 000002 000002       add #2, 2(SP)
0023 0032                            //18 i--;
0023 0032 005366 000004              dec 4(SP)
0023 0036                            //19 } while(i);
0023 0036 016600 000004              mov 4(SP), R0
0023 003A 005700                     tst R0
0023 003C 001000                     bne 4


TST уберу потом. И регистровые переменные сделаю.


09 Jan 2017 13:59
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
alemorf wrote:
Shaos wrote:
лучше как в досе - тип указателя far (и указатель становится 4 байта вместо 2), как минимум это логично (а указывать страницы при создании указателя - не очень)


Ну это скорость уменьшит в 3 раза.

Сейчас *a = 0xAAAA; компилируется в

mov #0xAAAA, @2(SP)

а будет

mov 2(SP), R0
mov 4(SP), SYS_PAGE_REG
mov #0xAAAA, (R0)

Ну так это от автора компилируемой программы зависит - если поставил ключевое слово far, то ожидай что будет чуть медленнее, а если хочешь быстрее - не ставь far :)
Но это наверное тут оффтоп :)

P.S. Форк C8080 вроде нашел - форкнул себе...

_________________
:dj: https://mastodon.social/@Shaos


09 Jan 2017 16:43
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 129 posts ]  Go to page 1, 2, 3, 4, 5 ... 9  Next

Who is online

Users browsing this forum: Mondx and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.