nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 29 Mar 2024 05:54



This topic is locked, you cannot edit posts or make further replies.  [ 82 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
ОС Collapse on Z80 
Author Message
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
Lavr wrote:
И хотя говорят, что Zero Page - это как 256 регистров, реально они не так удобны, поскольку в регистрово-
ориентированном процессоре его набор регистров "свободен" для каждой задачи или прерывания,
то с Zero Page всегда приходится думать, кто кроме тебя ещё пользуется этими "регистрами", а это и ОС,
и сам ЯВУ, если мы пишем из-под него.


Это так, да! Впрочем при входе в прерывания Z80 точно так же вынужден будет сохранять контекст, разве нет? Точно так же и любой из 256 псевдо-регистров можно сохранить в стек, а именно
Code:
 
  PHA                   ; 3
  LDA $zero_mem    ; 3
  PHA                   ; 3
.....
  PLA                   ; 4
  STA $sero_mem   ; 3
  PLA                   ; 4

Что займет 9 тактов на сохранение одного псевдо-регистра и 11 тактов на его восстановление. Z80 push/pop-ает пару регистров за 11/10 тактов, что дольше на такт при сохранении контекста и быстрее на 1 такт при его восстановлении.
В принципе можно аппаратно подменять ZeroPage при входе в прерывание, переключаясь на страницу псевдо-регистров для прерывания и это не займет 3 такта - "плюнуть" в порт в той же ZeroPage. В последствии такой подход переноса базы ZeroPage реализовали в продолжателях 6502 уже на уровне архитектуры CPU.


28 Oct 2019 01:21
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
barsik wrote:
Недостатки 6502 устраняет 65C816, у которого с 16-ти разрядностью и ограничением в 64К нет проблем, он оставляет по всем параметрам Z80 далеко позади. Но по сути доработок 65C816 отбрасывает, как неудобные программисту, все идеи применённые в оригинальном 6502 ради экономии транзисторов, - его архитектура в его "родном" режиме похожа на архитектуру 6809, а не 6502. С ассемблером 65C816 может быть было бы интересно познакомиться на практике. Но опять-таки, ассемблер, это уже не модно, т.е эффективно, но слишком трудоёмко. Если нет компиляторов специально для 65C816, то и смысла в нём нет. Кстати, в то же время Zilog тоже сделал апгрейд - Z180, но там почти нет в системе команд и архитектуре ничего нового (лишь в один флакон запихали CPU и периферийные БИС). Это потому, что у Z80 уже ничего нельзя было заметно улучшить, т.к он изначально хорош, в отличие от 6502.


Судя по параграфу с сайта WDC особенности обоих чипов 65C02 и 65C816 учитываются C-компилятором.

Quote:
WDC now provides it's WDCTools suite for FREE. You can register and download at WDC65xx.com.
The base installer includes limited versions of our W65C02 and W65C816 C-Compilers/Optimizers. You can now register and download FULL versions for free from the same WDCTools download page. We have these as individual downloads so that we have a better view of how many people are using the Assembler versions and C-Compiler versions.


Насчет улучшить Z80 до Z180. То же произошло и с 6502 при превращении его в 6502 и в 6510, где в последнем случае добавились линии порта внутрь процессора. Прям один в один. Что касаемо улучшений системы команд то аналогично z180, 65С02 и 6510 были "слегка модернизированы" избавлены от бага перехода через границу страницы и получили с пяток инструкций. Версия 65С02 в последствии была задрана до 14МГц.


28 Oct 2019 02:31
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
barsik wrote:
Я давно не в курсе программистского суржика, потому посмотрел в википедии, что значит back-end, но всё-равно не понял смысла. Ссылка с русской буквой "И" не выкладывается, смотрите вручную: [ru.wikipedia.org/wiki/Front_end_и_back_end]. По-видимому, имеется ввиду возможность странслировать один и тот же код и сравнить в реале.


Проще говоря back-end это та часть компилятора которая заведует получением машинно зависимого кода. На входе back-end получает какую то унифицированную информацию, для современных компиляторов это например синтаксическое дерево разбора, для более древних где back-end буквально вшит в код - это процедуры скажем привязанные к генерации кода для конструкции инкремента.
Конструкция то одна, предположим выглядит она так p++; а вот применений много скажем так a = *p++ или так c = *++p. Не оптимизирующий компилятор просто вызовет процедуру генерации инкремента над ячейкой памяти p, а после вызовет процедуру генерации доступа по указателю. А оптимизирующий может заложить это все в одну машинную команду, ну в случае например pdp-11.
Так вот если для Small-C имеем один и тот же front-end то back-end будет очень разный для Z80 и 6502 для операции например индексного доступа и это можно все рассмотреть в файле листинге и оценить соответственно кто точнее и ближе к платформе написал back-end.

Поизучал минут 15 выхлоп cc65 при разных ключиках оптимизации -Os, Or, O1, O2, O3

никаких изменений в генерируемом коде, не умеет он оптимизировать по всей видимости :)

P.S. Пардон муа, посвежей CC65 оптимизирует еще как оптимизирует! Вот два фрагмента без ключа -O и с ключом -O

Code:
unsigned char p[20];
unsigned char i;

void main(void){
  i=0;
 
  do{
    p[i] += p[i++];
  }while(i<20);

}

int arr16[128];

int getValue(int index) {
    return (arr16[index & 0x7f] & 0xff) >> 1;
}

.segment        "CODE"                                                    .segment        "CODE"                                           
                                                                                                                                           
        ldx     #$00                                                              lda     #$00                                             
        lda     #$00                                                              sta     _i                                               
        sta     _i                                                        L0005:  lda     #<(_p)                                           
L0005:  lda     #<(_p)                                                            ldx     #>(_p)                                           
        ldx     #>(_p)                                                            clc                                                       
        clc                                                                       adc     _i                                               
        adc     _i                                                                bcc     L000A                                             
        bcc     L000A                                                             inx                                                       
        inx                                                               L000A:  jsr     pushax                                           
L000A:  jsr     pushax                                                            sta     ptr1                                             
        ldy     #$00                                                              stx     ptr1+1                                           
        jsr     ldauidx                                                           ldy     #$00                                             
        jsr     pushax                                                            lda     (ptr1),y                                         
        ldx     #$00                                                              sta     sreg                                             
        lda     _i                                                                lda     _i                                               
        inc     _i                                                                inc     _i                                               
        clc                                                                       sta     ptr1                                             
        adc     #<(_p)                                                            tya                                                       
        tay                                                                       clc                                                       
        txa                                                                       adc     #>(_p)                                           
        adc     #>(_p)                                                            sta     ptr1+1                                           
        tax                                                                       ldy     #<(_p)                                           
        tya                                                                       lda     (ptr1),y                                         
        ldy     #$00                                                              clc                                                       
        jsr     ldauidx                                                           adc     sreg                                             
        jsr     tosaddax                                                          ldy     #$00                                             
        ldy     #$00                                                              jsr     staspidx                                         
        jsr     staspidx                                                          lda     _i                                               
        ldx     #$00                                                              cmp     #$14                                             
        lda     _i                                                                bcc     L0005                                             
        cmp     #$14                                                              rts                                                       
        jsr     boolult                                                                                                                     
        jne     L0005                                                     .endproc                                                         
        rts                                                                                                                                 
                                                                          ; ---------------------------------------------------------------
.endproc                                                                  ; int __near__ getValue (int)                                     
                                                                          ; ---------------------------------------------------------------
; ---------------------------------------------------------------                                                                           
; int __near__ getValue (int)                                             .segment        "CODE"                                           
; ---------------------------------------------------------------                                                                           
                                                                          .proc   _getValue: near                                           
.segment        "CODE"                                                                                                                     
                                                                          .segment        "CODE"                                           
.proc   _getValue: near                                                                                                                     
                                                                                  jsr     pushax                                           
.segment        "CODE"                                                            ldy     #$00                                             
                                                                                  lda     (sp),y                                           
        jsr     pushax                                                            asl     a                                                 
        ldy     #$01                                                              tay                                                       
        jsr     ldaxysp                                                           lda     _arr16,y                                         
        ldx     #$00                                                              ldx     #$00                                             
        and     #$7F                                                              lsr     a                                                 
        jsr     aslax1                                                            jmp     incsp2                                           
        clc                                                                                                                                 
        adc     #<(_arr16)                                                .endproc                                                         
        tay
        txa
        adc     #>(_arr16)
        tax
        tya
        ldy     #$01
        jsr     ldaxidx
        ldx     #$00
        jsr     asrax1
        jmp     L000F
L000F:  jsr     incsp2
        rts

.endproc


28 Oct 2019 04:16
Profile
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 584
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Post .
SAA wrote:
Ну первое, не соглашусь с высказыванием по поводу PL/M, как маркером пригодности процессора к ЯВУ.
Конечно, PL/M не критерий пригодности процессора для ЯВУ. Речь была о том, что имеется сейчас для практического использования, а PL/M по-моему как-раз лучшее, что можно найти (хотя похоже PLI от Digital Research не хуже, но он заметно сложнее). Ведь считается, что нет другого ЯВУ дающего более плотный код. В отличие от остального, о PL/M я немного в курсе, потому могу на эту тему порассуждать.

Официально считается, что PL/M даёт код всего на 30-40% больший, чем код из под ассемблера. Может на больших программах и других компиляторах это так, но пока у меня сложилось мнение, что PLMX даёт код примерно вдвое больший, чем аналог написанный на ассемблере (хотя надо учесть, что я имея мало опыта, пишу неоптимальный код). Пока я написал в учебных целях всего несколько и весьма небольших программ на PL/M (редактор фонтов, текстов редактор и два простейших конвертора текстовых файлов в 25 строчек моего кода в каждом).

Для сравнения, мой примитивный текстов редактор на ассемблере КР580 занимал 4 кб, чуть лучший по возможностям текстов редактор на Турбо-Паскале Z80 занимал 12 кб. А на PL/M это ~7 кб (примерно, т.к его ещё не дописал до конца). Редакторы - по возможностям примерно одинаковы (аналоги родного турбо-паскалевского).

А ведь Турбо-Паскаль, похоже, даёт самый плотный код из всех компиляторов, что я пробовал, (хотя возможно так лишь потому потому, что остальные компиляторы были для КР580). По моим неточным (т.е без подтверждения многократной статистикой) данным: Турбо-Паскаль Z80 даёт объёмный коэффициент ~3, Си для КР580 - ~4, компилятор Паскаль МТ+ ~4.5, бейсик-компилятор - ~6. Это значит, чтобы писать на Паскале и Си надо турбировать компьютер в 4 раза. А при PL/M всего в полтора раза.

Ясно, что сам PL/M примитивен относительно более молодых ЯВУ, например, нет структур, потоков, многомерных массивов, хоть какой-то арифметики за пределом 16-ти бит, не говоря уж об вычислениях с плавающей точкой с точностью 38 знаков, работы с указателями и управления динамической памятью. Потому облегчает программирование в меньшей степени, чем мощные алгоритмические языки. Т.е полезен только для не очень сложных программ, таких, что несложно написать и на ассемблере. В одной журнальной статье читал, что работу программиста на ассемлере PL/M ускоряет в 5 раз.

Ясно, что на Си программа будет написана быстрее и с меньшим напрягом мозга (уже то, что запись программы на Си компактнее, нагляднее и понятнее, облегчает). Потому, из-за того, что PL/M менее удобный, чем Си, если ранее для контроллеров писали программы на PL/M, теперь лишь на Си. Но может-ли самый оптимизирующий компилятор Си выдать код такой же плотности, что даёт PL/M ?

Кстати, ущербность архитектуры 6502 похоже сжирает все преимущества в объёме кода, что дают JR-команды и он уступает в этом даже 8080. Билл Гейтс с соратниками легко уместил бейсик 8080 при конверсии в тот же объём для процессора 6800, но при конверсии для 6502 это не получилось (6800 вообще очень экономный по коду, у него TINY-бейсик всего 768 байт против 1800 байт 8080).
Quote:
Ric Weiland, Bill Gates and Monte Davidoff at Microsoft wrote MOS 6502 BASIC in the summer of 1976 by converting the Intel 8080 version. While the former could fit well into 8 KB, so that a computer manufacturer could add some machine-specific I/O code and ship a single 8 KB ROM, code density was less on the 6502, and they could not fit it significantly below 8 KB – it was around 7900 bytes – so that computers with BASIC in ROM would require more than a single 8 KB ROM chip.

Spilling over 8 KB anyway, they decided to also offer an improved version with extra features in a little under 9 KB: This version had a 40 bit floating point library (“9 digits”) instead of the 32 bit one (“6 digits”), and the two-character error codes were replaced with actual error messages.
Сможет ли оптимизирующий компилятор Си дооптимизировать до уровня аналога написанного на ассемблере? Или хотя бы до уровня PL/M. Под эффективностью компилятора понимается скорость прогона и объём полученной программы. Хотя по логике понятие эффективность компилятора должна включать удобство и скорость разработки программ.

Почему-то несмотря на использование оптимизации компиляторы для PC с каждым годом становятся всё менее эффективными. Получаемые из под них программы требуют всё больше и больше ОЗУ и скорость процессора. Т.е понижается качество выходного кода ради роста уровня языка для упрощения разработки и, соответственно, удешевления продукта.


Last edited by barsik on 01 Nov 2019 08:02, edited 5 times in total.



28 Oct 2019 10:14
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
barsik wrote:
Для сравнения, мой текстов редактор на ассемблере КР580 занимает 3.5 кб, текстов редактор на Турбо-Паскаль Z80 даже с чуть меньшим объёмом функций занимает 12 кб. А на PL/M это ~7 кб. Редакторы - аналоги турбо-паскалевского, но примитивнее, без свопинга, т.е можно редактировать только файл, чей текст целиком уместился в буфер между концом кода редактора и вершиной TPA.


А не могли бы Вы как то охарактеризовать PL65 ? Я понимаю что Вам не довелось на нем пописать, но по спецификации смогли бы сказать насколько он прогрессивен относительно PL/M 8080? И вот еще вопрос который меня уже давно подмывает задать, а что скажите по поводу макро средств ассемблера. На C64 очень интересный в этом плане макроассемблер, напоминает нечто подобное PL/M. В конце того века (красиво звучит) на x86 были относительно не долго популярны зарезанные Си, C--. Такой интересный подход когда дают рулить переменными привязанными к регистрам и использовать синтаксис Си поверх. Не приходилось?

barsik wrote:
Ясно, что сам PL/M примитивен относительно более молодых ЯВУ, например, нет структур, потоков, многомерных массивов, хоть какой-то арифметики за пределом 65535, не говоря уж об вычислениях с плавающей точкой с точностью 38 знаков, работы с указателями и управления динамической памятью.

Но библиотеки то он позволяет, можно расширить и fixed point и даже float? Насчет структур конечно не очень здорово, но в принципе терпимо если можно использовать какое то макросредство и подставлять смещение к указателю. Мне не приходилось работать на PL/M и Ваше мнение особенно ценно. Есть ли действительно непреодолимые трудности написания в нем ПО?

barsik wrote:
Но может-ли самый оптимизирующий компилятор Си выдать код такой же плотности, что даёт PL/M ?

Неоднократно удивлялся как это умеет делать C от TI для msp430, разглядывая код порой чувствовал что я написал бы хуже. Иногда долго не мог понять почему не могу "переубедить" компилятор поступить по другому, обнаруживая в конце что компилятор видит шире меня, не сосредотачиваясь на узком участке кода на котором я считал что получаю выигрыш. Оптимизируя как по размеру, так и по скорости. То что код при этом получается иногда больше чем на ассемблере, как правило влияние подключения необходимого для старта кода, в том числе множества trap-ов и начальной инциалиазции boot-а (по моему он так и называется bootstrap код). Он в принципе выключается, но тогда многое придется делать в рукопашную. Опять же что то постоянно тянется из библиотек, стоит обнаружить ему скажем умножение на 10 и в код летит почти вся библиотека математики. Слишком много в ней пересечений и линекр не может вырезать лишнее, ну или я туплю и не могу это настроить. Так что да думаю сравнимый по плотности с PL/M код получить на современных Си компиляторов микроконтроллеров можно.
Другое дело что в принципе уплотнить код можно так как это делает Forth и тут совсем нет вариантов для ЯВУ, с ним тяжело тягаться наверное даже ассемблеру.

barsik wrote:
Билл Гейтс легко уместил бейсик 8080 при конверсии в тот же объём для процессора 6800, но для 6502 это не получилось (6800 вообще очень экономный по коду, у него TINY-бейсик всего 768 байт против 1800 байт 8080):


Стив Возняк как бы возражает своими 4К Integer Basic :) это я про 8К в статье. Насчет тини конечно нет.


28 Oct 2019 10:59
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
SAA wrote:
Lavr wrote:
И хотя говорят, что Zero Page - это как 256 регистров, реально они не так удобны, поскольку в регистрово-
ориентированном процессоре его набор регистров "свободен" для каждой задачи или прерывания,
то с Zero Page всегда приходится думать, кто кроме тебя ещё пользуется этими "регистрами", а это и ОС,
и сам ЯВУ, если мы пишем из-под него.

Это так, да! Впрочем при входе в прерывания Z80 точно так же вынужден будет сохранять контекст, разве нет? Точно так же и любой из 256 псевдо-регистров можно сохранить в стек...

Тут дело немного в другом, а не в сохранении псевдорегистров в стек.
Если мы сохранили в стек регистры 8080 или Z80, в подпрограмме или вызове прерывания, то мы
теперь знаем, что все регистры для нашей задачи свободны.

У 6502 сохранять их практически бесполезно: если работает ОС и наша задача, мы должны точно
не портить псевдорегистры, которые использует ОС. Сохраняй их, не сохраняй, но если наша задача
обращается к функциям ОС - нельзя портить содержимое её псевдорегистров.

Собственно, 256 псевдо-регистров тем и хороши, что не надо сохраняться в стек, а можно сразу
использовать свободные. Но надо точно знать, какие свободные.

Я с этим четко столкнулся, когда попытался программировать в симуляции Apple I: поверху - Woz Monitor,
у него - свои псевдо-регистры, под ним - Basic, у него - свои псевдо-регистры, а уже потом - моя задача,
и куда мои псевдо-регистры назначить - от фонаря не получится. Нельзя портить псевдо-регистры
Basic и Woz Monitor - надо точно знать, где они, а где свободно.

_________________
iLavr


28 Oct 2019 12:08
Profile
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 584
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Post .
А вот и мнение иностранного специалиста о том, что 6502 плохо годится для компиляторов ЯВУ:
Quote:
The 6502 is not very compiler friendly: lack of 16 bit registers, hardware stack with 8 bit stackpointer.
High level, block structured based, recursion able, languages require lots of memory, stacks, heaps, stack frames, variables on the stack. That means on the 6502 a software stack with zero page based stack pointer, and quite some code. Storing data stored on the stack also requires quite some code. A solution often used on small machines with the 6502 is to generate compact code for virtual machine and the virtual machine implements an interpreteer for a stack machine. It works but is slow. Trying to generate 6502 code leads to lots of code alas and memory is filled up quickly.
SAA wrote:
А не могли бы Вы как-то охарактеризовать PL65 ? Я понимаю, что Вам не довелось на нём пописать, но по спецификации смогли бы сказать насколько он прогрессивен относительно PL/M 8080?
PL65 это развитый язык похожий на Паскаль. По первому впечатлению не имеющий ничего общего с PL/M. По плотности выходного кода, он вряд-ли лучше, чем PL/M для 8080 или 6502, но по всем остальным параметрам, он, естественно, намного мощнее и удобнее для программиста, чем PL/M. Трудно ожидать иного, ведь 8-ми разрядный PL/M официально из 1973 (хотя была и ранняя 4-х разрядная версия уже в 1972), а PL65 для Атари из 1987, разница в 15 лет. Интересно бы сравнить объём кодов компиляторов.

Оригинальный PL/M был кросс-компилятором для майн-фрейма PDP-10 (написанный на фортране-IV), потому сравнивать можно лишь производные от него версии для "родных" платформ (т.е не кросс). Это PL/M для ОС ISIS от фирмы Intel из конца 70-тых с размеров в ~130 кб и компилятор PLMX для CP/M, который был написан в 1979 г. программистом по имени Roger Carlson размером в ~100 кб. Компилятор PL/M для ISIS фирмы Intel написан на самом PL/M, может даже на нём самом (первая версия конечно была странслирована кросс-средством).

Возможно PL/M от Intel более эффективный, чем PLMX от Roger Carlson, т.к он всё-таки создан солидной фирмой с кучей программистов и опытом поддержки PL/M в течение многих лет (в Intel всё писали на PL/M, даже их ОС ISIS написана на PL/M), в то время как PLMX написан одним индивидуальным предпринимателем. PLMX по возможностям самого языка это несущественно усечённая версия PL/M стандарта 1976, но зато он для CP/M и имеет библиотеки для CP/M (хотя мне они не нужны, я предпочитаю на ассемблере написать своё). Ну и немаловажно, что PLMX запускается под TSR-эмулятором CP/M, т.е прямо из Windows XP (не более поздних). PL/M от ISIS вообще не использовать. А написанный на фортране PL/M наконец недавно (конвертировали на Си) и научились использовать, - он может и чуть эффективней, но в использовании очень неудобный.

Возможно PL/M и не единственный пригодный инструмент для 8080, т.к судя по имеющейся информации, есть подозрение, что PL/I от Digital Research окажется не хуже, чем PLMX и PL/M. Но я уже потратил энергию на освоение PL/M и не хочу пока тратить силы и время на изучение другого, к тому же более сложного ЯВУ.
SAA wrote:
И вот ещё вопрос, который меня уже давно подмывает задать, а что скажете по поводу макро средств ассемблера. На C64 очень интересный в этом плане макроассемблер, напоминает нечто подобное PL/M.
C64 это компьютер Cоmmodore-64?

Как макроассемблер может напоминать что-то из PL/M? Там нет макро. Макро-ассемблер позволяет определить макрокоманду, т.е задать цепочку команд ассемблера, которой передаются параметры и есть куча хитростей с макроподстановкой. Это, кстати, позволяет на ассемблере реализовывать даже некоторые операторы из ЯВУ, например, WHILE-ENDW, IF-THEN-ELSE.

Ничего сравнимого по возможностям с макро средствами в PL/M нет. Там с помощью LITERALLY можно лишь задать замену одного любого слова на другое слово или цифру или несколько слов и цифр. Это аналог ассемблерного псевдооператора EQU и аналог define в Си. До макро-команд этому "фичу" далеко.
SAA wrote:
были относительно недолго популярны зарезанные Си, C--... Не приходилось?
Не видел, этого в СССР не было, лишь читал в Интернете. Ещё и Паскаль-0 был, упрощённый. Есть ли от подобного польза? Хоть что-то это улучшает, кроме экономии трудозатрат разработчика компилятора? Можно думать, что это ради упрощения компилятора, когда на полноценный компилятор, либо ОЗУ, либо энтузиазма, либо ума не хватило.
SAA wrote:
Но библиотеки-то он позволяет, можно расширить и fixed point и даже float?
Естественно, как и у всех линкующих компиляторов, можно писать модули на ассемблере или любом ЯВУ, если они используют линковку и их REL-формат совместим с Microsoft и Digital Research (а это не у всех компиляторов так). Как раз, когда я пишу на PL/M, всё что легко сделать на ассемблере, я делаю на нём и только в текстовом редакторе, который специально стал писать, чтобы оценить эффективность кода от PL/M, я всё делал только на самом PL/M.

Этим-то все линкующие ЯВУ лучше, чем Турбо-Паскаль. Его по сути следует считать игрушкой. Он конечно позволяет ассемблерные вставки, но намного более утомительным способом. Кстати, с наличием Паскалей для 6502 дело обстоит похоже на порядок хуже, чем с Си для него же.
SAA wrote:
Мне не приходилось работать на PL/M и Ваше мнение особенно ценно
В PL/M я пока не особо компетентен, хотя сейчас, похоже, в России кроме меня только Kakos-nonos имел дело с PL/M (он написал игру для Апогея). Я только пару месяцев, как этим озадачился, причём дважды за это время все написанные программы на PL/M утрачивались. А вообще в 80-тые PL/M-у учили на курсах программистов и инженеров конструкторов контроллеров (на 8085 и 8048/51), и PL/M был основным ЯВУ в дистрибутиве СМ-1800.

Долго привыкать, после Паскаля и Си раздражает (приводит к ошибкам) CALL перед процедурами, когда они вызываются, как процедуры. Постоянно забываешь вставить CALL. Даже подумывал написать препроцессор, что будет находить в тексте процедуры и вставлять, где надо CALL. Сначала вообще получалось не в 5 раз быстрее, чем на ассемблере, а раз в 15 медленнее. Спустя время более-менее привык, но всё-равно получается никак не быстрее, чем на ассемблере. Видимо надо набраться больше опыта, тогда получится польза от ЯВУ. Но в принципе писать на любом ЯВУ намного легче и приятнее, чем на ассемблере. Чтобы оценить PL/M, я хотел бы написать CP/M-нортон.

А вообще, если объём кода позволяет, то лучше писать на Паскале, получается намного быстрее и возможности выше. Особенно, если Паскаль не Турбо от Borland, а нормальный с линковкой (за счёт чего всё что удобно можно переписать на ассемблер). Или писать на Си. Но увы, на этих ЯВУ не написать программы даже средней сложности. Объём кода быстро нарастает за 32 кб. Например, более-менее полноценный Нортон получается в 40 кб, а ведь для него ещё нужен буфер копирования (чем он меньше, тем медленннее скорость копирования), а главное, совсем не остаётся места для реализациии "глЮкала": для графической машины нет места для буфера сохранения окон, только для текстовой. Потому и приходится использовать PL/M, несмотря на то, что он и не самый удобный ЯВУ.
SAA wrote:
Есть ли действительно непреодолимые трудности написания в нём ПО?
Нет, по сути это тот-же ассемблер, только синтаксис другой. Потому можно сделать всё то же, что и на ассемблере, т.е можно написать любую программу для которой хватает объёма ОЗУ (а если и появится что-то непреодолимое, то ассемблер в помощь). Но сложную по алгоритму программу лучше писать на Си или Паскале. Ещё Аду и Драко можно попытать. Они написаны позже, может быть эффективнее.
SAA wrote:
Стив Возняк, как бы возражает своими 4К Integer Basic
Целочисленный бейсик и от Билла Гейтса занимает те же 4 кб. Там речь шла о полноценном бейсике. Ну и был упомянут TINY-бейсик. Не интересовался объёмом TINY-бейсика в кодах 6502, но уверен, что он больше, чем 768 байт.

Любопытно, что Возняк писал ROM-BIOS-ы Apple и целочисленный бейсик в машинных кодах. У него не было дисковода и транслятора. Лишь мини-отладчик. А Билл Гейтс с компаньонами в работе использовали майн-фрейм PDP-10 и вот здесь написано, что у них благодаря этому был хоть и убогий, но транслятор ассемблера (реализованный в виде макро). Странно, что они поленились написать свой, ведь ассемблер без макрокоманд для 6502 (или 8080) пишется опытным программистом за 3-4 дня.


Last edited by barsik on 28 Oct 2019 20:12, edited 8 times in total.



28 Oct 2019 16:10
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
Lavr wrote:
У 6502 сохранять их практически бесполезно: если работает ОС и наша задача, мы должны точно
не портить псевдорегистры, которые использует ОС. Сохраняй их, не сохраняй, но если наша задача
обращается к функциям ОС - нельзя портить содержимое её псевдорегистров.


Я правильно понимаю что обращение к функциям ОС происходит из прерывания? Или речь о работе вне прерывания, когда 256 регистров из прерывания используются кем то другим?

Lavr wrote:
Собственно, 256 псевдо-регистров тем и хороши, что не надо сохраняться в стек, а можно сразу
использовать свободные. Но надо точно знать, какие свободные.

Я с этим четко столкнулся, когда попытался программировать в симуляции Apple I: поверху - Woz Monitor,
у него - свои псевдо-регистры, под ним - Basic, у него - свои псевдо-регистры, а уже потом - моя задача,
и куда мои псевдо-регистры назначить - от фонаря не получится. Нельзя портить псевдо-регистры
Basic и Woz Monitor - надо точно знать, где они, а где свободно.


В случае когда ОС и BIOS (монитор) написан не Вами и не документирован - ситуация совершенно таки аховая. Тут даже смена банка ZeroPage ничем не поможет так как в задаче пользователя в этот момент прерывания разрешены и если подменить страничку "только для себя", не выключив прерывания, то подменишь ее для всех (кроме того такой возможности в Apple II и нет). Все печально в таких случаях, могу лишь заметить что потенциально удобную возможность "изгавнять", как оказывается, пара пустяков.
А что у Воза все так плохо с документированием? Вроде бы его монитор для Apple I дизассемблировали, конечно там 512 байт и разобраться в них намного проще.


28 Oct 2019 19:30
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
barsik wrote:
Под эффективностью компилятора понимается скорость прогона и объём полученной программы. Хотя по сути понятие эффективность компилятора должна включать удобство и скорость разработки программ.


Я имел ввиду эффективность генерации машинного кода. Удобство и скорость разработки функция зависящая не только от компилятора как инструмента, но в большей степени от ЯВУ. Только что Вы приводили пример про то что на PL писать по сравнению с Си не настолько эффективно.

Ну и "что бы два раза не вставать" по поводу эффективности генерации кода которая от того на чем компилятор написан не зависит, писали бы компилятор на Си, на ассемблере или на PL/M все равно для генерации машинного кода использовалась бы одна и та же стратегия. Поэтому и не зависит от того на чем компилятор написан.

barsik wrote:
Почему-то несмотря на использование оптимизации компиляторы для PC с каждым годом становятся всё менее эффективными. Получаемые из под них программы требуют всё больше и больше ОЗУ и скорость процессора. Т.е понижается качество выходного кода ради роста уровня языка для упрощения разработки и, соответственно, удешевления продукта.


Тут другая проблема - желание разработчика увеличить скорость выхода готового продукта приводит к использованию множества библиотечного заимствованного кода, который в свою очередь написан с высоким уровнем абстракции, подразумевающим систему взаимосвязанных объектов с изоляцией их другу от друга (ООП). Очень распространены надстройки над этими библиотеками опять изолирующие свой код. Компилятор в этом случае не может рассмотреть цепочку вызовов на всем протяжении и скомпилировать код без лишних call. В итоге код разрастается по размеру, критические фрагменты не лезут в кеш, промахи приводят к потери производительности. Как то пришлось портировать код с С++ на Си на примере симулятора мк61. И было замечено что если в скорости код почти не теряет (за счет того что исходник полный без подключения каких либо библиотек реализуемых третей стороной) то по размеру на С++ он значительно больше чем на Си. И конечно это очень обозримый код, в котором ты ориентируешься от начала до конца.


28 Oct 2019 22:03
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
barsik wrote:
А вот и мнение иностранного специалиста о том, что 6502 плохо годится для компиляторов ЯВУ:
Quote:
The 6502 is not very compiler friendly: lack of 16 bit registers, hardware stack with 8 bit stackpointer.
High level, block structured based, recursion able, languages require lots of memory, stacks, heaps, stack frames, variables on the stack. That means on the 6502 a software stack with zero page based stack pointer, and quite some code. Storing data stored on the stack also requires quite some code. A solution often used on small machines with the 6502 is to generate compact code for virtual machine and the virtual machine implements an interpreteer for a stack machine. It works but is slow. Trying to generate 6502 code leads to lots of code alas and memory is filled up quickly.


Ну все понятно крутимся вокруг стека и рекурсии, плюс 16 битная арифметика. Хотя вот она то как то незаслужено обижена. Предложение для осуществления рекурсии перейти на интерпретируемый код и виртуальную машину, выглядит не вполне развернутым. Форт в некоей степени то же "виртуальная машина", про него не слова. Вполне можно вывернуться если нужна "бесконечная" рекурентность без потери производительности кода. На самом деле существуют ведь аппаратные стеки на 4,8,16 вложений. Это не новость и обходить рекурсивные алгоритмы научились. Ну да ладно, в этом фрагменте кроме 16-разрядности спорить особо не с чем. Все так.

сложим два 16 р-р числа лежащих в ZeroPage и не в ZeroPage
Code:
  clc    ; 2
  lda    $VAL0_LO_BYTE ; 3/4
  adc   $VAL1_LO_BYTE ; 3/4
  sta    $VAL1_LO_BYTE  ; 3/4   lo(val1) = lo(val0) + lo(val1)
  lda    $VAL0_HI_BYTE ; 3/4
  adc   $VAL1_HI_BYTE ; 3/4
  sta    $VAL1_HI_BYTE  ; 3/4  hi(val1) = hi(val0) + hi(val1) + CARRY


ИТОГО 20/26 тактов. А если код само-модифицирующийся будет еще быстрей

Code:
  clc                           ; 2
  lda    #VAL0_LO_BYTE ; 2
VAL1_LO:
  adc   #VAL1_LO_BYTE ; 2
  sta    $VAL1_LO+1      ; 3/4   lo(val1) = lo(val0) + lo(val1)
  lda    #VAL0_HI_BYTE ; 2
VAL1_HI:
  adc   #VAL1_HI_BYTE ; 2
  sta    $VAL1_HI+1      ; 3/4   lo(val1) = lo(val0) + lo(val1)


ИТОГО 16/18 тактов.

Поправьте меня если я не прав, 16 битное сложение для Z80 и 8080 это сложение пары регистров с HL, с передачей в HL результата. Я не говорю об выгрузке результата из HL, но загрузка пары из памяти или константой нужна, мы же не разбираем случай суммирования с накоплением. Загрузка пары HL это 16 тактов, для другой пары 20 тактов, само сложение еще 11 тактов. ИТОГО 47 тактов. Возможно тоже с само-модификацией загрузка константой HL это 10 тактов, другой пары 10 + сколько то на переброску из HL и само сложение 11, получим не меньше 31 такта. Возможно я не прав, ошибаюсь - поправьте меня.


28 Oct 2019 23:04
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
barsik wrote:
Долго привыкать, после Паскаля и Си раздражает (приводит к ошибкам) CALL перед процедурами, когда они вызываются, как процедуры. Постоянно забываешь вставить CALL. Даже подумывал написать препроцессор, что будет находить в тексте процедуры и вставлять, где надо CALL. Сначала вообще получалось не в 5 раз быстрее, чем на ассемблере, а раз в 15 медленнее. Спустя время более-менее привык, но всё-равно получается никак не быстрее, чем на ассемблере. Видимо надо набраться больше опыта, тогда получится польза от ЯВУ. Но в принципе писать на любом ЯВУ намного легче и приятнее, чем на ассемблере. Чтобы оценить PL/M, я хотел бы написать CP/M-нортон.


А сколько в строках/Кб занимает исходник скажем Вашего редактора на PL/M?
Препроцессор конечно бы ситуацию спас. Но вот вопрос - а где находится текст исходника при работе препроцессора? Буферизируется? Вычитывается и парсится по символьно, а куда складывается готовый результат?


28 Oct 2019 23:31
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
barsik wrote:
SAA wrote:
И вот ещё вопрос, который меня уже давно подмывает задать, а что скажете по поводу макро средств ассемблера. На C64 очень интересный в этом плане макроассемблер, напоминает нечто подобное PL/M.
C64 это компьютер Cоmmodore-64?


Он самый.

barsik wrote:
Как макроассемблер может напоминать что-то из PL/M? Там нет макро. Макро-ассемблер позволяет определить макрокоманду, т.е задать цепочку команд ассемблера, которой передаются параметры и есть куча хитростей с макроподстановкой. Это, кстати, позволяет на ассемблере реализовывать даже некоторые операторы из ЯВУ, например, WHILE-ENDW, IF-THEN-ELSE.


Макроассемблер может напоминать PL/M тем что использовать макроподстановку ключевых слов PL/M. Ниже фрагмент кода на таком ассемблере https://nurpax.github.io/c64jasm-browser/ !for здесь оператор макроподстановки размножения, не конструкции языка.

Code:
!include "c64.asm"

+c64::basic_start(entry)

entry: {
    lda #0      ; black color
    sta $d020   ; set border to 0
    sta $d021   ; set background to 0

    ; clear the screen
    ldx #0
    lda #$20
clrscr:
!for i in [0, $100, $200, $300] {
    sta $0400 + i, x
}
    inx
    bne clrscr

    ; line drawing, completely unrolled
    ; with assembly pseudos
    lda #$a0

    !for i in range(40) {
        !let y0 = Math.floor(25/40*(i+0.5))
        sta $0400 + y0*40 + i
        sta $0400 + (24-y0)*40 + i
    }
inf: jmp inf  ; halt
}


29 Oct 2019 01:46
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
SAA wrote:
А что у Воза все так плохо с документированием? Вроде бы его монитор для Apple I дизассемблировали, конечно там 512 байт и разобраться в них намного проще.

Да я верю, что у Воза все не так уж и плохо документировано. Просто когда ты в первый раз берешься
программировать под Эппл I всё это для тебя поначалу совершенно неизвестно, хотя монитор от Воза
даже не 512 байт, а всго лишь 256 при двух свободных байтах, причем код давно доступен с комментариями
от автора, и у меня он, безусловно есть, как и исходник Васика.

Но когда собираешься просто попробовать свои силы в ассемблере 6502, поиск и чтение документации
весь процесс просто зело и неконструктивно тормозит, хотя кодирование и несложно.

Когда в дремучие времена я учился программировать под К580ВМ80, я читал мануал от Микроши и
пытался действовать без ассемблера в кодах. :wink: Сунуться в дебри Монитора даже и не думал... :lol:

Просто мы сейчас же и ведем разговор: что удобно, и что неудобно у 6502 и z80(8080) для программиста.
Zero Page всё же не так удобно, как регистры на кристалле CPU, пусть даже этих псевдорегистров и больше.

_________________
iLavr


29 Oct 2019 07:37
Profile
Doomed
User avatar

Joined: 19 Feb 2017 03:46
Posts: 584
Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
Post 
Да, используя подпрограммы (там где для КР580 они не нужны) 6502 не много отстаёт и в 16-ти разрядной арифметике. А в Ваших расчётах увеличьте число тактов для 6502 вдвое (всегда сравнивают Z80 на 2 МГЦ с 6502 на 1 МГЦ).
SAA wrote:
Препроцессор конечно бы ситуацию спас. Но вот вопрос, - а где находится текст исходника при работе препроцессора? Буферизируется? Вычитывается и парсится по-символьно, а куда складывается готовый результат?
Всё проще. Препроцессор может быть отдельной программой конвертором и пишет в тот же файл. Компилятор запускается BAT-файлом (не вручную же набирать команды, этапов трансляции много). Просто перед запуском PLMX командный BAT-файл запускает простейшую программку конвертор написанную на том же PL/M. В ней есть загрузка/выгрузка файла целиком (это внешними библиотечными процедурами), потому сама программа в простом варианте это всего ~20 строк на PL/M делающих нужную обработку.

В более сложном варианте сканируем исходник, и по поиску слова PROCEDURE создаём список имён процедур. А на втором проходе ищем имена этих процедур и контролируем, что, если они вызываются не как функции, то перед ними присутствует слово CALL. Но даже это мне делать было бы лениво, - я хотел ещё проще, чтобы не сканировать дважды, планировал как флаг процедур начинать их имена с символа '$', что упрощает. Символ '$' компилятор PL/M игнорирует, его вставляют в имена для улучшения читабельности имён.
SAA wrote:
А сколько в строках / Кб занимает исходник скажем вашего редактора на PL/M?
Пока сказать не могу, но более 1000 строк, причём процедуры сдвига больших массивов и процедуру экранного ролика для граф.машины писать на ЯВУ разумно только с целью анализа его эффективности, иначе получается тормозятина. Всё остальное допустимо и на ЯВУ.

 современные винты служат недолго
Проблема в что, что у меня где-то 1.5 месяца назад сначала сдохли все данные на винчестере, погубив не только первые программки на PL/M, мелкие пробные, редактор фонтов (~350 строк) и почти законченный текстов редактор ~1000 строк, но и, что грустно, наработки по Паскалю МТ+ (это не восстановить, писалось давно и уже забыто). После переустановки DOS и ПО, т.к в голове всё ещё оставалось, за пару недель всё полезное по PL/M я почти восстановил (на 70%), но тут вдруг винчестер сдох окончательно. А я сдуру, т.к ещё не было доделано, снова не сделал копий на microSD 32 Гб или в облачном сервисе. Хотя всё нужное (наученный горьким опытом краха винта, когда потерял почти 50% архива программ и исходников 8-ми разрядок и все свои исходники за 3 последних года, лишь 50% сохранилось на винте ОРИОНА), привык резервировать. Но редко, а учебные программки и незаконченные исходники, естественно, вообще не резервировал.

Тогда до меня дошла подсказка, что вселенная не хочет, чтобы я в данный момент занимался программированием, потому решил немного позаниматься ретро железом. Это обычно: какое-то время что-то потихоньку программируешь (последние годы я этим занимаюсь на порядок меньше, даже, чем 10 лет назад и на 2 порядка, чем в 20 веке), а иногда для разнообразия, но редко, можно несколько недель подышать парами канифоли. На бОльший срок по железу меня никогда не хватает. Недавно начал написание текстового редактора на PL/M уже в третий раз. Пока восстановил лишь несколько подпрограмм.

 как устроен примитивный текстов редактор
Вообще примитивный текстов редактор 8-ми разрядки даже на ассемблере пишется за несколько дней (я это делал много раз). Бывают и совсем примитивные редакторы, которые при редактировании хранят весь текст в ОЗУ в распакованном виде, но это для 8-ми разрядки с крошечным ОЗУ совсем глупость. Хотя скорость их работы не страдает.

Нормальный примитивный редактор состоит всего из нескольких основных подпрограмм. Главная циклически прогоняемая процедура это EDIT. Первым делом, она вызывает подпрограмму SCRN_OUT, которая по текущей позиции экрана в тексте (по OFFSET) вычисляет адрес в текстовом буфере, где начало экрана, и выводит на экран 23 строки (2 строки служебные). Далее ожидая нажатий крутится цикл опроса, т.е в цикле прогоняется петля опрашивающая STATUS клавиатуры. По нажатиям курсорных клавиш курсор смещается по экрану (это делают процедуры: UP, DN, LE, RI, CR, PgUp, PgDn, To_Top, To_Bottom) с выходом в цикл опроса, а если нужна перерисовка экрана, то на вход EDIT. Если же будет нажата некурсорная клавиша или ^N, то делается уход на процедуру LN_EDIT.

В LN_EDIT текущая строка перегружается в строчный буфер, причём табуляции распаковываются. И далее работает примитивный строчный редактор для одной строки (при входе ему передаётся код полученной клавиши). В конце редактирования строки по нажатию клавиши меняющей вертикальную позицию, LN_EDIT делает сохранение строки в буфере текста и делается переход на главную петлю редактора вход EDIT.

При сохранении строчного буфера первым делом вычисляется: стала отредактированная текущая строка больше или меньше по размеру, чем исходная (что была на момент входа в редактор строки). Для этого сначала строка нормализуется, т.е где можно пробелы заменяются на TAB, хвостовые пробелы удаляются и после последней отображаемой буквы строки вставляется строчный разделитель (только 13 или два байта 13 и 10).

Если строка стала меньше, то строка вставляется в буфер и делается схлопка, сдвижка всего последующего текста на число байтов, на которое строка сократилась. Если же строка стала больше, то сначала место отводимое в буфере на строку освобождается, текст раздвигается, - последующие строки сдвигаются к вершине ОЗУ на нужное число байт и затем увеличившаяся отредактированная строка вставляется в исходное место.

Таким образом редактор по сути состоит из несложного редактора всего на одну строку и процедур пересылок. Ясно, что такая концепция редактирования простая, но очень тормозная. Если объём сдвигаемого текста до 10 кб, то сдвижка происходит более-менее быстро и незаметно. Но если текст в 40 кб, а редактируемая строка в начале текста, то сдвиг ~40 кб длится 2-3 секунды, что неудобно пользователю. Для скоростных машин, типа PC, сдвижка и 5 мб текста мгновенна, но для 8-ми разрядки это не так. Особенно тормозно, если редактировалась последняя строка экрана (или первая) и при перемещении курсора дополнительно выполняется ещё и ролик экрана. Это тормозит, даже при ролике стеком (да кстати, никогда 6502 не обойдёт по скорости ролик КР580 стеком).

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

 продвинутые алгоритмы текстового редактора
Есть несколько способов, как сделать работу текстового редактора нетормозной. Фирменные программы используют свопинг, отдельные буфера, разбивают огромный текст в 300 кб на кусочки и редактируют только небольшой текущий буфер. Потому в них уход с отредактированной строки не тормозит. А если писать на ЯВУ с поддержкой динамической памяти, то есть и более грамотные алгоритмы.

Но для машины, где ОЗУ с гулькин нос, доступ к флопу отсутствует (или дико тормозной), для ускорения нужны сложные алгоритмы. Я сделал для Специалиста такой скоростной редактор на ассемблере, идея отличная, скорости добился, но в итоге затрахался с отладкой, энтузиазма не хватило отладить до полной безглюковости (в каких-то ситуациях текст искажался). И до меня дошло, что сложные алгоритмы надо писать на ЯВУ.

Идея ускорения в том, чтобы делать долгую работу в паузы между нажатиями клавиш, в эти паузы процессор незаметно для пользователя, строчка за строчкой нормализует текст. Если при уходе с отредактированной строки, отредактированная строка меньше исходной, то она вставляется в исходное место, а лишние байты заполняются нулями (тогда подпрограмма поиска нужной строки, их пропустит), причём место где надо удалить лишние байты запоминается в списке. Если же строка имеет больший размер, чем исходная, то в текстовыё буфер вставляется байт-флага и следом за ним адрес динамического буфера, в котором теперь хранится эта строка. Динамические буфера под отдельные строки выделяются с RAMTOP и вниз.

Таким образом, получается мгновенная реакция на уход с отредактированной строки - курсор на экране переходит в другую строку без пауз. А затем, в паузу между нажатиями незаметно, без долгих зависов выполняется нормализация текста. И она не тормозит работу редактора, т.к текст нормализуется по-строчно. Т.е например, в случае, когда строка была короче и в тексте остались нулевые байты, то в цикле опроса STATUS-а клавиатуры, редактор сдвигает только одну очередную строку и так пока не дойдёт до конца текста. Если же надо делать сдвижку вверх, то начиная с последней строки, точно также построчно строки сдвигаются вверх. По окончании раздвижки строка из динамического буфера под вершиной ОЗУ ставится на место, а ОЗУ динамического буфера освобождается. Такой редактор имеет объём всего на 1 кб больше, чем тупой традиционный редактор, но зато работает без тормозов даже при такте 200 КГЦ.

Но такой алгоритм сложнее, чем примитивный, написать и отладить на ассемблере. Вот тут-то ЯВУ в помощь. А нет ли у кого-то идеи, как решить ту же задачу ускорения, но проще?

Чтобы понять о редакторах какого уровня речь, ниже в спойлере список их возможностей. Исходника редактора на ассемблере из начала 90-тых, который сравнивался, не сохранилось, но есть дополненная версия - в ней ~3200 строк ассемблера. Число строк редактора на PL/M не знаю (более 1000), а для версии на Турбо-Паскале можно посчитать.

Сохранён где-то на резервных CD-R оригинальный исходник CP/M-варианта редактора на Турбо-Паскале, но найти долго. Вот тот же исходник, лишь переделанный для трансляции TP MSDOS и затем переделанный для трансляции в Linux с помощью GPC. GPC ценен тем, что он перетранслирует исходники программ написанных для TP/BP/TPW в Linux (кстати, приятно, что есть модуль TP3, можно транслировать и программы CP/M-овского Турбо-Паскаля 3.0). Когда я в 1997 поставил себе Linux, то был в ужасе от качества их редакторов, они оказались вообще неэкранными. Пришлось перетранслировать CP/M-редактор под Linux и я им много пользовался (не этой версией, а доработанной, где было даже форматирование с правильными переносами), т.к ничего приличнее не было в дистрибутиве.

Как видите команды в моих редакторах те же, что и в редакторе самого Турбо-Паскаля (это популярный в CP/M стандарт). Кстати, раз Турбо-Паскаль уступает в эффективости ассемблеру всего в 3 раза, то т.к Турбо-Си для CP/M нет, то очевидный второй кандидат в наилучший инструментарий ретро программиста, это именно TP 3.0. Для Z80 (но не КР580) вроде бы есть и кросс-компиляторы Паскаля и даже с IDE, но, похоже, они или платные или недоделанные (типа студенческих работ).

 "О каких редакторах шла речь
[size=85]
Code:
HELP:   RST     18H

TXHELP: defb    CLSCOD,13,10,9
        defb    'NEW SCREEN ',VL,'.',SH,SL,' -- '
        defb    DH,DL,'.',MH,ML,'.',YH,YL,13,10,10

if      LAT

        defb    '^U   TO LINE END    ^ T  LN BEG/END',13,10
        defb    '^Q R GOTO BEG (@B)  ^Q C GOTO END (@E)',13,10
        defb    '^R   PAGE UP (@UP)  ^С   PG DOWN (@DN)',13,10
        defb    '^Y,^D ERASE LINE    ^N   INSERT LINE',13,10
        defb    'F5   CLEAR TO EOL   ^K O MERGE LINES',13,10
        defb    '^K B SET BLK.BEG    ^K K SET BLK.END',13,10
        defb    '^K C COPY BLOK      ^K V MOVE BLOK',13,10
        defb    '^K Y ERASE BLOK     ^K U UNMARK BLOK',13,10
        defb    '^Q F FIND (@F)      ^Q L FIND NEXT (^L)',13,10
        defb    '^Q A REPLACE (@Z)   ^QE  INSERT EOF',13,10
        defb    '^K 1..3 SET MARK    ^Q 1..3 GOTO MARK',13,10
        defb    'F2   ERASE SYMBOL   F3   INSERT SPACE',13,10
        defb    '^V   TOGGLE INS.    ^Q T SEL TAB MODE',13,10
        defb    '^K N NEW FILE (@N)  ^K A ASSEMBLER',13,10
        defb    '^E   EXIT',13,10,10,0
   else
        defb    '^T   В НАЧ/КОН СТРОКИ   ^U   В В КОНЕЦ СТРОКИ',13,10
        defb    '^Q R В НАЧ.ТЕКСТА (@B)  ^Q C В КОН.ТЕКСТА (@E)',13,10
        defb    '^R   НА ЭКР.ВВЕРХ (@UP) ^С   НА ЭКР.ВНИЗ (@DN)',13,10
        defb    "^Y,^D  УДАЛИТЬ СТРОКУ   ^N   ВСТАВИТЬ СТРОКУ",13,10
        defb    "F5   ОЧИСТИТЬ ДО 'EOL'  ^O   СЛИЯНИЕ 2 СТРОК",13,10
        defb    '^K B УСТ.НАЧАЛО БЛОКА   ^K K УСТ.КОНЕЦ БЛОКА',13,10
        defb    '^K C КОПИРОВАТЬ БЛОК    ^K V ПЕРЕМЕСТИТЬ БЛОК',13,10
        defb    '^K Y УДАЛИТЬ БЛОК       ^K U ОТМЕНИТЬ БЛОК',13,10
        defb    '^Q F ПОИСК ОБРАЗЦА (@F) ^Q L ПОИСК ДАЛЬШЕ (^L)',13,10
        defb    "^Q A ЗАМЕНА (@Z)        ^QE  УДАЛИТЬ ДО 'EOF'",13,10
        defb    '^K 1..3 УСТАН-ТЬ МЕТКУ  ^Q 1..3  ИДТИ К МЕТКЕ',13,10
;        defb    '^K P СТРОКУ В БУФЕР     ^K G СТРОКУ ИЗ БУФЕРА',13,10
        defb    'F2,^G  СДВИЖКА СТРОКИ   F3   РАЗДВИЖКА СТРОКИ',13,10
        defb    '^V   СМЕНА РЕЖ.ВСТАВКИ  ^Q T РАЗРЕШИТЬ ТАБ',13,10
        defb    '^K N НОВЫЙ ФАЙЛ (@N)    ^K A В АССЕМБЛЕР (@A)',13,10
        defb    '^E   ВЫХОД',13,10,10,0
 
endif
        RST     30H
        JR      BTM3

DH      EQU     DAY/10 +'0'
DL      EQU     (DAY MOD 10) +'0'

MH      EQU     MONTH/10 +'0'
ML      EQU     (MONTH MOD 10) +'0'

YH      EQU     YEAR/10 +'0'
YL      EQU     (YEAR MOD 10) +'0'

HOH     EQU     HOUR/10 +'0'
HOL     EQU     (HOUR MOD 10) +'0'

MIH     EQU     MIN/10 +'0'
MIL     EQU     (MIN MOD 10) +'0'

VL      EQU     (VERS MOD 10) +'0'
SH      EQU     SUBVER/10 +'0'
SL      EQU     (SUBVER MOD 10) +'0'

[/size]


Last edited by barsik on 01 Nov 2019 08:17, edited 4 times in total.



29 Oct 2019 17:04
Profile
Senior

Joined: 12 Jul 2016 21:30
Posts: 136
Lavr wrote:
даже не 512 байт, а всго лишь 256 при двух свободных байтах, причем код давно доступен с комментариями

Да нехорошо получилось, попутал, конечно же 256. Обидел Воза :) Но это верно для Apple I, а сколько занимает монитор Воза в Apple II?

Lavr wrote:
Просто мы сейчас же и ведем разговор: что удобно, и что неудобно у 6502 и z80(8080) для программиста.
Zero Page всё же не так удобно, как регистры на кристалле CPU, пусть даже этих псевдорегистров и больше.


Если быть точнее то обсуждаем мы что удобней для программиста компиляторов ЯВУ, т.е. в некотором роде системного ПО.
Я понимаю, Лавр, что Вы хотите сказать, но согласится с Вами на 100% не могу. То что Вы утверждаете верно для программиста приложений пользователя в ОС которая не регламентирует использование ресурсов и монополизирует их. Это так же верно и для других архитектур хоть z80 хоть x86, системный софт которых будет использовать на кристальные регистры безалаберно. 256 байт ОЗУ в версии 6508 было, кстати, перенесено на кристалл, но дело как мы понимаем не в локализации 256 регистров, а в регламентировании их использования.


29 Oct 2019 19:24
Profile
Display posts from previous:  Sort by  
This topic is locked, you cannot edit posts or make further replies.   [ 82 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

Who is online

Users browsing this forum: No registered users and 25 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.