Intel8080 на UASM

Тема в разделе "WASM.ASSEMBLER", создана пользователем Intro, 26 дек 2020.

  1. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    Ассемблер UASM начал понимать Intel8080.
    Тестовый код.
    Код (ASM):
    1.  
    2. ;;
    3. include intel8080.asm
    4. .model tiny
    5. .data
    6. foo db 77h
    7. doo db 99h
    8. zoo dw 1234h
    9. .code
    10. org 100h
    11. start:
    12. $NOP
    13. $CALLPO M1
    14. $MOV A,C
    15. $MOV A, [HL];,22
    16. ;; $MOV [HL], [HL]
    17. $ADD A,D
    18. $ADD A, 0FFh
    19. $MOV BC, 01234h
    20. $MOV [DE], A
    21. $MOV A, doo
    22. $MOV foo, A
    23. $MOV HL, zoo
    24. $MOV zoo, HL
    25. $INC A
    26. $INC HL
    27. $INC SP
    28. $DEC A
    29. $DEC HL
    30. $DEC SP
    31. $PUSH AF
    32. $PUSH DE
    33. $POP AF
    34. $POP HL
    35. $ADD HL, DE
    36. $ADD HL, SP
    37. $RST 7
    38. $JNZ M1
    39. $NOP
    40. M1:
    41. $MOV SP, HL
    42. $XCHG HL, DE
    43. $XCHG DE, HL
    44. $XCHG HL, [SP]
    45. $XCHG [SP], HL
    46. $ROL A
    47. $ROR A
    48. $SHL A
    49. $SHR A
    50. db 08h, 10h, 18h, 38h, 0
    51. db 0CBh, 0D9h, 0DDh, 0,0
    52. db 0EDh, 0FDh, 0,1
    53. $RET
    54. $JMP HL
    55. $LET HL:=zoo, A++, DE--, HL+=SP
    56. end start
    57.  
    Просто пример, как UASM может понимать не только х86.
     

    Вложения:

    • intel8080.asm
      Размер файла:
      12,2 КБ
      Просмотров:
      231
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Тебе может ссылок на v86 с манами насыпать сюда я могу.​
     
  3. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    Это просто пример правильного понимания реализации ассемблера вообще. Ассемблер - это, структурный, процедурный, с элементами ООП, язык программирования. И он может быть универсальный как сам Си.
    --- Сообщение объединено, 26 дек 2020 ---
    Правильно реализованный ассемблер может заменить даже С++.
     
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Intro,

    > Ассемблер - это, структурный, процедурный, с элементами ООП, язык программирования.

    Прежде такое тут никто не утверждал. Какое отношение имеет ооп к асм не понятно.
     
  5. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    ООП - Объектно Ориентированное Программирования. И хороший ассемблер может его частично поддерживать. Прежде всего это вызов процедур по ссылке в виртуальной таблице. В UASM реализовано, эээ... Да хреново реализовано. Например, если в OpenGL это просто функции, то в DirectX это уже виртуальные функции COM. И для нормальной работы надо реализовать возможность эффективного вызова функций по ссылке в таблице. Вот и всё. Больше от ассемблера и не надо.
     
  6. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    Где можно найти онлайн ассемблер 8080? С отладчиком и чтобы метки данные поддерживал, пару страниц Яндекс выдал какую-то хрень. То метки данных не понимает, то отладочных команд нет.
     
  7. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.454
    Адрес:
    Россия, Нижний Новгород
    Нет таких, используй локальные ассемблеры и отладчики
     
  8. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    Ладно, вот код на моём ассемблере, решает задачку "Счастливые билеты" оптимизация = 0
    Код (ASM):
    1. ; задача "Счастливые билеты" оптимизация = 0
    2. ; (с) НаноБот    5.11.2023
    3. .model tiny
    4. include ../intel8080.asm    ;Используется мой ассемблер с синтаксисом intel x86
    5. .data
    6. count       dw 0
    7. .code
    8. org 100h
    9. start:
    10.     $MOV    HL, 0
    11.     $MOV    count, HL
    12.     $MOV    H, 10   ;L1
    13. CYCLE1:
    14.     $MOV    L, 10   ;L2
    15. CYCLE2:
    16.     $PUSH   HL
    17.     $MOV    B, 10   ;L3
    18. CYCLE3:
    19.     $MOV    C, 10   ;R1
    20. CYCLE4:
    21.     $MOV    D, 10   ;R2
    22. CYCLE5:
    23.     $MOV    E, 10   ;R3
    24. CYCLE6:
    25.     $LET    A:=H, A+=L, A+=D, H:=A  ;H=L1+L2+L3
    26.     $LET    A:=C, A+=D, A+=E        ;A=R1+R2+R3
    27.     $CMP    A, H
    28.     $JNZ    M1      ;if (H==A)
    29.         $LET    HL:=count, HL++, count:=HL
    30. M1:
    31.     $INC    E
    32.     $JNZ    CYCLE6
    33.     $INC    D
    34.     $JNZ    CYCLE5
    35.     $INC    C
    36.     $JNZ    CYCLE4
    37.     $INC    B
    38.     $JNZ    CYCLE3
    39.     $POP    HL
    40.     $INC    L
    41.     $JNZ    CYCLE2
    42.     $INC    H
    43.     $JNZ    CYCLE1
    44.     $MOV    HL, count
    45.     $CALL   0FB78H  ;печать HL с пробелом //монитор РАДИО-86РК
    46.     $RET
    47. end start
    Проверить пока не получилось, но при 2МГц где-то 30-40 сек должно проработать.
    И да, там в intel8080.asm нашёл ошибку, я её исправил.
     
    Последнее редактирование: 5 ноя 2023
  9. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.454
    Адрес:
    Россия, Нижний Новгород
    Так а ты глянь в виртуалке под досом, на 32х-битной винде (она умеет запускать 16-битные бинарники) или в досбоксе
     
  10. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    HoShiMin, это intel8080 какой ещё досбокс?! По идеи надо на эмуляторе радио-86рк запустить, хотя это медленный БК, партнёр 01.01 быстрей, 2МГц и нет задержек по видеоконтролеру.
     
  11. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.454
    Адрес:
    Россия, Нижний Новгород
    А, он же восьмибитный... Глянул, их ни Qemu, ни Bochs не умеет... Ну тогда да, только искать эмуляторы
     
  12. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    Онлайн эмулятор радиошки.
    https://rk86.ru
    Только почему-то клава не работает.
    --- Сообщение объединено, 5 ноя 2023 ---
    Ошибок полно, вот версия точно должна работать.
    Код (ASM):
    1. ; задача "Счастливые билеты" оптимизация = 0
    2. ; (с) НаноБот    5.11.2023  v0.01
    3. .model tiny
    4. include ../intel8080.asm    ;Используется мой ассемблер с синтаксисом intel x86
    5. .data
    6. count       dw 0
    7. .code
    8. org 100h
    9. start:
    10.     $MOV    HL, 0
    11.     $MOV    count, HL
    12.     $MOV    H, 10   ;L1
    13. CYCLE1:
    14.     $MOV    L, 10   ;L2
    15. CYCLE2:
    16.     $MOV    B, 10   ;L3
    17. CYCLE3:
    18.     $MOV    C, 10   ;R1
    19. CYCLE4:
    20.     $MOV    D, 10   ;R2
    21. CYCLE5:
    22.     $MOV    E, 10   ;R3
    23. CYCLE6:
    24.     $PUSH   HL
    25.     $LET    A:=H, A+=L, A+=D, H:=A  ;H=L1+L2+L3
    26.     $LET    A:=C, A+=D, A+=E        ;A=R1+R2+R3
    27.     $CMP    A, H
    28.     $JNZ    M1      ;if (H==A)
    29.         $LET    HL:=count, HL++, count:=HL
    30. M1:
    31.     $POP    HL
    32.     $DEC    E
    33.     $JNZ    CYCLE6
    34.     $DEC    D
    35.     $JNZ    CYCLE5
    36.     $DEC    C
    37.     $JNZ    CYCLE4
    38.     $DEC    B
    39.     $JNZ    CYCLE3
    40.     $DEC    L
    41.     $JNZ    CYCLE2
    42.     $DEC    H
    43.     $JNZ    CYCLE1
    44.     $MOV    HL, count
    45.     $CALL   0FB78H  ;печать HL с пробелом //монитор РАДИО-86РК
    46.     $RET
    47. end start
    --- Сообщение объединено, 5 ноя 2023 ---
    Код (ASM):
    1. ; задача "Счастливые билеты" оптимизация = 0
    2. ; (с) НаноБот    5.11.2023  v0.02
    3. .model tiny
    4. include ../intel8080.asm    ;Используется мой ассемблер с синтаксисом intel x86
    5. .data
    6. count       dw 0
    7. .code
    8. org 100h
    9. start:
    10.     $MOV    HL, 0
    11.     $MOV    count, HL
    12.     $MOV    H, 10   ;L1
    13. CYCLE1:
    14.     $MOV    L, 10   ;L2
    15. CYCLE2:
    16.     $MOV    B, 10   ;L3
    17. CYCLE3:
    18.     $MOV    C, 10   ;R1
    19. CYCLE4:
    20.     $MOV    D, 10   ;R2
    21. CYCLE5:
    22.     $MOV    E, 10   ;R3
    23. CYCLE6:
    24.     $PUSH   HL
    25.     $LET    A:=H, A+=L, A+=B, H:=A  ;H=L1+L2+L3
    26.     $LET    A:=C, A+=D, A+=E        ;A=R1+R2+R3
    27.     $CMP    A, H
    28.     $JNZ    M1      ;if (H==A)
    29.         $LET    HL:=count, HL++, count:=HL
    30. M1:
    31.     $POP    HL
    32.     $DEC    E
    33.     $JNZ    CYCLE6
    34.     $DEC    D
    35.     $JNZ    CYCLE5
    36.     $DEC    C
    37.     $JNZ    CYCLE4
    38.     $DEC    B
    39.     $JNZ    CYCLE3
    40.     $DEC    L
    41.     $JNZ    CYCLE2
    42.     $DEC    H
    43.     $JNZ    CYCLE1
    44.     $MOV    HL, count
    45.     $CALL   0FB78h  ;печать HL с пробелом //монитор РАДИО-86РК
    46.     $CALL   0F86CH  ;выход в ОС
    47.    
    48. end start
    Заработал код(в 0.01 была ошибка), там эмулятор немного странно работает, но код я запустил. Вернуло D7D4, а проработало 54 сек, ну Партнёр 01.01 побыстрей бы подсчитал, может за 40 сек бы справился.
     
  13. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
    Я бы к A сперва L сложил, а R бы вычитал, так на команду сравнения и перекладок будет меньше.
    Инкремент count тоже тоже сделал бы однобайтовыми LD A,(count): INC A: LD,(count): JNZ skip_high_count_incr: ... тогда push/pop не нужно будет в ядре цикла наматывать, вроде должно стать быстрее.
    В восьмибитках чем восьмибитестее, тем бывает лучше.
     
    Последнее редактирование: 5 ноя 2023
  14. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    aa_dav, count у нас word, т.е. unsigned short. Возможно этот алго можно и быстрей скомпилировать в 8080, но как есть.
    Оптимизация = 1
    Код (ASM):
    1.     $LET    HL:=0, count:=HL, B:=0  ;sum_l
    2.     $LET    HL:=&L1, [HL]:=10
    3.     CYCLE1:
    4.         $LET    HL:=&L2, [HL]:=10
    5.         CYCLE2:
    6.             $LET    HL:=&L3, [HL]:=10
    7.             CYCLE3:
    8.                 $LET    HL:=&R1, [HL]:=10, C:=0 ;sum_r
    9.                 CYCLE4:
    10.                     $MOV    D, 10   ;R2
    11.                     CYCLE5:
    12.                         $MOV    E, 10   ;R3
    13.                         $MOV    A, B
    14.                         CYCLE6:
    15.                             $CMP    A, C
    16.                             $JNZ    M1      ;if (sum_l==sum_r)
    17.                                 $LET    HL:=count, HL++, count:=HL
    18.                             M1:
    19.                             $INC    C
    20.                             $DEC    E
    21.                         $JNZ    CYCLE6
    22.                         $LET    A:=C, A-=9, C:=A
    23.                         $DEC    D
    24.                     $JNZ    CYCLE5
    25.                     $LET    A:=C, A-=9, C:=A
    26.                     $LET    HL:=&R1, [HL]--
    27.                 $JNZ    CYCLE4
    28.                 $LET    B++, HL:=&L3, [HL]--
    29.             $JNZ    CYCLE3
    30.             $LET    A:=B, A-=9, B:=A
    31.             $LET    HL:=&L2, [HL]--
    32.         $JNZ    CYCLE2
    33.         $LET    A:=B, A-=9, B:=A
    34.         $LET    HL:=&L1, [HL]--
    35.     $JNZ    CYCLE1
    36.     $MOV    HL, count
    37.     $CALL   0FB78h  ;печать HL с пробелом //монитор РАДИО-86РК
    38.     $CALL   0F86CH  ;выход в ОС
    Этот код проработал уже 26 секунд, опять немного переделал intel8080.asm
     
  15. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
    В этом и прикол - мы сперва увеличиваем нижний байт пары, и если в результате не получился 0, то пропускаем инкремент верхней пары. Если же получился 0, то значит надо перенести флаг переноса в верхнюю пару и тогда один раз на 256 инкрементов запускается код по инкременту верхней пары (я его не приводил целиком, а обозначил через JNZ skip_high_count_incr).
    Эта стратегия неизбежна на таком монстре 8-битности как MOS 6502, но и в тяготеющем к указателям и 16-битным сложениям i8080/Z80 она продолжает быть актуальной во многих случаях.
    Изначальный код легко избавляется от push/pop таким образом и становится 8-битным без значимых пенальти, а наоборот с выгодой.
     
  16. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    8080 частично 16 битный процессор, есть советский КР580ВМ1, там кроме DAD есть ещё HL-=reg16 и CMP HL, reg16 что здорово помогает с 16 битной арифметикой, так же подобные расширения есть в 8085 и Z80.
    Код (ASM):
    1.     ;sum_l:B, sum_r:C
    2.     $LET    HL:=0, count:=HL, B:=0
    3.     $LET    HL:=&L1, [HL]:=10
    4.     CYCLE1:
    5.         $LET    HL:=&L2, [HL]:=10
    6.         CYCLE2:
    7.             $LET    HL:=&L3, [HL]:=10
    8.             CYCLE3:
    9.                 $LET    C:=0
    10.                 CYCLE4:
    11.                     $LET    A:=B, A++, A-=C
    12.                     $JM     M1
    13.                     $JZ     M1  ;if(a>0)
    14.                         $CMP    A, 20
    15.                         $JP     M1      ;if(a<20)
    16.                             $LET    HL:=count, E:=A, D:=0, HL+=DE, A-=10
    17.                             $JM     M2
    18.                             $JZ     M2  ;if(a>0)
    19.                                 $LET    A+=A, A^=0FFh, E:=A, D:=0FFh, HL+=DE, HL++
    20.                             M2:
    21.                             $LET    count:=HL
    22.                     M1:
    23.                     $LET    C++, A:=C
    24.                 $CMP    A, 10
    25.                 $JM     CYCLE4
    26.                 $LET    B++, HL:=&L3, [HL]--
    27.             $JNZ    CYCLE3
    28.             $LET    A:=B, A-=9, B:=A
    29.             $LET    HL:=&L2, [HL]--
    30.         $JNZ    CYCLE2
    31.         $LET    A:=B, A-=9, B:=A
    32.         $LET    HL:=&L1, [HL]--
    33.     $JNZ    CYCLE1
    Этот код уже меньше секунды.
    Хорошо бы формат rkp разобрать, чтобы ассемблер UASM сразу мог их генерировать, новою версию Emu80 скачал. Давно мечтал сделать похожий ассемблер, ещё лет 25-30 назад.
     
  17. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
  18. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    Ещё немного забавного кода.
    Код (ASM):
    1.     $LET    HL:=0
    2.     $PUSH   HL
    3.     $LET    A:=0, H:=10 ;L1
    4.     CYCLE1:
    5.         $MOV    L, 10   ;L2
    6.         CYCLE2:
    7.             $MOV    B, 10   ;L3
    8.             CYCLE3:
    9.                 $MOV    C, 10   ;R1
    10.                 CYCLE4:
    11.                     $MOV    D, 10   ;R2
    12.                     CYCLE5:
    13.                         $MOV    E, 10   ;R3
    14.                         CYCLE6:
    15.                             ;if (A==0){
    16.                             $AND    A, A
    17.                             $JNZ    M1
    18.                                 $LET    HL~~[SP], HL++, [SP]~~HL
    19.                             M1:;}
    20.                             $LET    A--, E--
    21.                         $JNZ    CYCLE6
    22.                         $LET    A+=9, D--
    23.                     $JNZ    CYCLE5
    24.                     $LET    A+=9, C--
    25.                 $JNZ    CYCLE4
    26.                 $LET    A+=1+10, B--
    27.             $JNZ    CYCLE3
    28.             $LET    A-=9, L--
    29.         $JNZ    CYCLE2
    30.         $LET    A-=9, H--
    31.     $JNZ    CYCLE1
    32.     $POP    HL
    Использую все регистры, и только count на верхушке стека. Оператор ~~ это у меня обмен. На радиошке 32 сек, партнёр должен 20 сек управиться. В Аккумуляторе сумма L1+L2+L3-R1-R2-R3
    intel8080.asm потом выложу.
     
  19. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    591
    aa_dav, команды и тайминги 8080 таковы что для word'ов лучше использовать эти 16 битные команды. А то смотришь на это.
    Код (ASM):
    1.  
    2. MOV A,E ;Заносим младшую часть множимого в аккумулятор
    3. ORA A   ;Сбрасываем флаг С
    4. RAL     ;Сдвигаем младшую часть множимого влево
    5. MOV E,A ;Возвращаем ее на место
    6. MOV A,D ;Заносим старшую часть множимого в аккумулятор
    7. RAL     ;Сдвигаем старшую часть множимого влево
    8. MOV D,A ;Возвращаем ее на место
    9.  
    И понимаешь можно сделать так.
    $LET HL~~DE, HL+=HL, DE~~HL ;DE*=2
    Не задействован аккумулятор, и выполняется довольно быстро 4+10+4=18 тактов. А код выше 5+4+4+5+5+4+5=32 такта. Нормально так, и что, 8080 разве не частично 16 битный? У КР580ВМ1 есть ещё DSUB и DCMP для сравнения BC/DE, что ещё больше делает его 16 битным.
     
  20. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
    Это если они чисто технически не начинают портить другие регистры и мешаться поэтому под ногами. В коде который я комментировал в центре цикла безусловно крутились два push/pop чтобы обеспечивать в том числе этот инкремент. Но инкремент происходит далеко не каждую итерацию и вынос его в байтовые команды мог наоборот помочь ускорить код - опять таки действительно надо по тактам смотреть, но по моим прикидкам так бы и было (сами однобайтовые команды, напомню, инкрементируя нижний байт только в одном из 256 случаев производят инкремент верхнего байта, т.е. их растактовка опять таки очень редко делает двойное обращение к памяти). Впрочем вынос count в вершину стека через ex hl,(sp) действительно еще круче.