Передовица » Макулатура » ИиО » Совместим ли 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, но отсутствие технических описаний этих систем не позволяет удостовериться в подобном положении дел.

* * *

Использование материалов проекта agatcomp без получения предварительного письменного разрешения agatcomp запрещено.


Почта для обратной связи: mail@agatcomp.ru


Живое общение по теме Агата: Telegram группа Agatcomp.


Накопленные знания и проекты: тематический ФОРУМ.


© 2004-2024 agatcomp.su / agatcomp.ru

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *