1 Отредактировано garnizon (21-01-2018 17:06)

Тема: Ошибки в ИКП-бейсике

Замечено что в ИКП-бейсике глючит функция VAL.

Если набрать программу (или запустить образ из вложения) :

5  PRINT "Нажмите две цифры"
10  GET A$: A =  VAL (A$)
20  GET B$: B =  VAL (B$)
30  PRINT A,B

Запускаем, нажимаем например 4,  потом 6

Получаем:

4.44444444e+16
6

т.е. первый раз функция VAL глючит, второй - нормально срабатывает.

Из-за этого например глючит игра ОХОТА НА ЛИС   - при нахождении последней лисы, сбрасывается в сообщение "Ошибочка вышла".

Как с этим бороться, реально ли поправить  это?

http://agatcomp.ru/Apps/Agatbasic.shtml

Post's attachments

Attachment icon 19_09_95b.dsk 840 kb, 269 downloads since 2018-01-06 

2 Отредактировано avivanov76 (29-08-2021 18:34)

Re: Ошибки в ИКП-бейсике

Собрался уже после этой темы http://forum.agatcomp.ru//viewtopic.php?id=148 долго и беспросветно копаться в Бейсике, но мне повезло удачно этот баг загуглить.
Вот тут есть дизассемблированный листинг Applesoft Бейсика с комментариями http://www.txbobsc.com/scsc/scdocumentor/

Нужный нам кусок - здесь: http://www.txbobsc.com/scsc/scdocumentor/E597.html
Это функция VAL, адрес $E707 (в ИКП Бейсике девятки - $E6C7).

Как видно, перед конвертированием строки в ее конец принудительно записывается нулевой байт.
Вообще, в Бейсике строки хранятся с указанием адреса и длины. Но внутренние алгоритмы (видимо для экономии на счетчике) используют C-шный формат, и для этого в конец строки принудительно прописывается нулевой байт. Тот байт, который был на месте нуля, сохраняется в стеке.

Вот только есть одна проблема. Данные переменной A$ начинаются с адреса $BFFF и занимают 1 байт. Угадайте, куда запишется нулевой байт? Правильно, в $C000.

Дальше внутренние процедуры обработают введенный символ из $BFFF, а потом вместо нуля из $C000 прочтут последний введенный символ из регистра клавиатуры. И так пройдут по всем адресам $C000-$C00F. Получив в нашем случае строку из 17 повторов последнего символа.

Потом эти процедуры прочитают адрес $C010, а там - не цифра. Парсинг остановится.
Так что бага унаследована от Applesoft. В Apple она не проявляется - когда DOS загружен, рабочая область Бейсика заканчивается на $9600 и проблем не возникает. Но ИКП-шный Бейсик использует всю память от $1900 до $BFFF и бага проявляется.

* Интересно, что на семерке такого эффекта нет - там регистр клавиатуры чистится сам, и процедура парсинга получит свой нуль.

Вылечить такое поведение ИКП-шного Бейсика можно командой

HIMEM:-16385

Либо можно в самом начале программы завести неиспользуемую строковую переменную и присвоить ей что-нибудь (но не пустую строку, конечно).

3

Re: Ошибки в ИКП-бейсике

Аплодисменты в студию ! :)))

4

Re: Ошибки в ИКП-бейсике

Бурные и продолжительные аплодисменты звучат из Загорска!

5 Отредактировано vvhitevvizard (30-08-2021 14:53)

Re: Ошибки в ИКП-бейсике

Интересная находка!

avivanov76 пишет:

Вот тут есть дизассемблированный листинг Applesoft Бейсика с комментариями http://www.txbobsc.com/scsc/scdocumentor/

И спасибо за листинг Applesoft Бейсика с очень КАЧЕСТВЕННЫМИ комментариями, собранными из разных мест!!, что само по себе бесценно.

В нем автор выделил (<<<) несколько других багов и мест для улучшений, что может быть интересно и для изучения Агатовских Бейсиков:
I have flagged about a half dozen bugs in the listing, and several areas of very "improve-able" code. These are marked with "<<<" and ">>>" at each end of the comment lines.


До кучи, может кому будет полезно: "Системный монитор" Apple ][ с комментариями. В виде одного .asm файла.
http://www.easy68k.com/paulrsm/6502/MON.TXT
----
И еще о том, cколько всего версий Microsoft 6502 Бейсика (Apple, Commodore итд) и какие правки/оптимизации делались (включая исходник для компиляции всех этих версий):
https://www.pagetable.com/?p=46

6 Отредактировано Voldemar0 (28-03-2023 07:51)

Re: Ошибки в ИКП-бейсике

Сейчас прислали интересную багу бейсика (повторяется в Бейсика-60, ИКП-Бейсик-7 и Basic Master 95):

"4E" с любой последующей цифрой интерпретатор понимает как 40.
Без последующей цифры - как "4". Никаких сообщений о синтаксической ошибке.

]?4E                            
4      
       
]?4E6  
40     
       
]?4E4  
40     
       
]?4E0  
40

]?4E+0 
4

]?4E+1
40

]?4E+2 
400

]?4E+3 
4000

]?4E+4 
40000

]?4E-4 
4E-04

Попробовал в РАПИРе - там нормально всё: 4E+3 или 4E3 :

#BЫBOД:4E+3;                   
4000.0

7

Re: Ошибки в ИКП-бейсике

Смешная бага. Вернее, не бага, а фича.

Сначала я подумал, что тут что-то не то с преобразованием строки в число (процедура FIN в Бейсике Apple ][). Но код ее выглядит в ИКП-7 точно так же, как и в Apple.

Кроме того, я посмотрел содержимое буфера входной строки после выполнения команды ]?4E6.
В Apple оно такое:

200: BA 34 45 36 00 ; ?4E6.

А в ИКП-7 такое:

200: BA 34 01 02 00 ; ?4...

Что это значит, сразу я не понял и решил, что дело в процедуре PARSE.INPUT.LINE, которая подготавливает введенную строку к выполнению. Проблема в том, что эту процедуру в ИКП-7 не просто перенесли в другой банк ПсевдоПЗУ, но и переписали заново, с учетом всех дополнительных фич (ассемблера и т.п.). Поэтому сравнивать ее с Бейсиком Apple ][ бесполезно: отличий слишком много.

Тогда я задумался, а не принимает ли Бейсик эту запись за что-то другое?
Набрал

]?E6

Бейсик ответил мне:

]0

Ага! А что, если так?

]E6=10
]?E6

И Бейсик ответил:

]10

То есть, в данном случае E6 понимается как имя переменной. Ее начальное значение 0, поэтому команду ?4E6 Бейсик воспринимает как печать числа 4 и переменной E6.

8

Re: Ошибки в ИКП-бейсике

Че-то в припоминаю в старых книжках было такое: аргументы оператора print должны быть разделены либо запятой, которая будет заменена символом табуляции, либо точкой с запятой, которая ни в каком виде не будет отображаться. Точка с запятой в конце вывода запрещает вывод символа перевода строки.
Также и вариант оператора INPUT с подсказкой: строка-подсказка должна быть отделена от имени вводимой переменной (или от списка вводимых переменных) точкой с запятой.
Это было формальное описание в каком-то бейсике.

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

Век живи, век учись...