Разработка мобильного программного обеспечения для ЭВМ линий 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). С ее помощью можно определять, например, была ли нажата клавиша
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, либо из программы соответствующим запросом. Кроме того, при нажатии клавиши
Аналогично системе Turbo-Pascal можно определить процедуры CRTINIT и CRTEXIT инициализации и завершения работы с терминалом. В ОС TSX-Plus здесь можно было бы ввести установку режима ввода одиночных символов, подавление символа
В ОС 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(О) ) ;
(♦ подавить символ
(• определить и запомнить тип используемого терминала ♦ ) 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 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 средств раздельной компиляции модулей позволяет разрабатывать мобильные средства расширения стандарта языка. Разработка ПО на едином языке высокого уровня, обладающем явными достоинствами с точки зрения программотехники, может существенно сократить усилия и время коллективов программистов, одновременно гарантируя высокую надежность создаваемого ПО .