• avatar aa-dav
  • 0
P.S.
Причесал код и внедрил условия и сделал все ключевые слова в нижнем регистре для консистентности. Ссылка на исходник потому изменилась: yadi.sk/d/fTZqZ1n12dD72A
Условия пишутся в любом месте инструкции:
@@ — всегда
@z или @nz — ноль/не ноль
@c @nc — перенос
@gt @gte — больше и больше-или-равно (пока не реализовано)
теперь работает такое:

        r0 = $8
loop    [ counter ] =-1 [ counter ]
        r0 =-1 r0
        pc = loop @nz // эта инструкция перейдёт на loop если не ноль
        dw 0

        org $0030
counter	dw $0010
  • avatar aa-dav
  • 0
Проапгрейдил ассемблер Simpleton еще дальше, теперь программа берет внешний файл source.asm, собирает и исполняет его с адреса 0 пока не наткнётся на инструкцию с кодом 0 (R0 = R0).
Теперь поддерживаются ключевые слова =, org и dw с нюансами.
Программа теперь может выглядеть так:

       R0         =     $FFFF
       R1         =     $CCCC
       R0         -=    R1
       [ first ]  =     R0
       [ second ] =+1   [ first ]
       [ third ]  +=    16
       dw         0     // DEF WORD 0 помещает в текущую ячейку компиляции константу
       org        $0020 // компилируем теперь начиная с адреса $0020
first  dw         0     // first и second теперь заданы
second dw         0     // как два нулевых слова в памяти
       org        $0030 // смещаем адрес компиляции в $0030
third  dw         forth // пример что в качестве DEF WORD слова можно указать символ, причём forward
forth  =          $1000 // через = значение символа задаётся напрямую без записи данных в память
       dw         1     // эта единица в памяти программы следует сразу за $1000 (third)

Основные моменты — регистрозависимость всех идентификаторов и ключевых слов.
Имена регистров: R0-R4, R5 (он же SP), R6 (он же PC), R7 (он же FLAGS).
Машинные команды имеют вид

DEST OP SRC

Где SRC это один из регистров, константа/символ или адрес задаваемый как регистр или константа/символ в квадратных скобках.
OP это операторы в стиле Си:
= присваивание
=+1 инкремент
=-1 декремент
<?> сравнение
+=
-=
+c= то же что и += с учетом флага переноса
-c= то же что и -= с учетом флага переноса
DEST может быть всем тем же что и SRC кроме константы/символа (не в квадратных скобках)
Числовые константы/литералы или десятичные или начинаются с $ и тогда являются шестнадцатеричными.

Если строка начинается не с пробельного символа, то создаётся символ.
Если он предшествует машинной инструкции или dw, то в него записывается её адрес.
Если он предшествует знаку =, то в него записывается константа или значение символа по правую часть от знака. Формульная математика пока не поддерживается вообще.
Если он предшествует ключевому слову org, то он будет равнятся адресу куда переводит компиляцию этот org.
org переводит запись генерируемых инструкций на указанный адрес (origin)
dw прописывает в текущую ячейку данное — оно может быть или константой или символом.
В стиле ассемблера Zilog 80 (и не в стиле ассемблера Intel) имя символа в чистом виде означает адрес ячейки памяти если это метка, а не значение в этой памяти. Чтобы адресовать ячейку надо использовать квадратные скобки.
Т.е.

some_addr = $1000
R0 = some_addr // в R0 запишется $1000
R0 = [ some_addr ] // в R0 запишется значение в ячейке с адресом $1000
some_addr = R0 // такое вообще запрещено, т.к. в констансту нельзя писать, надо:
[ some_addr ] = R0 // а вот это запишет R0 в ячейку памяти
  • avatar aa-dav
  • 0
Чтобы проверить архитектуру на практике, пусть и виртуальной, решил написать то что доступно — эмулятор машины Simpleton 3.x, текущий исходник, если вдруг кому интересно, что конечно вряд ли, можно качнуть тут: yadi.sk/d/-PGx1pEBf_O6kw
Сейчас довёл его до уже нормально исполняющего простые инструкции ассемблера, так вот такой код на C++:

    m.parseStart();
    int line = 0;
    m.parseLine( line++, "start R0 = $FFFF" ); // в R0 грузим константу $FFFF
    m.parseLine( line++, " R1 = $CCCC" ); // в R1 грузим константу $CCCC
    m.parseLine( line++, " R0 -= R1" ); // из R0 вычитаем R1 и заносим результат в R0
    m.parseLine( line++, " [ first ] = R0" ); // в ячейку памяти по адресу first заносим R0
    m.parseLine( line++, " [ second ] =+1 [ first ]" ); // в ячейку памяти по адресу second заносим инкремент ячейки first
    m.parseLine( line++, " R0 = R0" ); // NOP и ноль - эмулятор останавливается на команде NOP
    m.parseLine( line++, "first R0 = R0" ); // метка first ячейки с данными 0
    m.parseLine( line++, "second R0 = R0" ); // метка second ячейки с данными тоже 0 (DW пока не делал)
    m.parseEnd();

    m.show();

    while ( m.mem[ m.reg[ REG_PC ] ] != 0 )  // nop as stop
      m.step();
    m.show();

генерирует и исполняет следующий очищенный от C++ код на ассемблере Simpleton 3.x:

start  R0         =   $FFFF      // в R0 грузим константу $FFFF
       R1         =   $CCCC      // в R1 грузим константу $CCCC
       R0         -=  R1         // из R0 вычитаем R1 и заносим результат в R0
       [ first ]  =   R0         // в ячейку памяти по адресу first заносим R0
       [ second ] =+1 [ first ]  // в ячейку памяти по адресу second заносим инкремент ячейки first
       R0         =   R0         // NOP и ноль - эмулятор останавливается на команде NOP
first  R0         =   R0         // метка first ячейки с данными 0
second R0         =   R0         // метка second ячейки с данными тоже 0 (DW пока не делал)

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

R0:3333  R1:CCCC  R2:0000  R3:0000  R4:0000  SP:0000  PC:000A  FL:0000
0000:000E  0010:0000  0020:0000  0030:0000  0040:0000  0050:0000  0060:0000  0070:0000
0001:FFFF  0011:0000  0021:0000  0031:0000  0041:0000  0051:0000  0061:0000  0071:0000
0002:001E  0012:0000  0022:0000  0032:0000  0042:0000  0052:0000  0062:0000  0072:0000
0003:CCCC  0013:0000  0023:0000  0033:0000  0043:0000  0053:0000  0063:0000  0073:0000
0004:3801  0014:0000  0024:0000  0034:0000  0044:0000  0054:0000  0064:0000  0074:0000
0005:00F0  0015:0000  0025:0000  0035:0000  0045:0000  0055:0000  0065:0000  0075:0000
0006:000B  0016:0000  0026:0000  0036:0000  0046:0000  0056:0000  0066:0000  0076:0000
0007:10FF  0017:0000  0027:0000  0037:0000  0047:0000  0057:0000  0067:0000  0077:0000
0008:000B  0018:0000  0028:0000  0038:0000  0048:0000  0058:0000  0068:0000  0078:0000
0009:000C  0019:0000  0029:0000  0039:0000  0049:0000  0059:0000  0069:0000  0079:0000
000A:0000  001A:0000  002A:0000  003A:0000  004A:0000  005A:0000  006A:0000  007A:0000
000B:3333  001B:0000  002B:0000  003B:0000  004B:0000  005B:0000  006B:0000  007B:0000
000C:3334  001C:0000  002C:0000  003C:0000  004C:0000  005C:0000  006C:0000  007C:0000
000D:0000  001D:0000  002D:0000  003D:0000  004D:0000  005D:0000  006D:0000  007D:0000
000E:0000  001E:0000  002E:0000  003E:0000  004E:0000  005E:0000  006E:0000  007E:0000
000F:0000  001F:0000  002F:0000  003F:0000  004F:0000  005F:0000  006F:0000  007F:0000

Здесь видно что PC дошёл до 000A и остановился — это где первый искуственный NOP (R0 = R0) — check.
В R0 разница между FFFF и CCCC = 3333 — check.
В R1 — CCCC — check.
По адресу 000B хранится 3333 — это метка first — check.
По следующему адресу — метке second хранится увеличенное на 1 значение в first — 3334 — check!
Можно посмотреть в коды инструкций — адреса (а это между прочим forward reference для которых надо было запоминать адреса которые надо поправить после конца парсинга) 000B и 000C явно видно в ячейках с инструкциями по адресам 0006 и 0008-0009.
Забавное ощущение когда свой ассемблер делаешь виртуальной несуществующей машины. :D
Парсер и генератор кода конечно примитивный — лишь бы откровенных ошибок с подстановкой совсем уж неверных типов лексем не на свои места не было. Например косвенная адресация просто как флаг взводится и сбрасывается при встрече символов [ и ] поэтому такой код будет валидным: [ R0 = R1 ] и эквивалентен [ R0 ] = [ R1 ] (строго говоря валидно и [ R0 = R1
Но тем не менее в мнемониках кодировать весьма удобно становится. :)
Когда еще будет время реализую условия и попробую делать циклы.
  • avatar Anadara
  • 0
Это опечатка. Поправил. Спасибо.
  • avatar Shiru
  • 3
byuu конечно расстроится, узнав, что он так и не смог понять SA-1.

Вообще забавно заявление, что исправлена игра, хотя она просто запущена на более быстром процессоре, да и весь разговор по сути про SA-1. А ведь можно было бы заморочиться и реально оптимизировать код, чтобы игра перестала тормозить без привлечения дополнительного процессора. Во множестве игр на SNES основные тормоза из-за очень своеобразной организации списка спрайтов (биты координат разбросаны). Если писать в лоб, получается множество сдвигов и битовых операций. Помогает держать в памяти список спрайтов в более удобном формате, а блок для OAM формировать один раз в конце кадра развёрнутым циклом. В Gradius не смотрел, но скорее всего эта проблема присутствует и там.
  • avatar aa-dav
  • 0
RISK может в бразилии и так пишется, но у нас — RISC
  • avatar Anadara
  • 4
Я не хардкорный технарь, но старался перевести правильно. Если допущены ошибки, не стесняйтесь указать — я исправлю.
  • avatar FoxyLab
  • 2
Как дополнение:
Автокод, простой язык программирования; система команд некоторой условной машины, способной в качестве элементарных выполнять значительно более сложные операции, чем данная конкретная ЭВМ. Наиболее распространены А. типа 1:1, в которых основной элемент языка (оператор, строка) при переводе на языке цифровой вычислительной машины (ЦВМ) преобразуется в одну команду. С помощью А. типа 1:1 можно составить любую программу, которая возможна в системе команд вычислительной машины. Программирование на А. типа 1:1 эквивалентно программированию на языке ЦВМ, однако более удобно для человека и ускоряет работу примерно в 3 раза. А., отличные от А. типа 1:1, ориентируются не на систему команд ЦВМ, а на класс решаемых задач, значительно ускоряют работу по программированию, но не дают возможности получить программу такого же высокого качества, какое в принципе достижимо при программировании на языке ЦВМ или на А. типа 1:1. В А. (не типа 1:1) основной элемент языка (оператор) при переводе в код ЦВМ преобразуется, как правило, в совокупность нескольких команд. Указать резкую границу между А. и другими (более сложными) языками программирования невозможно. Примерами А. типа 1:1 могут служить А., разработанные в СССР для ЦВМ БЭСМ-6 и «Урал». Пример более сложного А. — А. типа «Инженер» для ЦВМ «Минск».

Алгоритм, заданный на А., перерабатывается в программу ЦВМ с помощью т. н. программы-транслятора, которая может по заданию программиста производить также простейшее распределение памяти, автоматическую компоновку программ из отдельных частей с использованием библиотеки подпрограмм и другие операции.

Во многих системах автоматического программирования А. служит промежуточным языком при переводе с другого языка программирования в код ЦВМ.

В. И. Собельман.

(Your text to link...)
  • avatar aa-dav
  • 2
Кстати, если вспоминать о бейсике в частности и ЯВУ в целом, то для Manchester Mark I/II было разработано несколько ЯВУ с общим названием Autocode: en.wikipedia.org/wiki/Autocode
Но забавным мне показался второй — Mark 1 Autocode, причём он довольно широко использовался, судя по википедии.
Пример программы:

  n1  =  201
  n2  =  301
  v99  =  0
7 v98  =  vn1 x vn2
  v99  =  v99+v98
  n1  =  n1+1
  n2  =  n2+1
  j7  ,  280 >= n1 

Что можно интересного сказать:
— одна операция — одна строка
— 18 целочисленных переменных с именами от n1 до n18
— столько вещественных переменных сколько было доступно прочей памяти с именами вида v1..v999
— оператор j7 переходит на строку пронумерованную как 7, после запятой пишется условие
— если нужно обращаться с ячейками памяти как с массивом, то используется конструкция vnx, например vn10 которая означает переменную v… с номером который хранится в переменной n10
Конечно это было прямо несколько шагов вперёд по сравнению с программирование в символах телетайпа.
  • avatar FoxyLab
  • 2
Замечание об оставлении пустого места между строками много лет спустя повторилось в рекомендации нумеровать строки бейсик-программ числами, кратными 10 — при необходимости можно будет вставить новые строчки. :-)
  • avatar Anadara
  • 1
Статья опубликована: shmupradio.com/ru/r-story
Спасибо за предоставленный материал.
  • avatar aa-dav
  • 0
P.S.
Но если прям интересно, то тут (документация по UNIVAC I от 59 года): www.bitsavers.org/pdf/univac/univac1/UNIVAC1_Programming_1959.pdf
Это страница 16 со слов: «The arithmetic registers are identical to memory cells except...»
  • avatar aa-dav
  • 0
Ну про инженеров — это я вообще ко всему коллективу работавшему над машиной обращался, там всё-таки согласно википедии 300000 человеко-часов было затрачено даже на предыдущую итерацию Mark I (Manchester Baby) у которого было всего 7 машинных команд (практически эзотерическая машина!) из которых арифметико-логические только вычитание и смена знака числа. Но вообще да, мозговой центр там был сплошь из профессоров и кандидатов наук.
  • avatar aa-dav
  • 0
я уже не понимаю зачем там вам нужно что-то перечитывать. что вы собираетесь найти? всё просто так как я констатировал и всё. двойных смыслов в тех фразах нет, это не афоризмы.
  • avatar Raider
  • 1
Поразила связность текста автора на видео. Интересно, он сходу так излагает, или читает? :)
  • avatar Raider
  • 0
Лучше приводить конкретные цитаты, выдержки из текста.
Желательно привести «точные координаты» утверждений, как я просил. Страницу (по нумерации источника), абзац, текст. Связано это с тем что я не могу вычитывать все документы в поиске утверждаемого, весьма лимитировано время...
Назвать Алана Тьюринга британским инженером — это, конечно, пять.

Но если учесть что Тьюринг — один из людей, сформировавший парадигму компьютерных вычислений вообще, я не уверен, что стоит сильно удивляться тому что мышление для современных компьютеров не особенно то и изменилось. Для смены парадигмы нужен ещё один Тьюринг.
Я тоже мало современный прог слушаю, поэтому, возможно, имеет место забавное совпадение :)
  • avatar aa-dav
  • 1
P.S.
Раскопал, что такая странная кодировка на самом деле не странная, а просто повторяет кодировку британского телеграфного кода тех лет — вставил картинку в статью.
Я кстати тоже подумал про LTE, но т.к. я современный прог слушаю мало, подумал что м.б. просто у меня ассоциация по незнанию. Очень круто что ты подумал именно про них же.