{ FILE: [22,310]GENERAL.TYP -- OMSI/RSX General Type Definitions LAST EDIT: 6-SEP-1989 16:07:34 PROGRAM DESCRIPTION: General Pascal type declarations which are common to OMSI and VAX_Pascal. AUTHORS: Jim Bostwick, Phil Hannay CREATION DATE: 30-MAR-1988 15:00:39 C H A N G E L O G Date | Name | Description --------------+---------+------------------------------------------------------- 9-DEC-1988 | JMB | Mung IO_Status_block for word or byte access --------------+---------+------------------------------------------------------- 30-MAR-1988 | JMB | Compatible definitions derived from GENERAL3.PAS --------------+---------+------------------------------------------------------- 8-JUN-1988 | JMB | Add Word,Byte,Uword,UByte types --------------+---------+------------------------------------------------------- 24-SEP-1988 | JMB | change Byte, UByte to Char for alignment reasons --------------+---------+------------------------------------------------------- 4-OCT-1988 | JMB | add multiples of send-data packet to string types --------------+---------+------------------------------------------------------- 6-Apr-1989 | PTH | add bit64_word/clunk types --------------+---------+------------------------------------------------------- 11-Apr-1989 | PTH | add ERROR_CLASS type, inadvertantly forgotten --------------+---------+------------------------------------------------------- 07-Aug-1989 | PTH | add CH200, STR199, STR193 --------------+---------+------------------------------------------------------- 06-Sep-1989 | PTH | add FULL_TIMESTAMP_TENTHS, CLUNK_HEX_TIMESTAMP types --------------+---------+------------------------------------------------------- 06-Sep-1989 | PTH | added TICK and TICK_PER_SEC to INT_TIMESTAMP record --------------+---------+------------------------------------------------------- %[change_entry]% } {*USER* This file is a descendant of the various "GENERALx.TYP" files used with OMSI Pascal under RSX. This version resulted from a desire to present a 'familiar' Pascal environment on both VMS (VAX-Pascal) and RSX (OMSI). As a result, GENERAL3.TYP has become GENERAL.TYP/GENERAL.PAS, plus additional include files. Note that coexistence is the issue here, not migration, nor source portability. This goal leads to the following guidelines: .list 0,"*" .le ;modules of the same name will have the same function on either system .le ;each module will deal with 'its' system on it's terms. .le ;within ISO rules, datatypes defined herein will allocate physical memory identically on both systems. This means that objects of these types may be ported (e.g. in DECNET messages) legibly between systems. .le ;some 'harmless' extended definitions (e.g. EFNs) have been allowed. VMS can access up to 127 EFNs, while RSX only gets at 96. By defining the type EFN as f0-f127, it is useable on either system. You get an error message if you try to use F120 on RSX, but this is 'harmless'. .le ;on VMS the preferred mechanism for including definitions is to 'inherit' them from an 'environment' file. On RSX, they must be 'included' at source level, from 'typ', and 'ext' files. Thus, on VMS you find GENERAL.PAS, and GENERAL.PEN, while on RSX you find GENERAL.TYP. .els .hl 2 VMS RSX Compatibility Two additional include files are defined to aid in VMS-RSX compatibility. These are RSXVMS.TYP, and VMSRSX.PAS/PEN. They include definitions which allow one system to reference native objects from another - such as integer and Long. Note that we normally don't worry about VMS using a 32-bit INTEGER while RSX uses 16-bits. It will matter, howver, if we want to define records which will be used on both systems. Thus, VMSRSX defines the PDP$Integer (16-bits), and RSXVMS.TYP defines the VMS$Integer (32-bits). .HL 2 NAMES Unless there is a special reason to do otherwise (EFN is an example), names are defined with a leading Upper Case letter followed by n lower case letters. Note that most of the general types have fairly long (and descriptive) names. Generic 'tag' identifiers, such as "_rec", or "_type", are used to allow common names to be used as variables. This is done to a)distinguish type identifiers from variable identifiers (i.e., Var Example:Example_rec); b) to try to avoid general type identifiers which would logically be used variable names. For datatypes which are processor (or operating system) specific, a prefix of xxx$ is used. For example, PDP$Integer is the native PDP-11 integer, and VMS$Integer is a (VAX) longword. .HL 2 Reserved names The following identifiers are reserved (primarily for the P2UTIL modules): DSW - pascal copy of $DSW IOSB - pascal copy of IO STATUS BLOCK (from QIOW calls). Type is IO_Status_Block Users are encouraged to use these standard identifiers whenever possible. } TYPE {*USER* .HL 2 Character arrays. The following define packed arrays of various lengths. The form is CHx, where x is the length. Lengths from 1 through 20 are defined, plus 26, and by tens from 30 through 80. These types map directly between OMSI and VAX Pascal. If the AMI string package is used, these types may be freely exchanged between RSX and VMS programs. If not, beware that VAX Pascal will blank fill these arrays, while the OMSI string package will zero (null) fill them. } CH1 = PACKED ARRAY [1..1] OF CHAR; CH2 = PACKED ARRAY [1..2] OF CHAR; CH3 = PACKED ARRAY [1..3] OF CHAR; CH4 = PACKED ARRAY [1..4] OF CHAR; CH5 = PACKED ARRAY [1..5] OF CHAR; CH6 = PACKED ARRAY [1..6] OF CHAR; CH7 = PACKED ARRAY [1..7] OF CHAR; CH8 = PACKED ARRAY [1..8] OF CHAR; CH9 = PACKED ARRAY [1..9] OF CHAR; CH10 = PACKED ARRAY [1..10] OF CHAR; CH11 = PACKED ARRAY [1..11] OF CHAR; CH12 = PACKED ARRAY [1..12] OF CHAR; CH13 = PACKED ARRAY [1..13] OF CHAR; CH14 = PACKED ARRAY [1..14] OF CHAR; CH15 = PACKED ARRAY [1..15] OF CHAR; CH16 = PACKED ARRAY [1..16] OF CHAR; CH17 = PACKED ARRAY [1..17] OF CHAR; CH18 = PACKED ARRAY [1..18] OF CHAR; CH19 = PACKED ARRAY [1..19] OF CHAR; CH20 = PACKED ARRAY [1..20] OF CHAR; CH21 = PACKED ARRAY [1..21] OF CHAR; CH22 = PACKED ARRAY [1..22] OF CHAR; CH23 = PACKED ARRAY [1..23] OF CHAR; CH24 = PACKED ARRAY [1..24] OF CHAR; CH25 = PACKED ARRAY [1..25] OF CHAR; CH26 = PACKED ARRAY [1..26] OF CHAR; { same size as RSX Send Data packet } CH27 = PACKED ARRAY [1..27] OF CHAR; CH28 = PACKED ARRAY [1..28] OF CHAR; CH29 = PACKED ARRAY [1..29] OF CHAR; CH30 = PACKED ARRAY [1..30] OF CHAR; CH40 = PACKED ARRAY [1..40] OF CHAR; CH50 = PACKED ARRAY [1..50] OF CHAR; CH52 = PACKED ARRAY [1..52] OF CHAR; { 2 X Send Data Packet } CH60 = PACKED ARRAY [1..60] OF CHAR; CH70 = PACKED ARRAY [1..70] OF CHAR; CH78 = PACKED ARRAY [1..78] OF CHAR; { 3 x Send Data Packet } CH80 = PACKED ARRAY [1..80] OF CHAR; CH90 = PACKED ARRAY [1..90] OF CHAR; CH100 = PACKED ARRAY [1..100] OF CHAR; CH104 = PACKED ARRAY [1..104] OF CHAR; { 4 x Send Data Packet } CH110 = PACKED ARRAY [1..110] OF CHAR; CH120 = PACKED ARRAY [1..120] OF CHAR; CH130 = PACKED ARRAY [1..130] OF CHAR; { 5 x Send Data Packet } CH132 = PACKED ARRAY [1..132] OF CHAR; CH156 = PACKED ARRAY [1..156] OF CHAR; { 6 x Send Data Packet } CH182 = PACKED ARRAY [1..182] OF CHAR; { 7 x Send Data Packet } CH200 = PACKED ARRAY [1..200] OF CHAR; CH208 = PACKED ARRAY [1..208] OF CHAR; { 8 x Send Data Packet } CH234 = PACKED ARRAY [1..234] OF CHAR; { 9 x Send Data Packet } CH255 = PACKED ARRAY [1..255] OF CHAR; {*USER* .hl 2 Varying STRING Types Both OMSI (via PASUTL String Package) and VAX_Pascal (via DEC RTL) support the varying length string datatype. Both consist of a byte count followed by that many data bytes. Unfortunately, OMSI uses a byte for the count (0..255), while VMS uses a word (0..65535). Sigh. Since this is an incredibly usefull data type, and would become clumsy to implement identically on both systems, it has been defined for both VMS and RSX. We now have three string types: CHxx (fixed-length) which is identical on either system; STRxx (OMSI type-0) which is 'native' to RSX; and VARxx (VAX_Pascal VARYING) which is 'native' to VMS. For RSX, STRxx are 'native'; VARxx types are defined in RSXVMS.TYP. } STR1 = PACKED ARRAY [0..1] OF CHAR; STR2 = PACKED ARRAY [0..2] OF CHAR; STR3 = PACKED ARRAY [0..3] OF CHAR; STR4 = PACKED ARRAY [0..4] OF CHAR; STR5 = PACKED ARRAY [0..5] OF CHAR; STR6 = PACKED ARRAY [0..6] OF CHAR; STR7 = PACKED ARRAY [0..7] OF CHAR; STR8 = PACKED ARRAY [0..8] OF CHAR; STR9 = PACKED ARRAY [0..9] OF CHAR; STR10 = PACKED ARRAY [0..10] OF CHAR; STR11 = PACKED ARRAY [0..11] OF CHAR; STR12 = PACKED ARRAY [0..12] OF CHAR; STR13 = PACKED ARRAY [0..13] OF CHAR; STR14 = PACKED ARRAY [0..14] OF CHAR; STR15 = PACKED ARRAY [0..15] OF CHAR; STR16 = PACKED ARRAY [0..16] OF CHAR; STR17 = PACKED ARRAY [0..17] OF CHAR; STR18 = PACKED ARRAY [0..18] OF CHAR; STR19 = PACKED ARRAY [0..19] OF CHAR; STR20 = PACKED ARRAY [0..20] OF CHAR; STR21 = PACKED ARRAY [0..21] OF CHAR; STR22 = PACKED ARRAY [0..22] OF CHAR; STR23 = PACKED ARRAY [0..23] OF CHAR; STR24 = PACKED ARRAY [0..24] OF CHAR; STR25 = PACKED ARRAY [0..25] OF CHAR; STR26 = PACKED ARRAY [0..26] OF CHAR; STR27 = PACKED ARRAY [0..27] OF CHAR; STR28 = PACKED ARRAY [0..28] OF CHAR; STR29 = PACKED ARRAY [0..29] OF CHAR; STR30 = PACKED ARRAY [0..30] OF CHAR; STR40 = PACKED ARRAY [0..40] OF CHAR; STR50 = PACKED ARRAY [0..50] OF CHAR; STR52 = PACKED ARRAY [0..52] OF CHAR; { 2 X Send Data Packet } STR60 = PACKED ARRAY [0..60] OF CHAR; STR70 = PACKED ARRAY [0..70] OF CHAR; STR78 = PACKED ARRAY [0..78] OF CHAR; { 3 x Send Data Packet } STR80 = PACKED ARRAY [0..80] OF CHAR; STR90 = PACKED ARRAY [0..90] OF CHAR; STR100 = PACKED ARRAY [0..100] OF CHAR; STR104 = PACKED ARRAY [0..104] OF CHAR; { 4 x Send Data Packet } STR110 = PACKED ARRAY [0..110] OF CHAR; STR120 = PACKED ARRAY [0..120] OF CHAR; STR130 = PACKED ARRAY [0..130] OF CHAR; { 5 x Send Data Packet } STR132 = PACKED ARRAY [0..132] OF CHAR; STR156 = PACKED ARRAY [0..156] OF CHAR; { 6 x Send Data Packet } STR182 = PACKED ARRAY [0..182] OF CHAR; { 7 x Send Data Packet } STR193 = PACKED ARRAY [0..193] OF CHAR; STR199 = PACKED ARRAY [0..199] OF CHAR; STR208 = PACKED ARRAY [0..208] OF CHAR; { 8 x Send Data Packet } STR234 = PACKED ARRAY [0..234] OF CHAR; { 9 x Send Data Packet } STR255 = PACKED ARRAY [0..255] OF CHAR; {*USER* .hl 2 EVENT FLAGS Event flags are defined as a scalar type. Note that all EFNs are defined, including those 'reserved' by DEC, as well as those available only to VMS. A null value, f0, is defined as well. The identifier EFN is reserved for use as a type Event_Flag, especially within the utility library modules. While not an efn, a flag of zero (f0) acts as a wildcard for some calls. CMKT (cancel marktime), for example, will cancel ALL marktimes if called with efn of zero. Secondary benefit is that ORD(EFN) is equal to the flag number. .note VMS in fact DOES define f0 to be a 'flag'. However, it is used very much like the null EFN in RSX: e.g., CMKT(f0) will cancel all outstanding timers. Flag 0 appears to be to vms a 'catchall' flag - used when you don't care, and NOT to be used as a 'real' flag. .end note EFNs f25-f32 and f57-f64 are reserved by RSX. EFNs f24-f31 are reserved by VMS. Use them at your own risk (it won't crash the system, but your task may act strangely). EFNs f97-f127 are available ONLY on VMS. Further, any flag >31 is a VMS 'common EFN' - similar to a group global in RSX. Common EFN 'clusters' must be created in VMS before they may be used, and may only be shared by processes running under the same group. If you inadvertantly use an illegal flag in RSX (f99 for example), you will get a DSW of "illegal flag". Just goes to show that it's a good thing to check the DSW after system calls. A drawback of this approach is that the Pascal flag-set and the DEC mask words do not line up, under RSX. This is normally transparent to the user. It is of critical importance to implementors of library procedures, however. Under VMS, everything lines up nicely, since f0 is pseudo-real. An additional subrange type, PDP$EFN, is defined for those who want to be rigorous or something. It's another way to allow the compiler to screech about something you really don't want to do... RSX uses group numbers, VMS uses clusters; both are usefull for such calls as WFLOR. Here is the skinny: .nf .sk RSX VMS ----- ------ f0 'null flag' 'catchall flag' f1 - f16 group _#0 (local) f17 - f32 group _#1 (local) f25 - f32 RSX RESERVED f0 - f31 Cluster _#0 (process local) f24 - f31 VMS RESERVED f33 - f48 group _#2 (global) f49 - f64 group _#3 (global) f57 - f64 RSX RESERVED (global) f32 - f63 cluster _#1 (common cluster) f65 - f80 group _#4 (grp. global) f81 - f96 group _#5 (grp. global) f64 - f95 cluster -#2 (common cluster) f96 - f127 cluster -#3 (common cluster) } TYPE {[F-]} VMS$Event_Flag =( f0, { NOT an RSX event flag, NOT REALLY a VMS one, but usefull for some calls } f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, {group #0} f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32, {group #1} f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44, f45, f46, f47, f48, {group #2} f49, f50, f51, f52, f53, f54, f55, f56, f57, f58, f59, f60, f61, f62, f63, f64, {group #3} f65, f66, f67, f68, f69, f70, f71, f72, f73, f74, f75, f76, f77, f78, f79, f80, {group #4} f81, f82, f83, f84, f85, f86, f87, f88, f89, f90, f91, f92, f93, f94, f95, f96, {group #5} { remainder VMS only !! } f97, f98, f99, f100, f101, f102, f103, f104, f105, f106, f107, f108, f109, f110, f111, f112, f113, f114, f115, f116, f117, f118, f119, f120, f121, f122, f123, f124, f125, f126, f127 ); Event_Flag = f0..f96; { RSX legal subset } {[F+]} { Group numbers are usefull for logical OR of event flag calls. The above works nicely, but fouls up SET of FLAG, because there is an extra element (f0). So, the two sets below are defined in terms of a subrange of Event_Flag. I don't think that this will cause users any troubles. } {*USER* .hl 2 Event Flag Sets To structures are defined for use with event flags. The Event_Flag_Set is simply a set of all real event flags (f0 is not included). This type is returned by the RDAF procedure. The Event_Flag_Array is a packed array of boolean which will match up with Event_Flag_Set. The ability to swap between these two types (using Loophole) is often usefull. } Event_Flag_Set = PACKED SET OF f1..f96; Event_Flag_Array = Packed Array [f1..f96] of BOOLEAN; { this may or may not prove a useful type. LOOPHOLE will nicely swap Event_Flag_SET and Event_Flag_Array types.} {*USER* .hl 2 Byte and Word Types Four atomic types are defined as an aid to low-level interfacing. These are Byte and UByte (signed and unsigned), and Word and UWord (also signed and unsigned). Because Pascal aligns integer subrange types on word boundaries, we use CHAR for Byte and UByte. Sigh. The 64-bit word is used for large integer arithmetic and for clunk style date/time. For clarity, a CLUNK_TYPE definition which is identical is also included the time definitions. } TYPE UWord = 0..65535; Word = UWord; Address = UWord; Byte = char; UByte = char; NByte = 0..255; { a numeric byte type } bit64_word = packed array [1..4] of integer; { same as a clunk time } {*USER* .hl 2 Time Units. The Time_Unit type is used in library calls involving time span or delay (i.e., WAIT, MRKT). It comprises Ticks (60 ticks per second), seconds, minutes, and hours, and milliseconds. Type Milliseconds has been added to the GENERAL3 definition of Time_Unit. Because it has been added 'at the end', no conflict will arise with earlier code (including current object code), so long as milliseconds are not referenced. In general, VMS doesn't understand ticks, and RSX doesn't understand milliseconds. The library routines for both systems will however handle these types. Don't expect much from a 1-ms. delay in RSX, though! VMS uses clunk time exclusively for all internal timing functions. The PASUTL routines will convert from seconds, etc. to clunks. However, non-portable code may be more efficiently written to call the delay routines directly, rather than going through the conversion in PASUTL routines. } Time_Unit = (ticks, seconds, minutes, hours, milliseconds); {*USER* .hl 2 Date and Time records These define ASCII and Integer records containing the full date/time information, to the second. (Ticks are something one finds only on dogs.) Subrecords are defined, which allows the entire date or time to be referenced as a unit. The integer records have intentionally left as INTEGER, rather than subrange types. This allows an illegal date/time to be read into the record, and then validated, without a run-time error. The ASCII date and time library procedures are now very flexible in the amount of information returned. They key on the length of the input array, and return just what is requested. The clunk style 64 bit date and time type is also defined. Clunk date/times are used in VMS and by datatrieve, and make a uniform accurate high resolution timestamp. } TYPE Int_Date = RECORD Year: Integer; {00-99} Month: Integer; {01-12} Day: Integer; {01-31} end; Int_Time = RECORD Hour: Integer; {00-23} Minute: Integer; {00-59} Second: Integer; {00-59} end; Int_Timestamp = RECORD Date: Int_Date; Time: Int_Time; Tick: Integer; Tick_per_sec: Integer; end; { AGAIN, this time in ASCII... note that these are NOT record types -- they are simple character arrays defined for convenience. Note that some of the P3UTIL date routines will use the type (array length) to determine what sort of date/time representation you are supplying or you wish to be returned. } Julian_Date = ch3; { ddd } DEC_Time = ch8; { hh:mm:ss } DEC_Date = ch9; { dd-mmm-yy } Full_Date = ch11; { dd-mmm-yyyy } DEC_Timestamp = CH18; { dd-mmm-yy hh:mm:ss } Full_Timestamp = CH20; { dd-mmm-yyyy hh:mm:ss } Full_Timestamp_tenths = CH22; { dd-mmm-yyyy hh:mm:ss.n } Full_Timestamp_msec = CH24; { dd-mmm-yyyy hh:mm:ss.nnn } Full_Timestamp_usec = CH26; { dd-mmm-yyyy hh:mm:ss.nnnnnn } Full_Timestamp_nsec = CH29; { dd-mmm-yyyy hh:mm:ss.nnnnnnnnn } { And finally, the 64 bit clunk style date and time. CLUNK_timestamp is the binary clunk time, while CLUNK_hex_timestamp is a CLUNK_timestamp expressed in ascii HEX numbers "0" thru "F", where the low order hex digit is in CLUNK_hex_timestamp[16]. } CLUNK_timestamp = bit64_word; CLUNK_hex_timestamp = CH16; {End of date/time types } {*USER* .hl 2 IO Status Block The IO_Status_Block type is used with all library procedures which do IO. Its contents are defined in the IO DRIVERS REFERENCE MANUAL. VMS, interestingly, uses a similar animal, but defined in terms of VMS Integers. Thus, the VMS IO_Status_Block will occupy 8 bytes, while the RSX one occpies 4 bytes. .note This definition violates the strict compatibility standard. Since I can see no possible conflicts, and many benefits from using the 'natural' IOSB, I've left it in. If we start passing RSX IOSBs to VMS, well, it'll be just too bad. } IO_Status_Block = Record Case Boolean of TRUE: ( Int: Packed Array [1..2] Of INTEGER); { Used with QIO procedures } FALSE: (Byt: Packed Array [1..4] of NByte); { access as 4 bytes } end; { IO_Status_Block } {*USER* .hl 2 Radix-50 The following types define RAD-50 data. Note that Pascal does not understand Rad50, and that these are really only usefull for system interface uses. Type Rad56 is very usefull for holding task names. } Rad53 = INTEGER; { 3 character Rad50 } Rad56 = Array [1..2] of Rad53; { 6-character Rad50 } {*USER* .hl 2 Error Class The P3UTIL procedure ERROR takes a severity class. Fatal errors cause program termination (with exit status), while other classes do not. } Error_class = (fatal_err, warning_err); {*USER* .hl 2 Directive Status Word In previous libraries, the executive calls included a Var parameter DSW, which received a copy of the task's directive status word. This method has been replaced by a GLOBAL variable $DSW. $DSW is origined to the task $DSW (in the low core context area of each task). Thus, the DSW parameter no longer appears in the executive directive procedures. The user should continue to check $DSW after each procedure call which invokes an exec directive. } VAR $DSW ORIGIN 46B :Integer; { Define the task Directive Status Word } {%[declaration_list]%...}