≡ Передовица » Макулатура » ИиО » Совместим ли soft ?
Совместим ли soft ? (N6/1994)С.В. Фролов, Санкт-Петербург С момента выпуска ПЭВМ «АГАТ» и по настоящее время создано большое количество версий системы программирования БЕЙСИК, в которых точки входа в подпрограммы различны. Кроме того, существуют и системы, отличные от БЕЙСИКа, такие, как система «Школьница», «Best tool kit», «Onix» и др. Программы, в которых есть ссылки на подпрограммы в области ПСЕВДО-ПЗУ, обычно используются для какой-либо одной системы и не будут работать в другой. В заметке А. Кривцова «Агат в образовании 1983-1987» (ИНФО. 1988. N 2. С. 29) обещано, что «соответствие основных точек входа интерпретатора БЕЙСИКа-60 и БЕЙСИКа-67 предполагается опубликовать в ближайших номерах», однако такое соответствие опубликовано не было. Вместе с тем работа по написанию программ, адаптация их с ПЭВМ «APPLE II» побудили меня самостоятельно составить такую таблицу, которая позволит читателям использовать опубликованные программы на своих компьютерах и адаптировать программы, написанные для других диалектов БЕЙСИКа. Небольшое пояснение к таблице. По вертикали расположены более или менее стандартные названия подпрограмм, по горизонтали - названия систем программирования, для которых сопоставлены адреса. Примечания1) АГАТ - системный монитор, входящий в стандартное ПЗУ и работающий сразу после включения ПЭВМ. 2) Система BASIC-67 распространялась также с адресами монитора типа BASIC-60. 3) СЕТЕВ. - «Сетевой» БЕЙСИК (включён в систему ИКП). 4) T.KIT - отладчик под названием «BEST TOOL KIT 89.2 и 89.3», автор А. Голов. 5) Акк. - регистр аккумулятора. 6) Действие подпрограмм может незначительно отличаться в разных диалектах. ------------------------------------------------------------ ! ! АГАТ !BAS-60!BAS-67!СЕТЕВ.!APPLE !РАПИРА!T.KIT ! !---------+------+------+------+------+------+------+------! !BASCALC ! FB7D ! FB8E ! FB26 ! FB2D ! FBC1 ! 1AF4 ! D969 ! !BELL ! FCA5 ! FCB4 ! FF3D ! FF3D ! FF3A ! 19A4 ! D89B ! !BS ! FC23 ! FC1F ! FC21 ! FC21 ! FC10 ! 1915 ! D81F ! !CLEOP1 ! FC49 ! FC4B ! FC4F ! FC4F ! FC46 ! 1952 ! D85C ! !CLEOP ! FC45 ! FC47 ! FC4B ! FC4B ! FC42 ! 194E ! D858 ! !CLREOL ! FC05 ! FC0C ! FCA5 ! FCA5 ! FC9C ! 198D ! D288 ! !COUT ! FDD4 ! FDDC ! FDE0 ! FDE1 ! FDED ! 18C6 ! D7E0 ! !COUT1 ! FDD7 ! FDDF ! FDE3 ! FDE4 ! FDF0 ! 18C9 ! D7E3 ! !CR ! FC5B ! FC67 ! FC6B ! FC6B ! FCB2 ! 1964 ! D86F ! !CROUT ! FD75 ! FD8E ! FD92 ! FD92 ! FD8E ! 18C4 ! D7DE ! !CROUT1 ! FD45 ! FD89 ! -- ! -- ! FC48 ! 18C1 ! D7DB ! !GETLN ! FD55 ! FD6E ! FD72 ! FD72 ! FD6A ! 1877 ! D4CB ! !GETLNZ ! FD4F ! FD6B ! FD6F ! FD6F ! FD67 ! 1874 ! D4C8 ! !HOME ! FC3B ! FC3D ! FC41 ! FC41 ! FC58 ! 1946 ! D850 ! !INIT ! FB3C ! FBED ! FBEF ! FBEF ! FB2F ! 1AAE ! D93F ! !KEYIN ! FD07 ! FD0D ! FD11 ! FD11 ! FD1B ! 1813 ! D504 ! !LF ! FC5F ! FC6B ! FC6F ! FC6F ! FC66 ! 1980 ! D87C ! !PRBYTE ! FDC1 ! FDC9 ! FDCD ! FDCE ! FDDA ! 18EC ! D953 ! !PRHEX ! FDDA ! FDD2 ! FDD6 ! FDD7 ! FDE3 ! 18F5 ! D95C ! !RDCHAR ! FB66 ! FB7A ! FB80 ! FB74 ! FD35 ! 1ADD ! D549 ! !RDKEY ! FD04 ! FD0A ! FD0E ! FCCB ! FD18 ! 1810 ! D501 ! !REASS ! FE60 ! FE5E ! FE5E ! FE63 ! FE5E ! -- ! E1D6 ! !RESET ! FA48 ! FA48 ! FA4C ! FA51 ! FA62 ! 1806 ! 0384 ! !SCROLL ! FC69 ! FC75 ! FC79 ! FC79 ! FC70 ! 19FA ! D8D9 ! !SETINV ! FE77 ! FE75 ! FE75 ! FE7A ! FE80 ! 19F7 ! D8AF ! !SETNORM ! FE7B ! FE79 ! FE79 ! FE7E ! FE84 ! 19BD ! D8B4 ! !SETTXT ! FB2E ! F846 ! F846 ! F846 ! FB39 ! 1AA1 ! D7CF ! !TABV ! FB50 ! FBFF ! FC01 ! FC01 ! FB5B ! 1ABF ! D94E ! !UP ! FC27 ! FC33 ! FC37 ! FC37 ! FC1A ! 1929 ! D833 ! !VTAB ! FC2F ! FC5B ! FC5F ! FC5F ! FC22 ! 1931 ! D83D ! !VTABZ ! FC31 ! FC5D ! FC61 ! FC61 ! FC24 ! 1933 ! D83D ! !WAIT ! FB94 ! FB2F ! FB94 ! FB94 ! FCA8 ! 1B07 ! D98E ! ------------------------------------------------------------ Пояснения и использование подпрограммBASCALC - позиционирование курсора (номер строки в Акк.) на начало строки; BELL - вывод звукового сигнала «БИП»; BS - перемещение курсора на одну позицию влево; CLEOP - очищает экран от курсора до конца экрана; CLEOP1 - то же, но координаты X и Y помещены в Акк. и рег. Y соответственно; CLREOL - очистка экрана от курсора; COUT - выводит символ из Акк. на устройство вывода (обычно - JMP COUT1); COUT1 - выводит символ на текущую позицию экрана; CR - переводит курсор на начало следующей строки; CROUT - передаёт символ $8D подпрограмме COUT, CROUT1 - то же, но с предварительной очисткой экрана до конца строки; GETLN - вводит строку символов; GETLNZ - то же, но с предварительным переходом на новую строку; HOME - очищает экран и переносит курсор в левый верхний угол; INIT - инициализирует параметры экрана (границы, размер и пр.); KEYIN - берет входной символ; LF - переносит курсор на строку вниз; PRBYTE - печатает шестнадцатеричный байт (значение в Акк.); PRHEX - печатает младший полубайт из Акк. как одну 16-ричную цифру; RDCHAR - то же, что KEYIN, но воспринимает управляющие коды (стрелки и др.); RDKEY - ввод символа с устройства ввода (обычно JMP KEYIN); REASS - вывод 28 строк в мнемокоде ассемблера; RESET - обработка реакции на клавишу УПР-СБР; SCROLL - сдвигает экран на одну позицию вверх и очищает нижнюю строку, на которую помещается курсор; SETINV, SETNORM - устанавливает инверсный и нормальный режимы соответственно; SETTXT - устанавливает и включает текстовый режим с адресом начала экрана, старший байт которого расположен в яч. $19; TABV - помещает курсор на строку, номер которой находится в Акк.; UP - перемещает курсор на строку вверх; VTAB - перемещает курсор на начало текущей строки; VTABZ - то же, но номер строки находится в Акк.; WAIT - выполняет задержку длительностью (5*Aкк.*Акк+27*Акк.+26)/2 мкс. Показанная выше таблица свидетельствует о том, что программы, в которых будет использовано непосредственное обращение к адресам системы, будут работать только в одной этой системе. Поэтому для того, чтобы программы могли работать в других системах, в них следует использовать подпрограммы ввода/вывода, написанные самостоятельно. Предложенные ниже подпрограммы, написанные на языке ассемблера для ПЭВМ «АГАТ», я использую практически во всех своих программах как базовые. Перед программами дан пример, который на экране демонстрирует их возможности. (Листинги компилируются в ассемблере системы «Школьница» или «ИКП».) ORG $2800 начало программы OBJ $2800 адрес размещения в памяти ассемблера LST OFF выкл. вывод на экран листинга DSECT; ORG $D0 ; ячейки нулевой страницы ; BASL DS 1 \ BASH DS 1 / вместе, не разъединять BAS2L DS 1 \ BAS2H DS 1 / вместе, не разъединять ; ; ниже ячейки могут быть не в нулевой странице ; YSAV DS 1 XC DS 1 YC DS 1 рабочие ячейки XSAV DS 1 SAV0 DS 1 INVFLG DS 1 номер цвета ВЫСОТА DS 1 ДЛИТЕЛ DS 1 CH DS 1 коорд. X*2 CV DS 1 коорд. Y DEND TXPAGE EQU $1000 начало текстовой страницы ; (обычно бывает равно $7800) НАЧАЛО STA $C70A включение экрана с адреса $1000 ; для экрана с $7800 - STA $C73E JSR RAMKA вывод рамки DFB 30 ширина DFB 30 высота DFB 0 коорд. X DFB 0 коорд. Y DFB 4 цвет синий JSR PRINT вывод надписи DFB 0 признак ввода координат DFB 18 коорд. X DFB 2 коорд. Y DFB 3 цвет жёлтый ASC .**. вывод звёздочек DFB 6 цвет голубой ASC .ЗАГОЛОВОК. DFB 3 цвет жёлтый ASC . **. выведена надпись: ** ЗАГОЛОВОК ** DFB 0,4,29 новые координаты DFB 7 цвет белый ASC :C.ФРОЛОВ V0.0 1993 <F34MS>: DFB $81 конец вывода текста JSR RAMKA вывод второй рамки DFB 21,5,8,12,5 параметры рамки JSR PRINT вывод надписи во второй рамке DFB 0,12,15,3 новые координаты ASC .НАЖМИТЕ КЛАВИШУ. DFB 1 цвет красный ASC .РЕД. DFB $81 конец вывода МЕТКА JSR KEY ожидание ввода клавиши CMP #$9B код клавиши РЕД ? BNE МЕТКА JSR HOME.. очистка экрана RTS выход ;----------------------------------------- **-ПОДПРОГРАММЫ-** ;-Рисование рамки-* ; ; Формат вызова: ; ;JSR RAMKA ;DFB ширина рамки (кол-во пробелов внутри рамки) до 30 (62) ;DFB высота рамки до 30 ;DFB координата X левого верхнего угла рамки ;DFB координата Y ;DFB цвет рамки RAMKA PLA сохранение адреса возврата STA BAS2L PLA STA BAS2H LDY #1 LDA (BAS2L),Y считывание байта из программы STA XC (параметры) INY LDA (BAS2L),Y STA YC INY LDA (BAS2L),Y TAX INY LDA (BAS2L),Y PHA INY LDA (BAS2L),Y PHA TYA вычисление адреса обратного перехода SEC (на адрес сразу за параметрами) ADC BAS2L STA BAS2L BCC RAMKA.4 INC BAS2H RAMKA.4 PLA STA SAV0 PLA TAY LDA SAV0 JSR BASCALC1. перенос курсора в левый верхний LDA YC угол рамки BEQ RAMKA.2 LDA #'' или символ левого верхнего угла (для АГАТ-9) JSR COUT вывод символа LDA #'' или символ горизонтальной черты LDX XC LDY CH JSR POVTOR. вывод горизонтальной черты LDA #'' или символ правого верхнего угла JSR COUT вывод символа DEY DEY STY CH RAMKA.1 INC CV переход на следующую строку JSR BASCALC.. LDA #'' или символ вертикальной черты JSR COUT LDA INVFLG PHA LDA #$23 цвет заполнения внутри рамки STA INVFLG LDX XC LDA #'' или символ заполнения внутри рамки LDY СН JSR POVTOR. вывод строки из символов заполнения PLA STA INVFLG LDA #'' или символ вертикальной черты JSR COUT вывод символа вертикальной черты DEY DEY STY CH DEC YC повторять, пока не будет выведена BNE RAMKA.1 вертикальная часть рамки INC CV JSR BASCALC.. LDA #'' или символ левого нижнего угла JSR COUT LDA #'' или горизонтальный символ LDX XC JSR POVTOR. вывод нижних горизонтальных символов LDA #'' или символ правого нижнего угла JSR COUT RAMKA.2 LDA INVFLG начало вывода звука AND #$F EOR #$F ASL A ASL A ASL A LDY #8 JSR PIC вывод небольшого звука (можно убрать) RAMKA.3 JMP (BAS2L) -RTS ;------------------------------ **-Очистка экрана-** ; Точки входа: ; HOME - очистка экрана текущим цветом ; HOME. - цвет символов в Акк. ; HOME.. - цвет символов - $23 (нормальный, жёлтый) HOME.. LDA #$23 номер цвета HOME. STA INVFLG HOME LDA #<TXPAGE адрес начала текстовой (графической) STA BASH страницы LDX #8 количество страниц очистки (20 для графики) LDY #0 STY BASL HOME.1 LDA #$A0 символ очистки (=0 для графики) STA (BASL),Y INY LDA INVFLG * цвет для очистки (* помечен код, STA (BASL),Y * который следует исключить для графики) INY * и режима 64*32 BNE HOME.1 INC BASH DEX BNE HOME.1 RTS ;-------------------------- **-Вычисление адреса-** Точки входа: ; BASCALC - координаты в регистрах X и Y. Адрес точки ; помещается в ячейки BASL,BASH (мл.,ст.) ;BASCALC. - то же, но координаты берутся из ячеек ; CH и CV (X и Y соответственно) ;BASCALC.. - то же, что BASCALC., но в BASL, BASH помеща- ; ется адрес начала строки и далее можно ; выводить символы подпрограммой COUT ;BASCALC1 - то же, что BASCALC.. ,но координаты X и Y ; сохраняются в ячейках CH и CV ;BASCALC1.. - то же, что BASCALC1, но дополнительно из ; Акк. сохраняется номер цвета BASCALC1. STA INVFLG BASCALC1 STX CH STY CV BASCALC.. LDX #0 DFB $2C BASCALC. LDX CH LDY CV BASCALC TYA AND #$1F STA BASH LDA #$00 LSR BASH ROR A LSR BASH ROR A STA BASL LDA #<TXPAGE ADC BASH STA BASH TXA ADC BASL STA BASL RTS ;----------------------------- **-Ввод символа-** ; ;Вводит символ с клавиатуры без курсора и без ;декодирования русской клавиатуры KEY STA $C010 очищаем строб LDA $C000 берём код из буфера клавиатуры, BPL *-3 пока он не станет больше $80 RTS ;------------------------------ **-Вывод сообщения-** ; ;Выводит строку сообщения сразу после команды ;обращения до кода $81 (УПР-А или клавиша f0) ;после кода 0 в следующих двух байтах вводится ;новая координата X*2 и Y ; ; JSR PRINT ; DFB 0,12,22 переход на позицию 6/22 ; ASC .Текст сообщения. ; DFB $81 PRINT PLA принцип действия такой же, как STA BAS2L и подпрограммы RAMKA PLA STA BAS2H LDY #1 PRINT.1 LDA (BAS2L),Y BNE PRINT.4 INY LDA (BAS2L),Y TAX INY LDA (BAS2L),Y STY YSAV LDY #$C6 LDY #$D2 LDY #$D3 TAY JSR BASCALC1 LDY YSAV JMP PRINT.5 PRINT.4 CMP #$81 BEQ PRINT.2 JSR COUT PRINT.5 INY BNE PRINT.1 PRINT.2 TYA SEC ADC BAS2L STA BAS2L BCC PRINT.3 INC BAS2H PRINT.3 LDX XSAV JMP (BAS2L) ;------------------------ **-Вывод символа-** ;Выводит символ из аккумулятора в ячейку памяти с ;адресом (BASL)+CH - в BASL - адрес начала строки ;CH - координата по X (удвоенная) ;Если в Акк. число, меньшее $10, то оно воспринима- ;ется как номер цвета для вывода следующих символов, ;причём если номер 8, то он инверсный (-8), а ;если 8, то нормальный COUT PHA CMP #$10 символ <$10? BCC COUT.2 да, это цвет, переход STY YSAV LDY CH коорд. X STA (BASL),Y вывод INY LDA INVFLG цвет STA (BASL),Y вывод INY STY CH сохранение новой коорд. X LDY YSAV COUT.RTS PLA RTS COUT.2 CMP #8 BGE COUT.3 ORA #$20 STA INVFLG сохранение нормального цвета PLA RTS C0UT.3 SBC #8 STA INVFLG сохранение инверсного цвета PLA RTS ;-------------------------- **-Пик-генератор-** ; ; Выводит обычный звуковой сигнал PIC STA ВЫСОТА STY ДЛИТЕЛ LDY #0 P2 LDX ВЫСОТА STA $C030 P3 DEY BNE P4 DEC ДЛИТЕЛ BEQ P5 P4 DEX BNE P3 BEQ P2 P5 RTS ;----------------------------- *-Вывод шестнадцатеричного байта (из Акк.) PRBYTE PHA JSR OBRAB.1 JSR COUT PLA PRHEX JSR OBRAB.2 JMP COUT OBRAB.1 LSR A LSR A LSR A LSR A DFB $2C OBRAB.2 AND #$F ORA #$B0 CMP #$BA BCC OBRAB.1A ADC #6 OBRAB.1A RTS ;-------------------------- *-Повтор символа ; X - количество символов ; Акк - символ ; Y - номер цвета POVTOR STY INVFLG POVTOR. JSR COUT DEX BNE POVTOR. RTS
От Agatcomp:
Многие операционные системы и системы программирования "Агата" строились по близким схемам и часто содержали общие элементы, исходные тексты которых вели свою историю от самого создания машины и распространялись, порой, вместе со стандартным программным обеспечением. Как минимум, существовало три таких элемента: RWTS (Read/Write Track/Sector - драйвер дисковода), IOSub (Input/Output Subroutines - драйвера текстового режима дисплея, клавиатуры, звукового канала и ещё некоторой мелочи. IOSub входит в системный монитор, хранимый в ПЗУ, но т.к. ПЗУ может быть недоступно при загруженной операционной системе, то на него полагаться можно не всегда), DOS (я даже не знаю - как именно ЭТО назвать, но функционально это был высокоуровневый драйвер файловой системы - т.е. он преобразовывал операции открытия/чтения/записи/закрытия файлов в обращения к драйверу дисковода). Очевидно, что будучи скомпилированы из общих исходников, функционально эти подсистемы были очень близки. Но так как никто из разработчиков особенно не стремился сделать единый API (т.е. интерфейс для сторонних - не своих - программ), то программисты, желавшие использовать эти процедуры, вынуждены были вызывать их по абсолютным адресам, которые "двигались" от версии к версии. Здесь было три варианта. Первый: разрабатывать программы именно под ту систему, которая есть лично у тебя (всё равно особых перспектив распространения своих программ не было, если не считать отправляемые почтой дискеты). Этот способ казался особенно очевидным в связи с крайне скудной информацией о существовании и особенностях других систем. Второй вариант: выпускать отдельные версии программ для каждой комбинации операционной системы и Бейсика, просто включая в исходный текст таблицы адресов используемых процедур и применяя условную компиляцию. Вот, собственно, эти таблицы автор и приводит в статье (только для IOSub). Здесь же предлагается и третий вариант: встраивать нужные подсистемы в собственные программы. Из тех же исходников (или придумывая на их основе собственные). До настоящего времени между разработчиками программ для "Агата" так и не была достигнута договорённость о едином способе определения версии операционной системы выполняющейся программой. Возможно, что какой-то способ был реализован в поздних ОС, вроде Спрайт-ОС или Onix, но отсутствие технических описаний этих систем не позволяет удостовериться в подобном положении дел. * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |