Разработка мобильного программного обеспечения для ЭВМ линий PDP-11 и VAX

Автор: Брусиловский Л.И., Михайлов Ю.А.

Журнал: Компьютерная оптика @computer-optics

Рубрика: Автоматизация проектирования

Статья в выпуске: 7, 1990 года.

Бесплатный доступ

Рассмотрен вопрос разработки мобильного программного обеспечения для ЭВМ линий PDP-11 и VAX. В качестве инструментальной предлагается использовать мобильную систему программирования "Pascal-2". Приведена реализация примитивов "нижнего уровня", с помощью которых можно создать инструментальные средства, адекватные имеющимся в системе программирования "Turbo-Pascal".

Короткий адрес: https://sciup.org/14058209

IDR: 14058209

Текст научной статьи Разработка мобильного программного обеспечения для ЭВМ линий PDP-11 и VAX

,<#CH,«1>

MOVE CH,C(SP)

ENDRR .END

В ОС RSTS/E этот модуль также реализуется на самом Pascal-2;

function GETC: char; external;

function GETC;

(♦ Get immediately one character from keyboard (RSTS/E version) ♦)

var C: char;

begin ENT(255); EMT(18); <• отменить эхосопровождение *) ENT(255); ENT(2u>; (• посимвольный ввод ♦) read(C);

GETC:-C

ENT(255); EMT(16>; (♦ восстановить эхосопровождение ♦ ) end;

Ниже все модули, зависящие от конкретной ОС будут приводиться на ассемблере для ОС TSX-Plus и RSX-11M. В ОС RSTS/E все модули могут быть реализованы средствами самого языка Pascal-2 с использованием системных вызовов [17].

С точки зрения эффективности использования клавиатуры видеотерминала важным является модуль определения наличия символа для ввода в буфере ввода (в Turbo-Pascal это функция KEYPRESSED). С ее помощью можно определять, например, была ли нажата клавиша или какая-либо из функциональных клавиш (нажатие функциональной клавиши приводит к передаче в буфер терминала символа и еще одного или нескольких символов - так называемой ESC-последовательности). Реализация функции KEYPRESSED для ОС TSX-Plus может иметь вид:

function KlyPRESseD: oooiean: external:

викякь:

-BYTE 0.123 . Т1 i LE KE YPRESSED

FUNC    KEYPRESSES,YES,BOOLEAN

SAVE    

BEGIN CURB    YESISP)

MOV     BBLKARb.Ru

EMT     375

BCS     IP

INCB    YESlSP)

10S

ENDPR .END

Аналогично для ОС RSX-11M:

.TITLE KEYPRESSED

.MCALL QIOW«S,TTSYMA

BLKARG:

.BYTE TC.TBF.O FUNC    KEYPRESSED,YES,SCALAR

BEGIN TTSYMS

UIUNAS #SF.GMC.#5,#5,,,,4«BLKARG,#2> CLRB    YES(SP)

TSTB    BLKARG+1

BEU     1Й

INCB    YESISP)

1Й:

ENDPR .END

В ОС TSX-Plus и RSX-11M для правильной интерактивной работы необходимо установить характеристики терминала. Например, в ОС TSX-Plus режим ввода одиночных символов можно установить из монитора, запустив программу командой RUN/S, либо из программы соответствующим запросом. Кроме того, при нажатии клавиши в программу обычно передаются два символа: и . Добавление символа можно подавить соответствующей установкой режима терминала. Кроме того, в составе ЭВМ линии PDP-11 и VAX могут работать терминалы различного типа, поэтому 8 модуле инициализации работы с терминалом желательно динамически (т.е, при запуске программы) определить тип терминала, с которым предполагается работа. Поскольку эта информация важна в дальнейшем, тип терминала можно запомнить в программе для повторного использования.

Аналогично системе Turbo-Pascal можно определить процедуры CRTINIT и CRTEXIT инициализации и завершения работы с терминалом. В ОС TSX-Plus здесь можно было бы ввести установку режима ввода одиночных символов, подавление символа после нажатия и определение типа используемого терминала, В ОС RSTS/E здесь можно было бы выполнять установку таких функций терминала, как LC INPUT, LC OUTPUT, ESC, ESCSEQ и т.д.

В ОС TSX-Plus установление спецрежимов терминала можно выполнить с помощью нижеприведенной процедуры SETTERM:

(♦nomain») (♦own*> type iERHTYPE = 1UNKNUWN. VT52, VTlUU. HAZELTINE. HDM3A.

LA3o, LA12U, D1ABlD_AND_QUME, RESERVED, VT2UU): var ITEMTYP : IERMTYPE <• переменная, в которой хранится тип используемого терминала »>

■function TERMTYP: TERMTYPE; external;

■function TTYPE: TERMTYPE; external;

■function TTYPE;

(♦ вернуть тип используемого терминала ♦> begin

TTYPE:=1TERMTYP end;

procedure CRTINIT; external:

procedure SETTERM(FUNC, ARG:char); external;

procedure CRTINIT;

begin

(♦ установить режим посимвольной активации *) SETTERM(S',chr(О) ) ;

(♦ подавить символ после символа *) SETTERM( D',chr(13));

(• определить и запомнить тип используемого терминала ♦ ) ITERMTYP:-TERMTYP end;

procedure CRTEXIT; external;

procedure CRTEXIT;

be9iBETTERM( T',chr(O>);

end:

Процедура SETTERM на ассемблере может иметь вид:

; procedure SETTERM(FUNC, ARG:char>; external; BLKAR6: .BYTE 0,152

.BLEW 2 .TITLE SETTERM PROC SETTERM PARhM   FCODE,CHAR

PARAM ARGVAL,CHAR SAVE

MOVB    ARGVAL(SP),BLKARG+4

MOV , #BLKARG,RO EMT     375

ENDPR . спи

А процедура определения типа терминала TERMTYP:

; function TTYPE: TERMTYPE; external;

BLKAR6:

.BYTE   0,137

.TITLE  TTYPE

FUNC    TTYPE,TTY,SCALAR

SAVE    

BEGIN MOV     #BLKARG,RO

EMT     375

MOVB    RO,TTY(SP)

ENDPR .END

Результат, возвращаемый функцией TERMTYP, имеет следующий смысл:

О      UNKNOWN (неизвестный тип терминала)

1      VT52 (15ИЗ-000-013, ВТА-2000-3, ВТА-2000-15)

2      VT100 (ВТА-2000-1ОМ)

  • 3      HAZELTINE

  • 4       ADM3A

  • 5LA36

  • 6LA120

  • 7       DIABLO, QUME

  • 8      RESERVED

    9       VT200 (MC7105)

Функция определения типа терминала в ОС RSX-11M будет иметь вид (для обес печения мобильности полагаем, что тип TERMTYP тот же, что и для ОС TSX-Plus):

; Function TERMTYP: TERMTYPE; external;

.TITLE .MCALL

TERMTYP

QI0W6S,TTSYM6

BLKARG:

.BYTE

TC.TTP,0

FUNC

1ERMTYP,TTY,SCALAR

SAVE

BEGIN

TTSYM6

QION6S

#SF.6MC,#5,#5,,,,<#BLKARG,#2>

CLR

RO

MOVB

BLKARG+1, RO

BEQ

26

CMPB

#11,RO

В NE

16

MOVB

• 1 ,RO

BR

26

16:

CMPB

#15,RO

В NE

36

MOVB

#2, Ro

BR

26

36:

CLRB

RO

26:

MOVB

RO,TTY(SP>

ENDPR

.END

Тогда в ОС RSX-11M процедура CRTMOU может иметь аналогичный вид, за исклю чением того, что процедура CRTINIT должна выглядеть следующим образом:

procedure CRTINIT; external;

procedure CRTINIT;

begin reset(INPUT,’TI:/RALzNOECHO/BUFF:1 ):

rewrite(OUTPUT,'TI:/BUFF: 1 ' > s

1TERMTYP:«TERMTYP eno;

А для версии v2.0 в ОС RSX-11M:

procedure CRTINIT; external; procedure CKfINIT;

begin rewr1te(OUTPUT, TI:/BUFF:11;

1 IERMTYP:« TERMTYP end:

В СП Turbo-Pascal позиционирование курсора реализуется с помощью предопределенной процедуры GOTOXY (COL,ROW), где COL и ROW соответственно номера столбца и строки, в которые нужно переместить курсор. 8 Pascal-2 эту процедуру можно реализовать на самом Pascal:

( »nomain* 1

  • •. vpe ItRnlYHE = IUNKNOWN, VT52, Vi1UU, HAZELTINE, ABM3A, LA3b, LA12U. DIABLO AN1» QUME, RESERVED, VT2UU); function ttvpe: TERMTYPE; external;

procedure uuI OXY(COL,ROW:inteaer>; external;

procedure bOFOXY: const

EsC=15d; oeqin case FTyPE от

VT52 : write(cnr(Esui , ' Y , chr . chr(COL+31)>;

VT1OO : wr i te(chr(ESC#, ’ C ' , cnr((Huw div 101+481, chr((ROW mod 101+481,;’ chr((COL div 101+481, chr((COL mod 101+481, H 1;

end end;

Процедуры управления экраном в СП Turbo-Pascal: CLRSCR (очистка экрана), CLREOL (очистка ст курсора до конца строки), CLREOS (очистка от курсора до конца экрана), LOWVIDEO (снижение яркости), NORMVIDEO (нормальная яркость) можно реализовать следующим образом:

const

ЕБС=Юэ;

procedure CLRSCR; (* очистка экрана ♦! oeqin case FTYPE от

VT52 : wr1te(chr(ESC1, Е 1;

v11ии    : write(chr(ESC), '£2J i ;

eno eno;

procedure ulkEOL; i» очистка от курсора до конца строки ♦ > Degin case FTyPE of

VF52 : write(cnrlESC), К 1;

VT100    : write(chr(ESC),’СК 1;

eno eno; procedure CLREOS; <♦ очистка от курсора до конца экрана ♦) oegi п case TlYpt от

VT52 : wr1te(cnr(ESbi, j 1;

VTluO : writeicnrlESCl, CJ’l;

end eno:

Полный перечень управляющих кодов можно получить в соответствующем руководстве по аппаратному обеспечению терминалов.

  • 2.2.    ОБРАБОТКА СТРОК

Второй группой примитивов “нижнего" уровня является обработка строк.

СП Turbo-Pascal имеет ряд предопределенных процедур и функций для работы со строками. Аналогичные процедуры и функции имеются и в пакете STRING.PAS, вхо дящем в состав СП Pascal-2. В Turbo-Pascal и в пакете STRING.PAS СП Pascal-2 версии не ниже v2.1 длина ограничена 255 символами. Это обусловлено тем, что строка рассматривается как массив символов размерностью [0..255]» причем нулевой элемент массива используется для хранения текущей длины строки. Такое определение строки отличается от принятого в стандарте языка (нижняя граница массива равна 1), поэтому для присвоения строке некоторого значения при использовании пакета STRING.PAS необходимо обращаться к соответствующей процедуре. Другим серьезным недостатком такого подхода является ограничение на длину обрабатываемых строк в 255 символов, так как в ряде приложений это ограничение может оказаться критическим.

Кроме того, реализация Pascal-2 версии v2.1 так называемых согласованных массивов-параметров не допускает их использование в качестве фактических параметров, что резко сужает область применения механизма согласованных массивов для манипулирования со строками.

Универсальным решением будет являться подход, используемый при обработке строк с помощью подпрограмм и функций системной библиотеки SYSLIB: конец строки помечается специальным символом chr(O). Тогда длина строки равна количеству символов, встретившихся в строке до появления символа chr(O).

В принципе можно было бы воспользоваться этими модулями библиотеки SYSLIB, тем более, что наличие директивы nonpascal в языке Pascal-2 позволяет вызывать модули, написанные на других языках (например, на FORTRAN'e или ассемблере), однако фактические параметры непаскальных модулей должны передаваться по ссылке (с описателем var), что может опять создать проблемы, связанные с передачей в качестве параметров строк различной длины. Поэтому целесообразно реализовать модули на самом Pascal-2 и поместить их в библиотеку.

Для вызова этих процедур и функций можно использовать следующий метод. В качестве параметра-строки необходимо указать переменную типа integer, передаваемую по знамению (без var), а при вызове соответствующей подпрограммы в качестве фактического параметра задавать адрес строки, приведенный к типу integer что можно легко осуществить с помощью встроенных функций loophole и ref. Это позволяет передавать в подпрограммы строки различного размера. Системные процедуры и функции требуют, чтобы конец строки указывался нулевым байтом chr(O).

Например, если L - строка, описанная как L: packet array [1..81] of char;

то ее "обнуление" выполняется просто, как L [1]: = chr(0), вычисление ее текущей длины выполняется как function LENGTH

oegi n

eno:

а сама функция LENGTH может иметь вид:

i*nomain») tvpe

STRING = раскет array il.,811 o-f char; к верхняя граница не существенна *) ■function uENGTHtvar S; STRING); integer; external; function LENGTH; var

I ; integer; begin i:=u;

while SE1*1j<>chr10) do I;=l*l;

LENBin:=I end;

Аналогично программируются другие обращения к подпрограммам и функциям обработки строк.

  • 2.3.    УПРАВЛЕНИЕ ПАМЯТЬ»

Третья группа примитивов "нижнего" уровня - динамическое управление памятью. В версии Turbo-Pascal имеются еще две процедуры выделения и освобождения памяти из хипа: GETMEM и FREEMEM. В языке Pascal динамически может выделяться память только под объекты с фиксированными размерами. Во многих прикладных программах было бы удобно динамически выделять память под объекты, размер которых на этапе компиляции не известен, например, под массивы с переменными верхними границами. Все возможные значения верхней границы массивов можно было бы указать с помощью записи с вариантами, однако, это было бы слишком громоздким решением. Процедура GETMEM позволяет программисту управлять объемом выделяемой из хипа памяти. Процедура GETMEM имеет два параметра:

GETMEM (переменная, выражение);

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

FREEMEM (переменная, выражение);

выполняет обратную функцию - возвращает в хип память, выделенную процедурой GETMEM. Значение параметра "выражение" процедуры FREEMEM должно быть в точности равно параметру "выражение" соответствующей процедуры GETMEM.

В версиях Pascal-2, начиная с v2.1, реализованы внешняя функция Р#INEW и процедура РД DISPOSE, управляющие выделением и освобождением выделенной памяти из хипа. Здесь построение соответствующего аналога тривиально:

(«поташ*)

гуре

POINTER = integer;

function PblNEWlSIZE: integer): pointer; external;

procedure FftDlSPOSEiPTR; pointer; SIZE: integer); external;

procedure GETMEMtvar PTR: pointer; SIZE: integer); external;

t* extends new procedure to support allocation o-f variable length aggregates ♦> procedure GETMEM;

begin pTR:=pgINEW(SIZE)

ena:

procedure FREEMEMiP: pointer; SIZE: integer); external;

t* complements GETMEM procedure to support treeing o-f variable length aggregates ♦)

procedure FRtEMtn;

begin pdbiSPOSElP, SIZE)

end;

В версиях v2.0 реализация функции Р $ INEW и процедуры Р ^DISPOSE может выглядеть следующим образом:

tunction PblNEWlSIZE: integer): pointer; external;

FUNC hARhm BEGIN 1NL

B1L MOV

CALL .GlUBL MOV ENDPR . END

РйINEW, PTR,ADDRESS

SIZE,INTEGER

SIZE(SP)

W1,SIZE(SP)     :выделить четное число байтов

S1ZE(SP>,-lSP>

ЙВ7О

ЙВ70

; procedure PBDISPObElP: pointer; SIZE: integer); external

FUNC PARAM PARAM BEGIN

MOV INC BIC

MOV CALL

.GLOBL EnDPR .END

PADISPOSE P,ADDRESS SIZE,INTEGER

SIZE(SP),RO

RO

#1 .RO

P1SP),-(SP)

ЯВ72

ЯВ72

Эти две процедуры выделяются системно независимыми, т.е. справедливы для ОС RT-11/TSХ-Р I us, RSX-11M, RSTS/E и могут использоваться в любой из указанных ОС при работе с СП Pascal-2.

Полезной может оказаться функция MEMAVAIL, возвращающая разность между вершинами стека и хипа, т.е. объем доступной динамической памяти в байтах. В Pascal-2 эту роль выполняет внешняя функция SPACE

; tunction MEMAVAIL: integer; external;

  • •tunction SPACE: integer; external;

function MEMAVAIL: integer; external;

<* return value of memory available for allocation in bytes ♦) function MEMAVAIl; oegi n MEMAVAIl:=SPACE end:

Использовать вышеприведенные процедуры можно следующим образом. При входе в процедуру, в которой требуется выделить память под объект, размер которого задается, например, с помощью какого-либо параметра, необходимо вызвать про-ЦвДУРУ GETMEM, передав ей в качестве параметров локальную переменную, имеющую тип ссылки на такой объект, и фактический требуемый размер памяти в байтах под этот объект. Обращения к этому объекту после выделения памяти осуществляются с помощью переменной-ссылки. Перед выходом из процедуры выделенная динамически память освобождается с помощью процедуры FREEMEM. При необходимости размещения памяти под несколько подобных объектов следует вызвать процедуру GETMEM соответствующее число раз, а затем столько же раз и процедуру FREEMEM (желательно указать ссылки на объекты в порядке, обратном их порядку при вызовах процедуры

GETMEM). Другим вариантом может быть запоминание адреса вершины хипа перед выделением динамической памяти, а затем освобождение динамической памяти восстановлением старого значения вершины хипа с помощью процедуры RELEASE.

Например, пусть в процедуре А необходимо динамически выделить массив вещественных чисел, размер которого определяется параметром N:

type

ARR - array Cl..2J о* real;

l* верхняя граница не существенна ♦) PTR - 'ARR;

procedure A(Nt integer); external;

procedure SETMEMtvar P:PFR; SIZE: integer); external; procedure FREEMEMlvar P:PTR; SIZE: integer); external; procedure A; var P : PTR;

begin SETMEM1P,4*N); <• длина числа типа real = 4 байта ♦)

P'C I J: —P^'E 1-1 J + l. О; (* работа с динамическим массивом •)

end;

FREEMEM

  • 2.4.    ОРГАНИЗАЦИЯ ПАРАЛЛЕЛЬНЫХ ВЫЧИСЛЕНИЙ

Авторы в данной статье не ставили перед собой цель реализовать примитивы "нижнего" уровня, адекватные имеющимся в языке Modula-2, например, процедуры NEWPROCESS и TRANSFER. Это станет предметом следующих работ, в которых помимо СП Turbo-Pascal будет рассмотрена СП МiсгоРоыег/РаsсаI фирмы DEC, также являющаяся мобильной для линии PDP-11 и VAX средством разработки автономных программируемых контроллеров на языке Pascal, включающем поддержку мультипрограммирования. Авторы утверждают, что подобные процедуры могут быть построены и для СП Pasca1-2.

Выводы

Использование СП Pascal-2 позволяет разрабатывать мобильное программное обеспечение для ЭВМ линии PDP-11, VAX и IBM PC, большая часть которого может быть написана на языке Pascal. Примитивы, зависящие от типа операционной системы или версии СП, можно локализовать в отдельные модули, которые и будут подлежать переделке при переносе программного обеспечения из одной среды (ОС или версии СП) в другую. Наличие в СП Pascal-2 средств раздельной компиляции модулей позволяет разрабатывать мобильные средства расширения стандарта языка.

Разработка ПО на едином языке высокого уровня, обладающем явными достоинствами с точки зрения программотехники, может существенно сократить усилия и время коллективов программистов, одновременно гарантируя высокую надежность создаваемого ПО .

Статья научная