Давайте думать над железкой (TRIADOR)

Уравновешенная троичная система счисления - форум переехал с http://ternary.info

Moderator: haqreu

User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

haqreu wrote:Можешь привести сценарий использования OPB?
Ну я там выше писал ведь примеры - MIN, MAX, MSK, CMP и может быть SUM

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

Code: Select all

ORG NNNNNN
; Multiply R1 and R2, store result at R4,R3
; At this point R4,R3 have return address because we jumped here using JPI
; We save them to R12,R11 and also will use R6,R5 to shift 1st argument left
; In the same time we will shift 2nd argument (R7) right until it becomes zero
LMUL:
    ; R5 = R1
    RR -5  ; NNN NNN
    ; R6 = 0
    R1  0  ; NNN NNO
    RR -6  ; NNN NNP
    ; Increment R1 that is zero, so C must be zero after that
    RR  1  ; NNN NON
    ; R12 = R4
    RR  4  ; NNN NOO
    RR -12 ; NNN NOP
    ; R11 = R3
    RR  3  ; NNN NPN
    RR -11 ; NNN NPO
    ; R4,R3 = 0
    R4  0  ; NNN NPP
    R3  0  ; NNN ONN
    ; Transfer R2 to R7 through R1
    RR  2  ; NNN ONO
    RR -7  ; NNN ONP
L1: ;NNN OON - Beginning of the loop
    ; Shift R7 right through C
    EX RRC ; NNN OON
    RR -7  ; NNN OOO
    ; Skip if C==O
    SK  0  ; NNN OOP
    JP  L2 ; NNN OPN
    ; Long jump to the end of the loop (L5)
    R1 NNO ; NNN OPO
    RR -13 ; NNN OPP
    JP  L5 ; NNN PNN
L2: ;NNN PNO - We here because C!=O
    ; Skip if C==N
    SK -1  ; NNN PNO
    JP  L3 ; NNN PNP
    ; Long jump to negative case (L4)
    R1 NNO ; NNN PON
    RR -13 ; NNN POO
    JP  L4 ; NNN POP
L3: ;NNN PPN - We here becauae C==P
    ; R3 += R5
    RR  5  ; NNN PPN
    RR -2  ; NNN PPO
    RR  3  ; NNN PPP
    EX ADD ; NNO NNN
    RR -3  ; NNO NNO
    ; R4 += R6 with C
    RR  6  ; NNO NNP
    RR -2  ; NNO NON
    RR  4  ; NNO NOO
    EX ADC ; NNO NOP
    RR -4  ; NNO NPN
    ; Jump to the end of the loop (L5)
    JP  L5 ; NNO NPO
L4: ;NNO NPP - We here because C==N
    ; R3 -= R5
    RR  5  ; NNO NPP
    RR -2  ; NNO ONN
    RR  3  ; NNO ONO
    EX SUB ; NNO ONP
    RR -3  ; NNO OON
    ; R4 -= R6 with C
    RR  6  ; NNO OOO
    RR -2  ; NNO OOP
    RR  4  ; NNO OPN
    EX SBC ; NNO OPO
    RR -4  ; NNO OPP
L5: ;NNO PNN - End of the loop
    ; Shift R6,R5 left (here C must be zero)
    RR  5  ; NNO PNN
    EX RLC ; NNO PNO
    RR -5  ; NNO PNP
    RR  6  ; NNO PON
    EX RLC ; NNO POO
    RR -6  ; NNO POP
    ; Do nothing
    OP NOP ; NNO PPN
    ; Check if R7 is zero
    RR  7  ; NNO PPO
    ; Skip if R1!=0
    SK -3  ; NNO PPP
    JP  L6 ; NNP NNN
    ; Increment R1 that is Oxx already, so C must be zero after that
    RR  1  ; NNP NNO
    ; Long jump to the beginning of the loop (L1)
    R1 NNN ; NNP NNP
    RR -13 ; NNP NON
    JP  L1 ; NNP NOO
L6: ;NNP NOP - We are here because R7 is zero - RETURN
    RR  12 ; NNP NOP
    RR -13 ; NNP NPN
    RR  11 ; NNP NPO
    RR -2  ; NNP NPP
    EX JPI ; NNP ONN
Тут кроме JPI ещё используются RRC, RLC, ADD, ADC, SUB, SBC и оно уже занимает 2 с половиной страницы - если городить анализаторы переноса и инверсию+сложение вместо вычитания, то будет ещё длиннее...

P.S. Для первоначального RLC/RRC пришлось обнулять флаг C таким образом:
R1 0 ; R1=0
RR 1 ; R1++ (C=O)
поэтому отдельная команда обнуления переноса CLC не помешала бы ( и её кстати можно изобразить из супер-пупер программируемой пермутации, что я изобрёл на предыдущей странице как собственно и RLC/RRC : )

P.P.S. Анализатор наличия переноса/заёма на самом деле относительно простой - для сложения:
SK 0 ; skip if C==O
RR 1 ; R1++
и для вычитания:
SK 0 ; skip if C==O
RR -1 ; R1--
так что возможно ADC и SBC действительно ненужны

P.P.P.S. По поводу ненужности SUB - по идее таки да, чтобы изобразить R2-R1 надо лишь OP PON сделать перед сложением - вот вариант где кроме JPI есть только RLC,RRC и ADD, и он только на 6 инструкций длиннее:

Code: Select all

ORG NNNNNN
; Multiply R1 and R2, store result at R4,R3
; At this point R4,R3 have return address because we jumped here using JPI
; We save them to R12,R11 and also will use R6,R5 to shift 1st argument left
; In the same time we will shift 2nd argument (R7) right until it becomes zero
LMUL:
    ; R5 = R1
    RR -5  ; NNN NNN
    ; R6 = 0
    R1  0  ; NNN NNO
    RR -6  ; NNN NNP
    ; Increment R1 that is zero, so C must be zero after that
    RR  1  ; NNN NON
    ; R12 = R4
    RR  4  ; NNN NOO
    RR -12 ; NNN NOP
    ; R11 = R3
    RR  3  ; NNN NPN
    RR -11 ; NNN NPO
    ; R4,R3 = 0
    R4  0  ; NNN NPP
    R3  0  ; NNN ONN
    ; Transfer R2 to R7 through R1
    RR  2  ; NNN ONO
    RR -7  ; NNN ONP
L1: ;NNN OON - Beginning of the loop
    ; Shift R7 right through C
    EX RRC ; NNN OON
    RR -7  ; NNN OOO
    ; Skip if C==O
    SK  0  ; NNN OOP
    JP  L2 ; NNN OPN
    ; Long jump to the end of the loop (L5)
    R1 NNO ; NNN OPO
    RR -13 ; NNN OPP
    JP  L5 ; NNN PNN
L2: ;NNN PNO - We here because C!=O
    ; Skip if C==N
    SK -1  ; NNN PNO
    JP  L3 ; NNN PNP
    ; Long jump to negative case (L4)
    R1 NNO ; NNN PON
    RR -13 ; NNN POO
    JP  L4 ; NNN POP
L3: ;NNN PPN - We here becauae C==P
    ; R3 += R5
    RR  5  ; NNN PPN
    RR -2  ; NNN PPO
    RR  3  ; NNN PPP
    EX ADD ; NNO NNN
    RR -3  ; NNO NNO
    ; R4 += R6 with C
    RR  6  ; NNO NNP
    RR -2  ; NNO NON
    RR  4  ; NNO NOO
    SK  0  ; NNO NOP
    RR  1  ; NNO NPN
    EX ADD ; NNO NPO
    RR -4  ; NNO NPP
    ; Jump to the end of the loop (L5)
    JP  L5 ; NNO ONN
L4: ;NNO ONO - We here because C==N
    ; R3 -= R5
    RR  3  ; NNO ONO
    RR -2  ; NNO ONP
    RR  5  ; NNO OON
    OP PON ; NNO OOO
    EX ADD ; NNO OOP
    RR -3  ; NNO OPN
    ; R4 -= R6 with C
    RR  4  ; NNO OPO
    RR -2  ; NNO OPP
    RR  6  ; NNO PNN
    OP PON ; NNO PNO
    SK  0  ; NNO PNP
    RR -1  ; NNO PON
    EX ADD ; NNO POO
    RR -4  ; NNO POP
L5: ;NNO PPN - End of the loop
    ; Shift R6,R5 left (here C must be zero)
    RR  5  ; NNO PPN
    EX RLC ; NNO PPO
    RR -5  ; NNO PPP
    RR  6  ; NNP NNN
    EX RLC ; NNP NNO
    RR -6  ; NNP NNP
    ; Do nothing
    OP NOP ; NNP NON
    ; Check if R7 is zero
    RR  7  ; NNP NOO
    ; Skip if R1!=0
    SK -3  ; NNP NOP
    JP  L6 ; NNP NPN
    ; Increment R1 that is Oxx already, so C must be zero after that
    RR  1  ; NNP NPO
    ; Long jump to the beginning of the loop (L1)
    R1 NNN ; NNP NPP
    RR -13 ; NNP ONN
    JP  L1 ; NNP ONO
L6: ;NNP ONP - We are here because R7 is zero - RETURN
    RR  12 ; NNP ONP
    RR -13 ; NNP OON
    RR  11 ; NNP OOO
    RR -2  ; NNP OOP
    EX JPI ; NNP OPN
Я тут за главного - если что шлите мыло на me собака shaos точка net
haqreu
Maniac
Posts: 318
Joined: 10 Mar 2017 05:30

Re: Давайте думать над железкой (TRIADOR)

Post by haqreu »

это что за модный листинг такой? чем его интерпретируешь?
User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

haqreu wrote:это что за модный листинг такой? чем его интерпретируешь?
пока только головой :mrgreen:

получается, что я таки согласился с вами со всеми, что один единственный ADD может быть вполне самодостаточен чтобы покрыть все сложения и вычитания, но вот без RLC и RRC не обойтись никак (ну и до кучи CLC можно добавить):

NNNNN - EX -13 -> ADD (C,R1=R1+R2) <<<<< единственный железобетонный ADD (а нужен ли он?)
NNNNO - EX -12 -> CUSTOM CIRCUIT -12
NNNNP - EX -11 -> CUSTOM CIRCUIT -11
NNNON - EX -10 -> PMT-10 (programmable by PEX)
NNNOO - EX -9 -> PMT-9 (programmable by PEX)
NNNOP - EX -8 -> PMT-8 (programmable by PEX)
NNNPN - EX -7 -> RLC (could be implemented as hardwired PMT)
NNNPO - EX -6 -> CLC (could be implemented as hardwired PMT)
NNNPP - EX -5 -> RRC (could be implemented as hardwired PMT)
NNONN - EX -4 -> RMH (read higher triad from memory [27*R4+R3] to R1)
NNONO - EX -3 -> WMM (write R2,R1 to memory [27*R4+R3])
NNONP - EX -2 -> RML (read lower triad from memory [27*R4+R3] to R1)
NNOON - EX -1 -> JPI (store current PC+1 to R4,R3 and jump to R13,R2)
NNOOO - EX 0 -> PEX (program OPB instances below and PMT instances above)
NNOOP - EX +1 -> OPB №1 (R1=R1 o R2) - programmable by PEX or hardwired MSK?
NNOPN - EX +2 -> OPB №2 (R1=R1 o R2) - programmable by PEX or hardwired MAX?
NNOPO - EX +3 -> OPB №3 (R1=R1 o R2) - programmable by PEX or hardwired MIN?
NNOPP - EX +4 -> OPB №4 (R1=R1 o R2) - programmable by PEX or hardwired CMP?
NNPNN - EX +5 -> OPB №5 (R1=R1 o R2) - programmable by PEX or hardwired SUM?
NNPNO - EX +6 -> OPB №6 (R1=R1 o R2) - programmable by PEX or hardwired OVF?
NNPNP - EX +7 -> OPB №7 (R1=R1 o R2 where o is programmable by PEX or manually)
NNPON - EX +8 -> OPB №8 (R1=R1 o R2 where o is programmable by PEX or manually)
NNPOO - EX +9 -> OPB №9 (R1=R1 o R2 where o is programmable by PEX or manually)
NNPOP - EX +10 -> CUSTOM CIRCUIT +10 (programmable by PEX?)
NNPPN - EX +11 -> CUSTOM CIRCUIT +11
NNPPO - EX +12 -> CUSTOM CIRCUIT +12
NNPPP - EX +13 -> HLT ( halt and catch fire ; )

P.S. Вариант без обязательного ADD и с переносом всех "программируемых" команд и пользовательских схем вверх для логичности:

NNNNN - EX -13 -> HLT ( halt and catch fire ; ) <<<<<<< перенесено по просьбе haqreu
NNNNO - EX -12 -> CUSTOM CIRCUIT C (read any registers, writes R1 and C)
NNNNP - EX -11 -> CUSTOM CIRCUIT B (read any registers, writes R1 and C)
NNNON - EX -10 -> CUSTOM CIRCUIT A (read any registers, writes R1 and C) <<<< например это может быть ADD (C,R1=R1+R2)

NNNOO - EX -9 -> PMT-9 (programmable by PEX)
NNNOP - EX -8 -> PMT-8 (programmable by PEX)
NNNPN - EX -7 -> PMT-7 (programmable by PEX)

NNNPO - EX -6 -> OPB-6 (R1 = R1 o R2) - programmable by PEX
NNNPP - EX -5 -> OPB-5 (R1 = R1 o R2) - programmable by PEX
NNONN - EX -4 -> OPB-4 (R1 = R1 o R2) - programmable by PEX
NNONO - EX -3 -> OPB-3 (R1 = R1 o R2) - programmable by PEX
NNONP - EX -2 -> OPB-2 (R1 = R1 o R2) - programmable by PEX
NNOON - EX -1 -> OPB-1 (R1 = R1 o R2) - programmable by PEX

NNOOO - EX 0 -> PEX (program customizable EX instructions above using R1,R2,R3,R4)
NNOOP - EX +1 -> CMP (hardwired OPB)
NNOPN - EX +2 -> MIN (hardwired OPB)
NNOPO - EX +3 -> MAX (hardwired OPB)
NNOPP - EX +4 -> MUL (hardwired OPB) <<< это то что я раньше MSK называл - у людей это MUL
NNPNN - EX +5 -> SUM (hardwired OPB)
NNPNO - EX +6 -> CON (hardwired OPB) <<< консенсус (бывший OVF - для генерации трита переноса при суммировании)

NNPNP - EX +7 -> CLC (hardwired PMT) <<< или очистка флага C слишком простая команда, чтобы под неё целый PMT отводить?
NNPON - EX +8 -> RLC (hardwired PMT)
NNPOO - EX +9 -> RRC (hardwired PMT)

NNPOP - EX +10 -> WMM (write R2,R1 to memory [27*R4+R3])
NNPPN - EX +11 -> RML (read lower triad from memory [27*R4+R3] to R1)
NNPPO - EX +12 -> RMH (read higher triad from memory [27*R4+R3] to R1)

NNPPP - EX +13 -> JPI (store current PC+1 to R12,R11 and jump to R13,R1) <<<< сохранять в R12,R11 и прыгать на R13,R1 вроде логичнее?

PEX может программировать любые команды вверх и у каждой будет 9-тритовый регистр, который может быть использован внутри схемы.
При попытке запрограммировать команды вниз PEX приведёт систему в режим Halt (либо ничего не произойдёт - надо подумать).
Часть регистров PEX (а то может быть и все 13) можно использовать для вывода - например на светодиодный дисплейчик:

Image

(Автор гифки - JeNNeR)
Я тут за главного - если что шлите мыло на me собака shaos точка net
haqreu
Maniac
Posts: 318
Joined: 10 Mar 2017 05:30

Re: Давайте думать над железкой (TRIADOR)

Post by haqreu »

тупые вопросы:
1) что такое триада?
2) что такое rotate through C?
User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

haqreu wrote:тупые вопросы:
1) что такое триада?
2) что такое rotate through C?
1) триада это 3 трита

2) если имеем R1=XYZ и C
то после выполнения RLC получили бы C=X R1=YZC
а после выполнения RRC получим R1=CXY C=Z
т.е. вращаем по кольцу в котором 4 элемента - три трита регистра R1 и флаг C
Я тут за главного - если что шлите мыло на me собака shaos точка net
haqreu
Maniac
Posts: 318
Joined: 10 Mar 2017 05:30

Re: Давайте думать над железкой (TRIADOR)

Post by haqreu »

Ага, понял. Зачем вращать налево - понимаю, это умножение на 3. Зачем вращать направо?
User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

haqreu wrote:Ага, понял. Зачем вращать налево - понимаю, это умножение на 3. Зачем вращать направо?
деление на 3 :)
но в данном конкретном случае просто очередной трит выталкивается во флаг C и далее мы на него глядя либо прибавляем сдвинутое налево (при C=P), либо вычитаем сдвинутое налево (при C=N) либо идём на следующий цикл (при C=O)

P.S. А вот интересно можно ли ADD реализовать с помощью OPB? Скажем запрограммированный как SUM бинарный оператор сложит триты и далее надо понять были ли переносы:

N+N=P --> N
N+O=N
N+P=O
O+N=N
O+O=O
O+P=P
P+N=O
P+O=P
P+P=N --> P

Выходит чтобы переносы узреть нужен OPB=NOOOOOOOP и далее корректируем:

Code: Select all

; R3 + R4 => R5
 RR 4
 RR -2
 RR 3
L1:
 EX SUM ; OPB=PNONOPOPN
 RR -5
 RR 3
 EX OVF ; OPB=NOOOOOOOP
 SK 3 ; Skip if R1==0
 JP L0
 EX CLC
 EX RLC
 RR -2
 RR 5
 RR -3
 JP L1
L0:
скажем PPP+OOP
SUM даст PPN
OVF даст OOP
сдвигаем влево - OPO
складываем снова потритно
SUM даст PNN
OVF даст OPO
сдвигаем влево - POO
складываем снова потритно
SUM даст NNN
OVF даст POO
сдвигаем влево - OOO (и C=P)
алгоритм пойдет на сложение и получит все тот же NNN и выскочит т.к. OVF вернет 0

получается без ADD тоже можно обойтись :mrgreen:

тут в худшем случае будет 3 прохода (как в вышеописанном примере), а в лучшем - только 1 (когда переносов не выявится на первом же шаге)

ну что - делаем триадор без сумматора? :lol:
Я тут за главного - если что шлите мыло на me собака shaos точка net
haqreu
Maniac
Posts: 318
Joined: 10 Mar 2017 05:30

Re: Давайте думать над железкой (TRIADOR)

Post by haqreu »

ладно, лишнюю болтовню я удаляю, согласен с тем, что вращение хорошо, из него сделать деление несложно.
User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

Shaos wrote:Кстати добавь виртуальный метод в класс Triador, чтобы внешние обработчики EX можно было цеплять - вот и попробуем :rotate:
Типа

Code: Select all

virtual bool doEX(int arg)
{
  return false; // not handled - halt
}
P.S. Я могу сам добавить и тебе заслать пул-реквест :mrgreen:

P.P.S. Да и OP надо бы к общему знаменателю привести viewtopic.php?p=154508#p154508
заслал пулл-реквест :mrgreen:

https://github.com/ssloy/triador/pull/2

там 2 коммита - фикс OP и виртуальный метод для внешней обработки EX, чтобы можно было кастомно расширять не трогая исходники триадора

P.S. уже 4 коммита - коммент поправил в обработчике EX и переименовал виртуальный метод в do_ex чтобы стилю соответстовал :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
haqreu
Maniac
Posts: 318
Joined: 10 Mar 2017 05:30

Re: Давайте думать над железкой (TRIADOR)

Post by haqreu »

Смерджил ; я помимо прочего исправил формат программ и перемешал скипы (если не забыл). Актуальное описание архитектуры тут и тут

Текущий вариант сложения выглядит следующим образом:

Code: Select all

R2   2 # write  2 to R2                                               ┌─────────────────────────────────┐
R3  13 # write 13 to R3           ┌─────────────────────────────────┐ │ int C, R1, R2=2, R3=13, R4=0;   │
R4   0 # write  0 to R4           │ This program computes R2+R3,    │ │ void hardware_overflow() {      │
R1 -13 #                          │ the result is stored as R3+R4*27│ │     C = R1>13?1:(R1<-13?-1:0);  │
RR -13 # choose segment NNN       │ Side effects: R2, R1 and C      │ │     if (R1> 13) R1 -= 27;       │
RR   3 # copy R3 to R1 <─────┐    │ are destroyed.                  │ │     if (R1<-13) R1 += 27;       │
SK  -6 # skip if R2!=0       │    │                                 │ │ }                               │
JP  13 # break the loop ─────│─┐  │ Here is a C++ world equavalent ──>│ int main() {                    │
SK   7 # skip if R2>0        │ │  └─────────────────────────────────┘ │     while (R2!=0) {             │
RR  -1 # R1--                │ │                                      │         R1=R3;                  │
SK   5 # skip if R2<0        │ │                                      │         if (R2>0) R1++;         │
RR   1 # R1++                │ │                                      │         if (R2<0) R1--;         │
RR  -3 # copy R1 to R3       │ │                                      │         hardware_overflow();    │
SK   0 # skip if C==0        │ │                                      │         R3 = R1;                │
JP   3 # overflow ───────┐   │ │                                      │         if (C) {                │
JP   6 # no overflow ────│─┐ │ │                                      │             R4 = 1;             │
R4   1 # write 1 to R4 <─┘ │ │ │                                      │             if (C==-1) R4 = -1; │
SK   1 # skip if C==1      │ │ │                                      │         }                       │
R4  -1 # write -1 to R4    │ │ │                                      │         R1 = R2;                │
RR   2 # copy R2 to R1 <───┘ │ │                                      │         if (R2>0) R1--;         │
SK   7 # skip if R2>0        │ │                                      │         if (R2<0) R1++;         │
RR   1 # R1++                │ │                                      │         hardware_overflow();    │
SK   5 # skip if R2<0        │ │                                      │         R2 = R1;                │
RR  -1 # R1--                │ │                                      │     }                           │
RR  -2 # copy R1 to R2       │ │                                      │     return R3+27*R4;            │
JP  -8 # main loop ──────────┘ │                                      │ }                               │
EX   0 # halt and catch fire <─┘                                      └─────────────────────────────────┘
Там в итоге побились программы, как найду время, почищу всё.
User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

Прицепил обновлённые доки на первой странице этого топика и обновил список скипов там же

На досуге попробую реализовать последний вариант EX-таблицы что выше и постараюсь написать программу умножения без ADD :mrgreen:

P.S. Halt and catch fire вроде бы у тебя был EX 13?

P.P.S. Думаю про "вумный" ассемблер, который будет псевдоинструкцию JMP label превращать либо в JP x (если передача управления происходит в пределах страницы и R13 не поменялся) либо в

R1 y
RR -13
JP x

(если метка лежит за пределами страницы или R13 больше не совпадает с номером сегмента куда идёт переход)

Плюс макросы поддержать, например для того же CLC можно иметь:

Code: Select all

CLC MACRO 
   R1 0
   RR 1
ENDM
И видимо надо этот ассемблер научить отслеживать где будет неявная порча регистра R1 внутри макроса и попытка его использовать после макроса чтобы выдавать ошибку.
R13 тоже придётся отслеживать чтобы корректно JMP компилировать в одну либо 3 инструкции?
Ну или просто сделать макрос JMP для дальних прыжков и пусть программист сам следит за своими адресами и содержимым R13:

Code: Select all

JMP MACRO L
    R1 SEG L
    RR -13
    JP OFF L
ENDM
Этот ассемблер может выдавать листинг файлы, пригодные для скармливания в эмулятор триадора (адреса будут укзаны в каждой строке как комментарии), а также бинарные файлы 2К-образа ПЗУ для моего логисимовского симулятора триадора[/b]

 TRIADOR2.INC

Code: Select all

; TRIADOR-2 definitions for assembler TRIADORA
; Created by Alexander A. Shabarshin <me@shaos.net>

NNN EQU -13
NNO EQU -12
NNP EQU -11
NON EQU -10
NOO EQU -9
NOP EQU -8
NPN EQU -7
NPO EQU -6
NPP EQU -5
ONN EQU -4
ONO EQU -3
ONP EQU -2
OON EQU -1
OOO EQU  0
OOP EQU  1
OPN EQU  2
OPO EQU  3
OPP EQU  4
PNN EQU  5
PNO EQU  6
PNP EQU  7
PON EQU  8
POO EQU  9
POP EQU  10
PPN EQU  11
PPO EQU  12
PPP EQU  13

; >>>>> SKIP MACROS

IF_R4LE0  EQU -13
IF_R4NE0  EQU -12
IF_R4GE0  EQU -11
IF_R3LE0  EQU -10
IF_R3NE0  EQU -9
IF_R3GE0  EQU -8
IF_R2LE0  EQU -7
IF_R2NE0  EQU -6
IF_R2GE0  EQU -5
IF_R1LE0  EQU -4
IF_R1NE0  EQU -3
IF_R1GE0  EQU -2
IF_BORROW EQU -1
IF_NOOVER EQU  0
IF_CARRY  EQU  1
IF_R1LT0  EQU  2
IF_R1EQ0  EQU  3
IF_R1GT0  EQU  4
IF_R2LT0  EQU  5
IF_R2EQ0  EQU  6
IF_R2GT0  EQU  7
IF_R3LT0  EQU  8
IF_R3EQ0  EQU  9
IF_R3GT0  EQU  10
IF_R4LT0  EQU  11
IF_R4EQ0  EQU  12
IF_R4GT0  EQU  13

; Long jump to label L
JMP MACRO L
    R1 SEG L
    RR -13
    JP OFF L
ENDM

; Refresh R13 with current segment identifier
RFR MACRO
    LOCAL L
    R1 SEG L
L:  RR -13
ENDM

; Clear flag C
CLC MACRO
    R1 0
    RR 1
ENDM

; Decrement R1 with updating flag C
DEC MACRO
    RR -1
ENDM

; No operations
NOP MACRO
    RR  0
ENDM

; Increment R1 with updating flag C
INC MACRO
    RR  1
ENDM

; >>>>> EXTENDED INSTRUCTIONS

; Program EX using R1,R2,R3 and R4 as identifier of EX command to program
PEX MACRO
    EX 0
ENDM

; Indirect jump to R13,R1 with storing PC+1 to R12,R11
JPI MACRO
    EX 1
ENDM

; >>>>> DATA MEMORY ACCESS

; Read data memory from address R4,R3 and store lower triade to R1
RML MACRO
    EX 2
ENDM

; Write R2,R1 to data memory address R4,R3
WMM MACRO
    EX 3
ENDM

; Read data memory from address R4,R3 and store higher triade to R1
RMH MACRO
    EX 4
ENDM

; Read data memory from address A and store value to R2,R1
RMA MACRO A
    R1 SEG A
    RR -4
    R1 OFF A
    RR -3
    EX 4
    RR -2
    EX 2
ENDM

; Write R2,R1 to data memory address A
WMA MACRO A
    R1 SEG A
    RR -4
    R1 OFF A
    RR -3
    EX 3
ENDM

; Write constant C to data memory address A
WMC MACRO A,C
    R1 SEG A
    RR -4
    R1 OFF A
    RR -3
    R1 SEG C
    RR -2
    R1 OFF C
    EX 3
ENDM

; >>>>> BINARY TRITWISE OPERATIONS

MIN MACRO
    EX 5
ENDM

MSK MACRO
    EX 6
ENDM

MAX MACRO
    EX 7
ENDM

SUM MACRO
    EX 8
ENDM

OVF MACRO
    EX 9
ENDM

CMP MACRO
    EX 10
ENDM

; >>>>> PREDEFINED PERMUTATIONS

RLC MACRO
    EX 11
ENDM

RRC MACRO
    EX 12
ENDM

; >>>>> HALT AND CATCH FIRE

HLT MACRO
    EX 13
ENDM

; >>>>> SUBROUTINES MACROS (SP=R10,R9)

; subroutine is called by CALL label

; if subrouting is not calling anything else then it can just do RET at the end

; if subrouting is calling something else (including itself) while working
; then it should do PUSH in the beginning to store current R12,R11 on the stack
; and it should do RETURN at the end to return to proper address from the stack

; to store pair of registers on the stack use PUSHRR and POPRR

CALL MACRO A
    R1 SEG A
    RR -13
    R1 OFF A
    EX 1
ENDM

RET MACRO
    RR 12
    RR -13
    RR 11
    EX 1
ENDM

SP  MACRO A
    R1 SEG A
    RR -10
    R1 OFF A
    RR -9
ENDM

PUSH MACRO
    RR 10
    RR -4
    RR 9
    RR -3
    RR 12
    RR -2
    RR 11
    EX 3
    RR 9
    RR -1
    RR -9
    RR 10
    SK 0
    RR -1
    RR -10
ENDM

RETURN MACRO
    RR 9
    RR 1
    RR -9
    RR -3
    RR 10
    SK 0
    RR 1
    RR -10
    RR -4
    EX 4
    RR -13
    EX 2
    EX 1
ENDM

PUSHRR MACRO H,L
    RR 10
    RR -4
    RR 9
    RR -3
    RR H
    RR -2
    RR L
    EX 3
    RR 9
    RR -1
    RR -9
    RR 10
    SK 0
    RR -1
    RR -10
ENDM

POPRR MACRO H,L
    RR 9
    RR 1
    RR -9
    RR -3
    RR 10
    SK 0
    RR 1
    RR -10
    RR -4
    EX 4
    RR -H
    EX 2
;    IF L NE 1
    RR -L
;    ENDIF
ENDM

чего-то пуши с попами тяжеловастые получаются - в половину сегмента длиной - наверное надо подумать про микрокодовые CALL и RET внутри кастомных EX-команд или у нас типа RISC?...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

Shaos wrote:Про то как расширять память я писал ещё в ноябре 2017 года:
Shaos wrote:Далее - для калькулятора нужна память для временного хранения чисел (т.к. большинство регистров задействованы под отображение). Идея следующая - наше 2К ПЗУ программ покрывает области Oxxxxx и Pxxxxx, а в область Nxxxxx мы втыкаем статическое ОЗУ! В EX вставляем пару команд - записать в память и прочитать из памяти (адрес будет браться из регистров, скажем из R3 и R4). Можно будет записывать как триады, так и слова - чтобы потом на ОЗУ можно было передать управление и запустить введённую юзером программу!
т.е. я предполагал, что ПЗУ будет двоичным с тупым отображением троичного адреса в двоичный диапазон адресов 2К, а вот ОЗУ может быть троичным и к нему можно будет получать доступ программно, записывая и читая данные, а также загружая туда подпрограммы извне, а потом можно пойти ещё дальше и сделать банки памяти, листая это самое ОЗУ (да и двоичное ПЗУ тоже можно листать). Вот тогда у нас и будет универсальный компьютер, который будет способен подгружать с внешних носителей и исполнять программы, написанные пользователем на этом же самом компьютере...
Адреса Oxxxxx отображаются на первый килобайт ПЗУ, а Pxxxxx - на второй, вот его как раз и можно листать, скажем записывая 2 триады по адресу PPP PPP через EX - получается мы можем листать 729 страниц по 243 ячеек каждая или 177147 ячеек всего (плюс нелистаемые 243 ячейки в области Oxxxxx где может сидеть BIOS) - тетрис думаю в такое страничное ПЗУ должен влезть :mrgreen:
Nxxxxx как и написано выше может являться частью ОЗУ, которое доступно для записи и чтения через EX (т.е. верхние 243 слова ОЗУ будут отображаться в память программ для возможной загрузки и запуска пользовательского кода) - ОЗУ также можно будет частично заставить листаться, если 729 слов окажется мало...
Я тут за главного - если что шлите мыло на me собака shaos точка net
haqreu
Maniac
Posts: 318
Joined: 10 Mar 2017 05:30

Re: Давайте думать над железкой (TRIADOR)

Post by haqreu »

Да что ж ты так торопишься с расширением-то! HCF я хочу в EX -13, этой команде нельзя не дать красивый номер NN NNN.
User avatar
Shaos
Admin
Posts: 24079
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Давайте думать над железкой (TRIADOR)

Post by Shaos »

haqreu wrote:Да что ж ты так торопишься с расширением-то! HCF я хочу в EX -13, этой команде нельзя не дать красивый номер NN NNN.
ок, а то ты было её в EX 0 сдвинул в последнем варианте :)

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

P.S. я там на первой странице примерно разбил архитектуру на "поколения":
Shaos wrote: TRIADOR-0 : 4 регистра без EX-инструкций и с 3-тритной шиной адреса
TRIADOR-1 : 13 регистров без EX-инструкций и с 6-тритной шиной адреса (R13 используется при передаче управления)
TRIADOR-2 : 13 регистров с 6-тритной шиной адреса и некоторым набором EX-инструкций (программируемых переключателями)
TRIADOR-3 : 13 регистров с 6-тритной шиной адреса и полным набором EX-инструкций (программируемых программно) и дополнительной памятью данных с 6-тритным адресом...
я пытаюсь 3-е поколение продумать (и просимулировать) в том объёме, чтобы можно было реальный чип троичного микроконтроллера (с внешней памятью) сделать :)
Shaos wrote:Вариант без обязательного ADD и с переносом всех "программируемых" команд и пользовательских схем вверх для логичности:

NNNNN - EX -13 -> HLT ( halt and catch fire ; ) <<<<<<< перенесено по просьбе haqreu
NNNNO - EX -12 -> CUSTOM CIRCUIT C (read any registers, writes R1 and C)
NNNNP - EX -11 -> CUSTOM CIRCUIT B (read any registers, writes R1 and C)
NNNON - EX -10 -> CUSTOM CIRCUIT A (read any registers, writes R1 and C) <<<< например это может быть ADD (C,R1=R1+R2)

NNNOO - EX -9 -> PMT-9 (programmable by PEX)
NNNOP - EX -8 -> PMT-8 (programmable by PEX)
NNNPN - EX -7 -> PMT-7 (programmable by PEX)

NNNPO - EX -6 -> OPB-6 (R1 = R1 o R2) - programmable by PEX
NNNPP - EX -5 -> OPB-5 (R1 = R1 o R2) - programmable by PEX
NNONN - EX -4 -> OPB-4 (R1 = R1 o R2) - programmable by PEX
NNONO - EX -3 -> OPB-3 (R1 = R1 o R2) - programmable by PEX
NNONP - EX -2 -> OPB-2 (R1 = R1 o R2) - programmable by PEX
NNOON - EX -1 -> OPB-1 (R1 = R1 o R2) - programmable by PEX

NNOOO - EX 0 -> PEX (program customizable EX instructions above using R1,R2,R3,R4)
NNOOP - EX +1 -> CMP (hardwired OPB)
NNOPN - EX +2 -> MIN (hardwired OPB)
NNOPO - EX +3 -> MAX (hardwired OPB)
NNOPP - EX +4 -> MUL (hardwired OPB) <<< это то что я раньше MSK называл - у людей это MUL
NNPNN - EX +5 -> SUM (hardwired OPB)
NNPNO - EX +6 -> CON (hardwired OPB) <<< консенсус (бывший OVF - для генерации трита переноса при суммировании)

NNPNP - EX +7 -> CLC (hardwired PMT) <<< или очистка флага C слишком простая команда, чтобы под неё целый PMT отводить?
NNPON - EX +8 -> RLC (hardwired PMT)
NNPOO - EX +9 -> RRC (hardwired PMT)

NNPOP - EX +10 -> WMM (write R2,R1 to memory [27*R4+R3])
NNPPN - EX +11 -> RML (read lower triad from memory [27*R4+R3] to R1)
NNPPO - EX +12 -> RMH (read higher triad from memory [27*R4+R3] to R1)

NNPPP - EX +13 -> JPI (store current PC+1 to R12,R11 and jump to R13,R1) <<<< сохранять в R12,R11 и прыгать на R13,R1 вроде логичнее?

PEX может программировать любые комманды вверх и у каждой будет 9-тритовый регистр, который может быть использован внутри схемы.
При попытке запрограммировать команды вниз PEX приведёт систему в режим Halt (либо ничего не произойдёт - надо подумать).
Часть регистров PEX можно использовать для вывода - например на светодиодный дисплейчик:

Image

(Автор гифки - JeNNeR)
P.P.S. Может быть PEX при R4=0 заставить программировать границы программируемых OPB / PMT / CUSTOM CIRCUIT ?
Как например
R1 - будет означать начало области PMT (т.е. область OPB будет простираться от -1 до предыдущего индекса - сделав R1=-1 можно запретить OPB вовсе),
R2 - начало области CUSTOM CIRCUITS и
R3 - начало области HLT (при желании можно сделать разные хальты, которые скажем разные лампочки будут зажигать при остановке)
(значения по умолчанию -7, -10 и -13)
Я тут за главного - если что шлите мыло на me собака shaos точка net
haqreu
Maniac
Posts: 318
Joined: 10 Mar 2017 05:30

Re: Давайте думать над железкой (TRIADOR)

Post by haqreu »

где-то на тысячном корпусе микросхем для триадора я всё же запаял один задом наперёд :rotate:
You do not have the required permissions to view the files attached to this post.