Благодарю, все еще в поиске исходника tasm или хотя бы linux версии, на данный момент нашел вот такой архив, в нем есть документация в pdf по программированию для процессора 6502, думаю может быть полезна для тех, кто разрабатывает версию программы расчета числа Пи под процессор 6502 (NES, Агаты, Анюша, Apple 1).
Левенталь 6502 Подпрограммы на ассемблере (книга на английском).
в том же архиве находится и сам tasm 3.2, но с таблицей только для 6502.
Подумалось, что наверное не так сложно будет мне расковырять tasm с целью получить fork в исходниках, а сами таблички-то просто текстовые файлы, их можно использовать будет без изменений в авторской редакции.
tasm мега компилятор с ассемблера, и сразу под массу процессоров, среди которых есть почти все нужные нам ретро-процессоры.
Не представляется сложным написать самим таблички под какие-то другие более экзотичные процессоры , для этого и программирование даже знать и не нужно
Не особенно тщательно искал но на той же страничке проекта много чего выложено, может еще что-то найдется в тех архивах уникальное, как к примеру выше упомянутая версия книги Левенталя для 6502, дайте знать и мне.
Ждем теперь оптимизированную версию расчета чиста Пи по неоптимальному алгоритму и для процессора 6502
Последний раз редактировалось perestoronin; 01.01.2016 в 13:53.
Ретрокладовая продажи
Как вижу, деление работает с любым делителем до 2^16, это действительно необходимо? Уменьшение диапазона в два раза позволит выкинуть половину кода, а из оставшейся половину условных переходов. Вроде бы алгоритму "краника" деления на числа до 2^15 хватает для вычисления 4930 десятичных знаков.
Судя по времени работы текущая версия litwr весьма оптимизирована:
Это большой плюс tasma, который перевешивает (для меня) его недостатки.
- - - Добавлено - - -
Да, старший бит делителя бывает единичным. Диапазоны чисел я проверял, в умножении учет диапазона хорошо помог, а в делении, к сожалению, нет.
? Не могу сообразить, за счет чего можно выкинуть половину кода при уменьшении диапазона в два раза. На каждый бит делимого приходится 8 строк.
- - - Добавлено - - -
Это Вы наверно про исходный, а здесь то "4х циферный"
Последний раз редактировалось ivagor; 01.01.2016 в 15:51. Причина: исправил опечатки и ошибки
весьма вероятно что это так, но цифры уж очень близки к версии для 8080, поэтому думаю что это именно весьма неоптимизированная версия, при равной частоте с 8080, должна получаться версия быстрее для 6502.
память можно рассматривать и как массив байт и как массив бит, другое дело что обращение к памяти как к массиву бит потребует накладных расходов, тут нужно внимательно смотреть сколько выигрываем и сколько проиграем в производительности и объеме памяти.
В дополнение старый список инструментов для компиляции программ под ретропроцессоры
http://www.z80.info/z80sdt.htm
увы ни исходника tasm, ни версию для linux, я не нашел, но зато нашел другой ассемблер и тоже управляемый таблицами и причем с исходными кодами самого ассемблера:
http://www.penguin.cz/~niki/tdasm/
думаю будет полезен и для Z80, тем более что таблица (хотя и неполная) для z80 прилагается, а полные таблицы и отсутствующие таблички можно попробовать портировать для tdasm из архива tasm, но форматы таблиц различны.
PS. В целом мне кажется tdasm не дотягивает до уровня tasm, поэтому ищу исходники или версию tasm под linux дальше.
еще наткнулся на vasm, тоже достоен внимания http://sun.hasenbraten.de/vasm/index.php?view=relsrc
Последний раз редактировалось perestoronin; 01.01.2016 в 16:04.
Ретрокладовая продажи
Мой код начинает работать с R<B, и на каждом шаге остаток удваивается с добавлением очередного бита делимого, после чего к нему либо прибавляется либо вычитается B, чтобы |R| оставался меньше B, а далее можно обрабатывать следующий бит. Если B<2^15, то |R|<2^15 на каждом шаге, и после удвоения переполнения произойти не может, а условный переход требуется только чтобы отследить момент, когда сложение с B нужно заменить вычитанием. А вот если |R|>=2^15, то здесь требуется дополнительное ветвление, чтобы правильно отследить знак после добавления/вычитания B.
В версии для 8080 "удвоенное" количество кода вызвано отсутствием команды HL=HL+RP+флаг переноса. В вариантах для 8085 и z80 код почти как у Вас, только с переходами по переносу, а не знаку.
- - - Добавлено - - -
Поправлюсь - на каждый бит делимого
- - - Добавлено - - -
Уф, это я опять про делимое, а не про делитель. Максимальный делитель для 1000 - 6999, для 100 - 699. Не думаю, что это можно использовать для сокращения процедуры при расчете 1000 или 100 цифр. Вот если бы делимое, которое я как раз имел в виду, тогда другое дело.
Последний раз редактировалось ivagor; 01.01.2016 в 16:01.
Я скачивал с официальной странички, сейчас уже не открывается, но есть в веб-архиве.
а другие на ретро-железках еще и деньги зарабатывают, с каждой копии своей программы по 100 сантиков:
http://www.cdadapter.com/cross32.htm
Вот нам и Licensing Best Practices в действии.
Последний раз редактировалось perestoronin; 01.01.2016 в 16:31.
Ретрокладовая продажи
8080 гадость конечно редкостная, но даже для него с делением не всё так плохо:
#define ADC8(a,b) do{a=(a&255)+(b&255)+C; C=a>>8; a&=255;}while(0)
#define ADD16(a,b) do{a=(a&65535)+(b&65535); C=a>>16; a&=65535;}while(0)
//BC - делитель, должен быть в диапазоне от 256 до 32768
//DE = -BC
//HL < BC - старшие два байта делимого
//SP - младший байт делимого расширенный нулём
//A - частное
//деление производится по формуле A=HL*256/BC; HL=HL*256%BC; HL+=SP; if(HL>=BC) {HL-=BC; ++A;}
void div_8080(int &hl, int &a, int &bc){
int sp=a;
int de=-bc;
int C=0;
ADD16(hl,hl); ADD16(hl,de); if(!C) goto A1;
S1: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A2;
S2: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A3;
S3: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A4;
S4: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A5;
S5: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A6;
S6: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A7;
S7: ADC8(a,a); ADD16(hl,hl); ADD16(hl,de); if(!C) goto A8;
S8: ADC8(a,a); ADD16(hl,sp); ADD16(hl,de); if(!C) goto A9;
S9: ADC8(a,0);
return;
A1: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S2;
A2: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S3;
A3: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S4;
A4: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S5;
A5: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S6;
A6: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S7;
A7: ADC8(a,a); ADD16(hl,hl); ADD16(hl,bc); if(C) goto S8;
A8: ADC8(a,a); ADD16(hl,sp); if(C) goto S9;
A9: ADD16(hl,bc);
return;
}
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)