.; HELP file for Whitesmiths' C and Pascal compiler driver scripts. .; RUNOFF as it comes for C, with .VARIANT Pascal for Pascal. .; Requires Bonner Lab RUNOFF. .PS64,80.NOPAGING.RM78.nhy .; Starting a line with a null disables a / or digit, without affecting layout: .define escape "^[" HSP,0 0 .IF Pascal .define substitute/I$/P .define substitute/Lang$/Pascal .define substitute/typ$/PAS .define substitute/Cand$/C and .define substitute/files$/files, SOURCE__FILE.C and .define substitute/are$/are .define substitute/CVI$/PC .define substitute/CuI$/P .define substitute/Ecpp$/ .define substitute/cemV$/-cem .define substitute/cemu$/-cem 1 Pascal .ELSE Pascal .define substitute/I$/C .define substitute/Lang$/C .define substitute/typ$/C .define substitute/Cand$/ .define substitute/files$/file, .define substitute/are$/is .define substitute/CVI$/CVMS .define substitute/CuI$/C .define substitute/Ecpp$/Execution: .define substitute/cemV$/-c .define substitute/cemu$/ 1 C__compiler .ENDIF Pascal .flags substitute $ .nf Syntax: _$ $I$VMS [-o exe__file] source__file[ ...] .iifnot Pascal.i8;_$ $I$VMSD [-o exe__file] source__file[ ...] .i8;_$ $I$68K [-h] [-r] [-o exe__file] source__file[ ...] .i8;_$ $I$80 [-o exe__file] source__file[ ...] .f.p0 execute command procedures to invoke the Whitesmiths' $Lang$ compiler phases necessary to produce object and/or executable files from one or more source files. $I$VMS is for VAX native code, $I$68K for cross-compilation to run on a Motorola MC68000-series processor, and $I$80 for cross-compilation to an Intel 8080. .ifnot Pascal $I$VMSD compiles and/or links for VAX native use including the VAX-DEBUG debugger, and also produces a cross-referenced LINK map. .endif Pascal .rm76 2 Parameters .br source__file .p0 One or more $LANG$ or assembler source files, object files, or object libraries to be compiled and/or linked. The type of the file is determined from its filetype, which also affects its usage:- .s.nf.lm+5.ts14,22,41 native micro type action ------ ----- ---- ------ .IF Pascal default#or#PAS Pascal#source compiled C C C#source compiled .ELSE Pascal default#or#C C#source compiled .ENDIF Pascal MAR S assembler#source assembled OBJ O object#file linked OLB O object#library linked .lm-5.f.p0 The maximum number of files is limited by the VMS restriction of 8 parameters to a command, which must also include flags. .br 2 Flags .rm74 3 h .i5 -h######(CP/M-68k compilations only) .p0 creates a ".68k" executable file ("short", or 0x601a magic header) using the link utility alone. The file will contain no symbol table or relocation information. .p0 If the -h flag is not given, the executable file does contain symbol table and relocation information. .br 3 o .i5 -o[#]exe__file .p0 links the compiled source files and objects to form an executable file. If the exe__file contains no explicit filetype, then one of the following is used:- .lm+5.s.nf.ts18 VAX#native EXE CP/M-68k 68K unless the -r flag is given, when it is REL. CP/M-80 none .lm-5.f.p0 The space between the -o flag and the filename is optional. If it omitted, one more source file can be included on the command line. .p0 If no -o flag is given, the source files and compiled and/or assembled, but not linked. .br 3 r .i5 -r######(CP/M-68k compilations only) .p0 creates a CP/M-68k ".rel" file, instead of a ".68k" executable file (which is the default without -r). .rm76 2 Compilation__phases .br $Lang$ compilations take several phases, involving invocation of several utilities:- .IF Pascal .lm+33.ts10,33.p-28 PTC Pascal-to-C#translator translates Pascal source code into C. .p .ELSE Pascal .lm+31.ts10,31.p-26 .ENDIF Pascal CPP the#C#pre-processor expands _#include and _#define statements, and processes _#if's, and outputs a binary-encoded form of the program. .p CP1 compiler#phase#1 converts the output of CPP into a target-independent compiled format. .p CP2 compiler#phase#2 generates processor-specific assembler code from the output of CP1. .p ASx assembler assembles the output of the above to an object file. .p LNK linker links one or more object files and libraries into an executable file. .IIF Pascal.lm-33 .IIFNOT Pascal.lm-31 2 Examples .rm74.TS12,16 3 VAX__native .br The#command: _$ $I$VMS -o EXE__FILE SOURCE__FILE SYS_$LIBRARY:ULIB.OLB .P0 compiles SOURCE__FILE.$typ$ and links it with THE Unix-compatible object library SYS_$LIBRARY:ULIB.OLB and the system libraries, giving executable image file EXE__FILE.EXE, which can then be RUN. .nf.S .IIF Pascal;Execution: _$ PTC -m31 -oSOURCE_FILE.C SOURCE_FILE.PAS $Ecpp$ _$ CPP -x -dlongname -dvms -iSYS_$LIBRARY -oCPP.TMP - SOURCE__FILE.C _$ CP1 $cemV$-lb2 -n32 -r6 -oCP1.TMP CPP.TMP _$ CP2 -oSOURCE__FILE.MAR CP1.TMP _$ MACRO SOURCE__FILE.MAR _$ LINK/EXE=EXE__FILE/NOTRACE SYS_$LIBRARY:CHDR,- SYS_$DISK:[]SOURCE__FILE,SYS_$LIBRARY:ULIB/LIBRARY,- SYS_$LIBRARY:PLIB/LIBRARY _$ DELETE CPP.TMP;*,CP1.TMP;* .F.P0 Note that the intermediate $Cand$ assembler source $files$ SOURCE__FILE.MAR $are$ NOT deleted. .ifnot Pascal .p0 It is sometimes necessary to conditionalise code on the VMS operating system. To facilitate this, the CPP phase defines symbol vms (note lower case) for use with _#ifdef blocks. .endif Pascal .p0 If the above execution procedure is not acceptable, e.g_. you want to change the CP1 or CP2 flags, copy the command procedure SYS_$COMFILE:$CVI$.COM .iifnot Pascal;and/or $CVI$D.COM (debugger version) into your own directory, and modify it as you wish. Note, however, that such modifications are unsupported, and you may not be notified of corrections to the original. .br 3 68000 .br The#command: _$ $I$68K -o EXE__FILE -h SOURCE__FILE LIB__FILE.O .f.p0 compiles SOURCE__FILE.$typ$ and links it with object file (or library) LIB__FILE.O and the system libraries, giving executable file EXE__FILE.68K, which can be run on a Motorola 68000 microprocessor under the CP/M-68k system. .nf.S .IIF Pascal;Execution: _$ PTC -m31 -oSOURCE_FILE.C SOURCE_FILE.PAS $Ecpp$ _$ CPP -x -iSYS_$LIBRARY: -oCPP.TMP SOURCE_FILE.C _$ CP1 $cemu$-al -n8 -o CP1.TMP CPP.TMP _$ P268K -oSOURCE_FILE.S CP1.TMP _$ AS68K -oSOURCE_FILE.O SOURCE_FILE.S _$ LNK -tb0x1200 -eb__memory -ed__edata - SYS_$LIBRARY:CRTCPM.68K SOURCE__FILE.O LIB__FILE.O - SYS_$LIBRARY:LBUCPM.68K SYS_$LIBRARY:LBPCPM.68K _$ TO68K -oEXE_FILE.68K _$ DELETE XEQ.;0,CPP.TMP;*,CP1.TMP;* .F.P0 Note that the intermediate $Cand$ assembler source $files$ SOURCE__FILE.S $are$ NOT deleted. .p0 If the above execution procedure is not acceptable, e.g_. you want to change the CP1 or CP2 flags, copy the command procedure SYS_$COMFILE:$CuI$68K.COM into your own directory, and modify it as you wish. Note, however, that such modifications are unsupported, and you may not be notified of corrections to the original. .br 3 8080 .br The#command: _$ $I$80 -o EXE__FILE SOURCE__FILE LIB__FILE.O .p0 compiles SOURCE__FILE.$typ$ and links it with object file (or library) LIB__FILE.O and the system libraries, giving executable file EXE__FILE., which can be run on an Intel 8080 microprocessor under the CP/M-80 system. .nf.S .IIF Pascal;Execution: _$ PTC -oSOURCE_FILE.C SOURCE_FILE.PAS $Ecpp$ _$ CPP -x -iSYS_$LIBRARY: -oCPP.TMP - SYS_$LIBRARY:UTEXT.H SOURCE__FILE.C _$ CP1 $cemu$-b0 -n8 -u -oCP1.TMP CPP.TMP _$ P280 -oSOURCE__FILE.S CP1.TMP _$ AS80 -oSOURCE__FILE.O SOURCE__FILE.S _$ LNK -O EXE__FILE -eb__memory -ed__edata -htr -tb0x100 - SYS_$LIBRARY:CRTCPM.80 SOURCE__FILE.O LIB__FILE.O - SYS_$LIBRARY:LBPCPM.80 _$ DELETE CPP.TMP;*,CP1.TMP;* .F.P0 Note that the intermediate $Cand$ assembler source $files$ SOURCE__FILE.S $are$ NOT deleted. .p0 If the above execution procedure is not acceptable, e.g_. you want to change the CP1 or CP2 flags, copy the command procedure SYS_$COMFILE:$CuI$CPM80.COM into your own directory, and modify it as you wish. Note, however, that such modifications are unsupported, and you may not be notified of corrections to the original. .IF Pascal .reset escape .REQUIRE 'Pascal_SYNTAX.RNO' .ELSE Pascal .br 2 VAX__runtime__libraries .br.rm76 Subroutines from the VAX/VMS system, runtime, and utility libraries may be called directly from C programs. All such routines have names starting with a three or four-letter mnemonic and a dollar sign. .p0 Many system routines use symbolic arguments of the form XXX_$YYY or XXX_$__Y__ZZZ. A set of files is available in SYS_$LIBRARY to define these. The files are named after the defining macro given in the DEC manuals, e.g. I/O specific definitions are in IODEF.H, so to use them you must .s.i8;_#include .s Note that, in the usual C convention, defined symbols are in UPPER case, subroutine names in lower, as in: .s.i8;sys_$qiow(NULL,chan,IO_$__READVBLK|IO_$M__NOECHO,NULL,NULL, ... ) .p0 Missing (defaulted) subroutine arguments must be specified as NULL, as above. .p0 Many system routines require string descriptors as arguments. A struct typedef DESCRIPTOR has been added to SYS_$LIBRARY:VMS.H to support this. See the DESCRIPTOR sub-topic for further information. .p0 N.B_. when VMS calls a subroutine (e.g_. as an AST), it does not follow the C compiler convention of extending arguments passed by value to longwords (at least). Since C assumes this convention has been followed, regardless of the type you specify in argument declarations, there may be problems in accessing such arguments. .br.rm74 3 DESCRIPTOR .br The following declarations are included in header file SYS_$LIBRARY:VMS.H:- .s.nf typedef struct { unsigned short length; unsigned short type; char *pointer; } DESCRIPTOR; .f.p0 For most purposes, type should be set to 0x10e, the string class for a fixed-length string. .p0 The following macros are also defined: .s.nf _$DESCRIPTOR(label, string) --------------------------- which expands to DESCRIPTOR label = {sizeof(string)-1, 0x10e, string} and is used for static declarations, e.g.: .s.i8 static _$DESCRIPTOR(heldes, "Hello world!); .s _$DESCRIPTOR__I(label, string) ----------------------------- which expands to####label.length = sizeof(string)-1, ####################label.type = 0x10e, ####################label.pointer = string and is used for runtime initialisations (see next example). .s _$DESCRIPTOR__F(label, string) ---------------------------- which expands to####label.length = sizeof(string)-1, ####################label.pointer = string .f and is used to change the length and address when the type has been set previously, and the new string is of length known at compile time, as in: .s.lm+8.nf DESCRIPTOR strdes; .i8;_... _$DESCRIPTOR__I(strdes, "Hello world!"); .i8;_... _$DESCRIPTOR__F(strdes, "Goodbye world!"); .lm-8.s _$DESCRIPTOR__L(label, string, lth) ---------------------------------- which expands to####label.length = lth, ####################label.pointer = string .f and is used when the length must be computed at runtime, e.g_. by a strlen call, as in: .s.i8;_$DESCRIPTOR__L(bufdes, buf, strlen(buf)); .br 3 Examples .ts8,16,24,32,40,48,56,64,72 .br.lm+3.i-3 ^[1)#The following program assigns a channel to the terminal with system library routine SYS_$ASSIGN, reads single characters, without echo, using SYS_$QIOW, and deassigns the channel with SYS_$DASSGN on exit. Note the use of the _$DESCRIPTOR macro (see DESCRIPTOR sub-topic) to create a string descriptor for "SYS_$INPUT". .s.lm-3.nf _#include _#include _#include .s VOID main() { char inchar; unsigned short chan = 0; static _$DESCRIPTOR(sysindes, "SYS_$INPUT"); .s if (!(sys_$assign(_&sysindes,_&chan,NULL,NULL)_&1)) /* Assign chan to */ error("can't open SYS_$INPUT",NULL); /* terminal input */ .s do { sys_$qiow(NULL,chan,IO_$__READVBLK /* Read */ |IO_$M__NOECHO /* without echo */ |IO_$M__NOFILTR, /* pass _^U, _^R, del */ NULL,NULL,NULL,_&inchar, /* to inchar */ 1, /* 1 character */ NULL,NULL,NULL,NULL); putfmt("%c_\n",inchar); /* Show what we got */ } while (inchar != '_\032'); /* Ctrl/Z = exit */ .s sys_$dassgn(chan); /* Deassign chan */ exit(); } .lm+3.f.s.i-3 ^[2)#The following example uses the screen management library routines. It is a Whitesmiths' C version of the program in Chapter 3 of the VAX/VMS Runtime Library Manual, Part I. Note that here, the same string descriptor is used several times, and variables named __n are pre-allocated to supply contant values by reference, as the SMG_$ routines require. .s.lm-3.nf _#include _#include _#include .s main() { char text__output[26]; short term__char; int __3 = 3, __7 = 7, __9 = 9, __24 = 24, __60 = 60, border = SMG_$M__BORDER; int display,paste,keyboard; DESCRIPTOR strdes; .s ^[/* Create the virtual display with a border. */ smg_$create__virtual__display(_&__7,_&__60,_&display,_&border); .s ^[/* Create the pasteboard. */ smg_$create__pasteboard(_&paste); .s ^[/* Create a virtual keyboard. */ smg_$create__virtual__keyboard(_&keyboard); .s ^[/* Paste the virtual display at row 3, column 9. */ smg_$paste__virtual__display(_&display,_&paste,_&__3,_&__9); .s _$DESCRIPTOR__I(strdes, "Enter the character after the >> prompt."); smg_$put__line(_&display,_&strdes); _$DESCRIPTOR__F(strdes, "The character you type will not be echoed."); smg_$put__line(_&display,_&strdes); _$DESCRIPTOR__F(strdes, "The character equivalent of K is displayed."); smg_$put__line(_&display,_&strdes); strdes.length=0; smg_$put__line(_&display,_&strdes); .s ^[/* Read a key stroke from the virtual keyboard. */ .s _$DESCRIPTOR__F(strdes, ">>"); smg_$read__keystroke(_&keyboard,_&term__char,_&strdes,NULL,_&display); strdes.length=0; smg_$put__line(_&display,_&strdes); .s ^[/* Convert the value of term__char to a decimal ASCII string. */ .s _$DESCRIPTOR__L(strdes, text__output,_\ ####decode(text__output,26,"Terminal character is: %- 3us",term__char)); .s ^[/* Print the decimal ASCII text string. */ .s smg_$put__line(_&display,_&strdes); .s ^[/* Print the decimal ASCII string again another way. */ .s _$DESCRIPTOR__L(strdes, _&text__output[23], 3); smg_$put__chars(_&display,_&strdes,_&__7,_&__24); .s exit(); } .f .reset escape .REQUIRE 'CSYNTAX.RNO' .ENDIF Pascal