Trailing-Edge
-
PDP-10 Archives
-
decuslib20-04
-
decus/20-0110/io.sai
There are 3 other files named io.sai in the archive. Click here to see a list.
ENTRY;
COMMENT
.SEC(IO.SAI - PROC10 I/O package)
.index(IO.SAI - PROC10 I/O package)
.;
COMMENT
.SEC(IO.SAI package)
.INDEX(IO.SAI package)
.;
Begin "IO.SAI"
Require "DEFINE.REQ" source!file;
Require "PRCMAX.REQ" source!file;
Require "PRCINV.REQ" source!file;
#
IO.SAI - An I/O package for DDTG data files on the PDP10.
---------------------------------------------------------
BRUCE SHAPIRO and PETER LEMKIN
IMAGE PROCESSING UNIT
NCI, DCBD
NATIONAL INSTITUTES OF HEALTH
BETHESDA, MARYLand 20014
Revised Nov 14, 1976 - Lemkin, removed [50,752] ref and fixed NUMBER mode
Revised July 27, 1976 - Lemkin fixed GETPIX BM data mode
Revised July 7, 1976 - Lemkin fixed GETDDTG
Revised May 25, 1976 - Lemkin fixing mask PUTBMASK
Revised May 24, 1976 - Lemkin fixing mask and boundry title i/o
Revised May 19, 1976 - Lemkin, made arrays SAFE
Revised May 17, 1976 - Lemkin, made procedures SIMPLE
Revised April 14, 1976 - Lemkin, fixed put mask size
Revised April 10, 1976 - Lemkin, added GET/PUTARRAY procedures
AUGUST 25, 1975
Revised SEPTEMBER 9, 1975
Revised SEPTEMBER 23, 1975
Revised OCTOBER 8, 1975
Revised December 17, 1975 - Lemkin, added byte modes
Revised December 18, 1975 - Lemkin, added HEADER
Revised December 24, 1975 - Lemkin, speeded up DECODE
Revised December 30, 1975 - MADE IT WORK!
Revised Jan 12, 1976 Lemkin - added GETPIX, PUTPIX
Revised Jan 14, 1976 Lemkin - corrected GETPIX, PUTPIX
Revised Jan 15, 1976 - Lemkin, fixed oheader ref. in MAKEHEADER
Revised Jan 16, 1976 - Lemkin, fixed iheader ref. in GETDDTG
Revised Jan 30, 1976 - Lemkin, fixed CVI7, and deleted extraneous code.
Revised Feb 3, 1976 - Lemkin, added devices to io!file!names
Revised Feb 4, 1976 - Lemkin, added GETBOUNDARY, PUTBOUNDARY,
GETMASK, PUTMASK
Revised Feb 11, 1976 - Lemkin, added modes 14 and 15 to MAKHEADER
Revised Feb 12, 1976 - Lemkin, added length to GETBOUNDARY
Revised Feb 12, 1976- Shapiro, fixed length in GETBOUNDARY
Revised Feb 13, 1976 - Lemkin, added length spec to input of
PUTBOUNDARY
Revised Feb 18, 1976 - Lemkin, fixed case limit test in MAKHEADER
Revised Feb 19, 1976 - Lemkin, speeded up For loops on GET/PUTs
Revised March 5, 1976 - Lemkin, fixed header[80] for types 9-12
INTRODUCTION
------------
The set of routines in IO.SAI enable a user to read or
write grey scale picture files (256 by 256 with 256
levels of grey) or variable size boundary files on the
PDP10. The data is packed so that it may be manipulated
by the RTPP-PDP8/e configuration. In particular the
programs called DDTG and PROCES running on the PDP8/e
will read and produce data of this form. With the aid
of these programs, it is therefore possible to process
images scanned by the RTPP on the PDP10.
Similarly, any images produced on the PDP10 with this
package may be processed by the RTPP.
In addition to insuring the compatability of data
formats between the PDP8/e and the PDP10, the data
packing used assures maximum packing density.
Procedures GETDDTG and PUTDDTG are used to lookup and
enter DDTG files and read and write the header.
MAKEHEADER is used to create an header Array for use in
PUTDDTG while CVTHEADER is used to convert the Integer
Array iheader to selected variables. GETLINE and
PUTLINE are used on successive calls to read and write
line data. GET12BIT and PUT12BIT (and their 8-bit
versions GET8BIT and PUT8BIT) are used to read and
write 12 and 8 bit byte data. CLOSEINDATA and
CLOSEOUTDATA are used to close the input and output
channels respectively so that another file may be used.
Only one input and out channel may be active at a time.
;
COMMENT
.NEXT PAGE
.SS(Logical data file format)
.index(Logical data file format)
Logical Data file format
------------------------
A DDTG data file consists of a file header followed by
DDTG data where the data format is described in the header.
------------------------------------------
| Header | Variable length data segment |
------------------------------------------
1 block n blocks
The header contains the following information:
12-bit
word
number field and function
------ -------------------
1 (a) data file space mode (7 to 15 decimal) - 1 word
BM=7, MASK=10, QMT=11, GRAFPEN=12, GALSCAN=13,
STATE=15.
2 (b) file length in blocks (0 means variable) - 1 word
3:4 (c) number of data (0 means variable) - 2 words
5 (d) number of words/datum (a fraction
expressed by the numerator in the left 6-bit byte,
and the denominator in the right 6-bit byte - 1 word.
6 (e) data file submode number (see DDTG.DOC table 2) - 1 word
7 (f) data length - 1 word (0=8-bit, 1=10-bit,
2=12 bit data, 3=16-bit, 4=1-bit)
8 (g) information type - 1 word (0=z data, 1=xy data,
2=xyz data (not used), 3=(x(e),x(x))
MASK reg. data, 4=QMT function comp.
data, 5=bin. mask, 6=36bit PDP10 words)
9 (h) data packing mode - 1 word (0 means packed 8-bit,
1 means unpacked in 12-bit words).
10 (i) OS/8 date word when file created - 1 word
month - bits 0:3
day - bits 4:8
year (0 to 7) - bits 9:11.
11 (j) horizontal window coordinate before scan - 1 word
12 (k) vertical window coordinate before scan - 1 word
13:16 (l) file name and extension (6-bit Ascii) - 4 words
17:52 (m) 72 character Comment (6-bit Ascii) with zero last
character - 36 words
53:76 (n) 12-tuple double precision CURRENT position state
vector, see MDPDATA[7:8,1:12] in COMMON - 24 words
77 (o) gray value used for filling masks (8-bits lsb
default is 255) - 1 word
78 (p) Class key (0 if not used), 1 to 12 if used.
79:80 (q) Time of day in two words packed 4A6
81 (r) Size of image for tsubmode 15 as (2**n)-1
.next page
;
COMMENT
.next page
.ss(Table 2. Data space file header information)
.index(Table 2. Data space file header information)
Table 2. Data space file header information (from DDTG.DOC)
--------------------------------------------
The table below specifies (a)-(h) where appropriate for the 12
data file modes.
Data file mode | (a) | (b) | (c) | (d) | (e)
------------------------------------------------------
1 BMi | 7 | 171 | 65K | 2/3 | 1 (8-BIT PACKED)
2 BMi | 7 | 342 | 65K | 4/3 | 2 (16-BIT PACKED)
------------------------------------------------------
3 MASK | 10 | 8 | 1024 | 2 | 3
------------------------------------------------------
4 QMT | 11 | 8 MAX | 1018MAX| 6 | 4 (VAR)
------------------------------------------------------
5 GRAF-PEN | 12 | VAR. | VAR. | 2 | 5 (10-BIT VECTOR)
6 GRAF-PEN | 12 | VAR. | VAR. | 2 | 6 (10-BIT NOVECTOR)
7 GRAF-PEN | 12 | VAR. | VAR. | 4/3 | 7 (8-BIT VECTOR)
8 GRAF-PEN | 12 | VAR. | VAR. | 4/3 | 8 (8-BIT NOVECTOR)
------------------------------------------------------
9 GALV-SCAN | 13 | 171 | 65K. | 2/3 | 9 (256 RASTER)
10 GALV-SCAN | 13 | 1736 | 1048K | 2/3 | 10 (1024 RASTER)
11 GALV-SCAN | 13 | 171 | 65K. | 2/3 | 11 (256 RAST-MASK)
12 GALV-SCAN | 13 | 1736 | 1048K | 2/3 | 12 (1024 RAST-MASK)
------------------------------------------------------
13 STATE | 15 | 1 | 12 | 2 | 13 (see header)
------------------------------------------------------
14 BMASK | 16 | VAR | VAR | 12 | 14 (in PROC10)
------------------------------------------------------
15 IMAGE | 17 | VAR | VAR | 2/3 | 15 (in PROC10)
------------------------------------------------------
16 PDP10 DATA | 18 | VAR | n wds | 3/1 | 16 PDP10 36bit words
Data file mode | (f) | (g) | (h)
--------------------------------------
1 BMi | 0 | 0 | 0 (MEMORY i=[0:7])
2 BMi | 3 | 0 | 0 (MEMORY i=[0:7])
--------------------------------------
3 MASK | 1 | 3 | 1
--------------------------------------
4 QMT | 1 | 4 | 1
--------------------------------------
5 GRAF-PEN | 1 | 1 | 1 (DOUBLE 0 IS EOF)
6 GRAF-PEN | 1 | 1 | 1 (DOUBLE 0 IS EOF)
7 GRAF-PEN | 0 | 1 | 0 (DOUBLE 0 IS EOF)
8 GRAF-PEN | 0 | 1 | 0 (DOUBLE 0 IS EOF)
--------------------------------------
9 GALV-SCAN | 0 | 0 | 0
10 GALV-SCAN | 0 | 0 | 0
11 GALV-SCAN | 0 | 0 | 0
12 GALV-SCAN | 0 | 0 | 0
--------------------------------------
13 STATE | 1 | 4 | 1
--------------------------------------
14 BMASK | 4 | 5 | 0
--------------------------------------
15 IMAGE | 0 | 0 | 0
--------------------------------------
16 PDP10 DATA | 2 | 6 | 1
;
COMMENT
.next page
.ss(Physical data file format)
.index(Physical data file format)
PHYSICAL DATA FORMAT
--------------------
All physical data is comprised of 8-bit bytes. On the
PDP8/e 3 bytes are packed into 2 PDP8/e words as
follows:
***********************
* HIGH3 * BYTE1 *
***********************
* LOW3 * BYTE2 *
***********************
note that the high and low segments (each 4 bits) must
be concatenated to form the third byte.
A similar packing arrangement exists for data on the
PDP10, except that now, 36 bit words are used and
therefore, exactly 9 bytes will fit into two 36 bit
PDP10 words as follows:
*******************************************************
* HIGH3 * BYTE1 * LOW3 * BYTE2 * HIGH6 * BYTE4 *
*******************************************************
* LOW6 * BYTE5 * HIGH9 * BYTE7 * LOW9 * BYTE8 *
*******************************************************
Again note that HIGHn and LOwn must be concatenated to
form an 8 bit byte.
;
COMMENT
.next page
.ss(PDP8e/PDP10 file transmission methods)
.index(PDP8e/PDP10 file transmission methods)
.;
"
PDP8e/PDP10 file transmission methods
-------------------------------------
The I/O routines implemented in this package will read
files of the latter form which were either created
directly on the PDP10 with this package or were
transferred from the PDP8/e with either the MAG-TAPE
routines or PIP10 with a /I switch for DEC-TAPE (also
using PIP on the PDP10, with a /I switch).
.ss(External IO.SAI procedure calls)
.index(External IO.SAI procedure calls)
External IO.SAI Procedure calls
-------------------------------
[1] Boolean Simple GETDDTG(String io!file!name;
Reference Integer Array iheader);
-lookup the file and get the header.
returns True if file not found Else false.
io!file!name-a String variable containing the
name of the file containing the data.
iheader-an Integer Array iheader[0:255]
which when called with iheader[0] set
to '1' will be filled with the contents
of the 256 12-bit byte file header. Otherwise
it is assumed that the file
does not contain a header and the first
byte in the file is taken as data.
If iheader[0]='N' then data is read
in as a raster of ascii numbers.
[2] Simple GETLINE(Reference Integer Array ILINE);
will retrieve the next 256 sequential 8-bit
bytes of data from ithe input specified file.
ILINE-a 256 word one-dimensional Integer Array.
This Array will be filled with unpacked 8-bit
data. It should be dimensioned in the calling
program as ILINE[0:255].
[3] Integer Simple GET12BIT - will retrieve the next 12-bit input byte.
note that GETDDTG must have been called
previously with a header request to
initialize the file.
[4] Integer Simple GET8BIT - will retrieve the next 8-bit input byte.
note that GETDDTG must have been called
previously with a header request to
initialize the file.
[5] Simple CLOSEINDATA-will permit the the Opening
of a new input file. Any previous
input file Opened will not be accessible.
[6] Boolean Simple PUTDDTG(String Oio!file!name;
Integer Array oheader);
-enter the file and write out the header.
returns True Enter error Else false.
Oio!file!name-a String variable which will
contain the name of the output file.
oheader-a 256 word Integer Array which when oheader[0]
is zero will cause the Procedure to
assume that no header is to exist in
the output file. If the it is '1'
Then the header will be written
at the Beginning of the file.
[7] Simple PUTLINE(Integer Array OLINE)
will store the next 256 bytes sequentially
in packed format
OLINE-a 256 word one-dimensional Integer Array
which contains the next 256 bytes to
be wrItten. It should be dimensioned
in the calling program as OLINE[0:255].
[8] Simple PUT12BIT(Integer N12BIT) - will write out the value of
its argument N12BIT. note that
PUTDDTG must have been called
previously with a header request to
initialize the file.
[9] Simple PUT8BIT(Integer N8BIT) - will write out the value of
its argument N8BIT. note that
PUTDDTG must have been called
previously with a header request to
initialize the file.
[10] Simple CLOSEOUTDATA-will close the output file written
with the PUTDDTG Procedures. It will also
permit the Opening of a new output file
when PUTDDTG is called. Only one output file
may be Opened at a time.
[11] Simple MAKEHEADER( Integer submode;
String Oio!file!name, com;
Integer Array oheader);
- setup an initial header Array based on the
submode information (see table 2), the
io!file!name, Comment (com) and store it in oheader.
[12] Simple CVTHEADER(Reference Integer submode;
Reference String io!file!name, com;
Reference Integer Array iheader);
- convert a header Array into the
submode information (see table 2), the
io!file!name, Comment (com) from oheader.
[13] Boolean Simple GETPIX( Reference Integer Array image3;
Reference String io!file!name, com;
Reference Integer Array header);
- Input a picture from the specified file and
return with the title in the input string. The
procedure returns true if it failed otherwise
it returns false.
[14] Boolean Simple PUTPIX( Reference Integer Array image1;
String io!file!name, com;
Reference Integer Array header);
- Output a picture into the specified file
given the Comment string com. If it fails the
Enter it returns true otherwise it returns
false.
[15] Boolean Simple GETBMASK( Reference Integer Array mask3;
Reference String io!file!name, com;
Reference Integer Array header);
- Input a binary mask from the specified file and
return with the title in the input string. The
procedure returns true if it failed otherwise
it returns false.
[16] Boolean Simple PUTBMASK( Reference Integer Array mask1;
String io!file!name, com;
Reference Integer Array header);
- Output a binary mask into the specified file
given the Comment string com. If it fails the
Enter it returns true otherwise it returns
false.
[17] Boolean Simple GETBOUNDARY( Reference Integer Array
boundary3;
Reference String io!file!name, com;
Reference Integer Array header;
Reference Integer bnd!length);
- Input a boundary from the specified file and
return with the title in the input string. The
procedure returns true if it failed otherwise
it returns false. Bnd!length is the boundary
length including the logical eof which is (x,y)=(0,0).
[18] Boolean Simple PUTBOUNDARY( Reference Integer Array
boundary1;
String io!file!name, com;
Reference Integer Array header;
Integer bnd!length);
- Output a boundary into the specified file
given the Comment string com. If it fails the
Enter it returns true otherwise it returns
false. note that header[0] should be 0 to generate
the header.
[19] Boolean Simple GETARRAY( Reference Integer Array
data!array;
Reference String io!file!name, com;
Reference Integer Array header;
Reference Integer total!array!size);
- Input an Integer ARRAY from the specified file and
return with the title in the input string. The
procedure returns true if it failed otherwise
it returns false. total!array!size is the ARRAY
length.
[20] Boolean Simple PUTARRAY( Reference Integer Array
data!array;
String io!file!name, com;
Reference Integer Array header;
Integer total!array!size, array!type, number!tuples);
- Output an Integer ARRAY into the specified file
given the Comment string com. If it fails the
Enter it returns true otherwise it returns
false. note that header[0] should be 0 to generate
the header. In either case, header[80]_array!type,
and header[81]_number!tuples.
LINKING TO THE Procedures
-------------------------
These Procedures may be incorporated in any
user SAIL program by placing the file IO.REQ in your
program.
---------------------------------------------------------"
COMMENT
.next page
.SS(GET IO.SAI procedures)
.index(GET IO.SAI procedures)
.;
Begin "GET"
#-----------------------------------------------------------
# Own variables For use in GETting data
#-----------------------------------------------------------;
Own Integer
r,
c,
pz,
data,
twocounter,
by1,
by2,
by3,
device!name,
bytecounter,
flag,
I,
brchar,
eoflag,
mask4,
mask8,
word,
sstuffbytecnt,
channum,
num,
tempword1,
tempword2,
tempword3,
tempword4,
tempword5,
tempword6,
high1,
high2,
high3,
low1,
low2,
low3;
Safe Own Integer Array
sstuff[1:60];
COMMENT
.next page
.sss(Procedure CLOSEINDATA)
.index(Procedure CLOSEINDATA)
.;
Internal Simple Procedure CLOSEINDATA;
Begin "CLOSEINDATA"
#-----------------------------------------------------------
# THIS Procedure WILL RESET flag SO THAT If INPUT
# FROM A NEW FILE IS DESIRED THE INITIALIZATION CODE
# WILL BE ENTERED WITH A NEW FILE NAME SUPPLIED AS
# AN ARGUMENT TO GETDDTG.
#-----------------------------------------------------------;
flag_false;
RETURN;
End "CLOSEINDATA";
COMMENT
.NEXT PAGE
.SSS(Procedure DECODE)
.index(Procedure DECODE)
.;
Simple Procedure DECODE(Integer index);
Begin "DECODE"
#-------------------------------------------------------------
# THIS Procedure WILL EXTRACT THE 8 BIT byteS FROM TWO
# PDP10 wordS LOCATED IN THE BUFFER 'sstuff'. TWO PDP10
# wordS CONTAIN EXACTLY 9 PDP8/E 8 BIT byteS. WHEN THE
# Procedure IS CALLED A DETERMINATION IS MADE AS TO
# WHICH PAIR OF PDP10 wordS IN 'sstuff' SHOULD BE
# DECODED. THE UNPACKING ALWAYS USES TWO PDP10 wordS
# For EACH CALL.
#-------------------------------------------------------------;
Integer K;
k_sstuff[index];
high1_(K Land mask4) Lsh -28;
tempword1_(K Land (mask8 Lsh -4)) Lsh -24;
low1_(K Land (mask4 Lsh -12)) Lsh -20;
tempword2_(K Land (mask8 Lsh -16)) Lsh -12;
high2_(K Land (mask4 Lsh -24)) Lsh -4;
tempword3_K Land (mask8 Lsh -28);
k_sstuff[index+1];
low2_(K Land mask4) Lsh -32;
tempword4_(K Land (mask8 Lsh -4)) Lsh -24;
high3_(K Land (mask4 Lsh -12)) Lsh -16;
tempword5_(K Land (mask8 Lsh -16)) Lsh -12;
low3_(K Land (mask4 Lsh -24)) Lsh -8;
tempword6_K Land (mask8 Lsh -28);
End "DECODE";
COMMENT
.NEXT PAGE
.SSS(Procedure GET8BIT)
.index(Procedure GET8BIT)
.;
Internal Integer Simple Procedure GET8BIT;
Begin "GET8BIT"
#---------------------------------------------------------
# THIS Procedure WHEN GIVEN A byte numBER WILL EXTRACT
# THE NEXT SEQUENTIAL byte FROM THE BUFFER 'sstuff'.
#---------------------------------------------------------;
Integer
L,
K,
byte;
k_sstuffbytecnt MOD 270;
#----------------------------------------------------------
# If K=0 THE 'sstuff' BUFFER MUST BE FILLED FROM THE DISK
# DISK FILE THAT WAS SPECIFIED. THIRTY PDP10 wordS ARE
# READ FROM DISK. THIS numBER REPRESENTS 270 byteS WHICH
# APPROXIMATES A 256 byte Iline AND IS ALSO DIVISIBLE BY 9
# (THE numBER OF PDP8/E wordS IN TWO PDP10 wordS).
#-------------------------------------------------------------;
If K=0 Then
Begin "REFILL-BUFFER"
ARRYIN(channum,sstuff[1],60);
sstuffbytecnt_0;
word_-1;
End "REFILL-BUFFER";
#---------------------------------------------------------
# KEEP TRACK OF THE numBER OF byteS REMOVED FROM 'sstuff'.
#--------------------------------------------------------;
sstuffbytecnt_sstuffbytecnt+1;
#---------------------------------------------------------
# DETERMINE WHICH ONE OF THE 9 possible byteS TO
# RETRIEVE FROM THE PDP10 word PAIR.
#---------------------------------------------------------;
bytecounter_bytecounter+1;
L_((bytecounter-1) MOD 9);
#----------------------------------------------------------
# If L=0 IT IS NECESSARY TO DECODE THE PDP10 word PAIR
# INTO IT comPONENT PARTS WHICH WILL Then BE PIECED
# TOGETHER TO For AN 8 BIT byte.
#----------------------------------------------------------;
If L=0 Then DECODE(word_word+2);
#-------------------------------------------------------------
# NOW GET THE CORRECT byte.
#------------------------------------------------------------;
Case l Of
Begin "PIECEIT"
byte_tempword1;
byte_tempword2;
byte_high1 Lor low1;
byte_tempword3;
byte_tempword4;
byte_high2 Lor low2;
byte_tempword5;
byte_tempword6;
byte_high3 Lor low3;
End "PIECEIT";
#----------------------------------------------------------
# NOW THAT THE byte HAS FINALLY BEEN RETRIEVED, RETURN IT
# TO THE CALLER.
#---------------------------------------------------------;
Return(byte);
End "GET8BIT";
COMMENT
.NEXT PAGE
.SSS(Procedure GET12BIT)
.index(Procedure GET12BIT)
.;
Internal Integer Simple Procedure GET12BIT;
Begin "GET12BIT"
#
# Return a 12-bit byte from the input buffer
# already Opened with GETDDTG;
If twocounter=2 Then
Begin "read-3-bytes"
by1_GET8BIT;
by2_GET8BIT;
by3_GET8BIT;
twocounter_0;
End "read-3-bytes";
twocounter_twocounter+1;
If twocounter=1
Then Return (by1 Lor ((by3 Lsh 4) Land '7400))
Else Return (by2 Lor ((by3 Lsh 8) Land '7400));
End "GET12BIT";
COMMENT
.NEXT PAGE
.SSS(Procedure GETLINE)
.index(Procedure GETLINE)
.;
Internal Simple Procedure GETLINE(Reference Integer Array Iline);
Begin "GETLINE"
#---------------------------------------------------------
# GET THE NEXT 256 byteS If the not the first header call.
#--------------------------------------------------------;
For num_0 Step 1 Until 255 Do Iline[num]_GET8BIT;
RETURN;
End "GETLINE";
COMMENT
.NEXT PAGE
.sss(Procedure GETDDTG)
.INDEX(Procedure GETDDTG)
.;
Internal Boolean Simple Procedure GETDDTG( String io!file!name;
Reference Integer Array iheader);
Begin "GETDDTG"
Integer iomode;
#--------------------------------------------------------
# This Procedure is used to LOOKUP the file and
# get the header
#--------------------------------------------------------;
#-----------------------------------------------------------
# INITIALIZE SOME VARIBLES. notE THAT TWO mask wordS
# ARE DEFINED. 'mask4' IS USED TO mask OUT THOSE PORTIONS
# THE PDP10 wordS THAT CORRESPOND TO THE high AND low
# 4 BIT PACKING OF THE PDP8/E word. SIMILARLY 'mask8'
# CORRESPONDS TO THOSE PORTIONS OF THE PDP8/E wordS
# THAT ARE 8 CONTIGUOUS BITS.
#-----------------------------------------------------------;
If flag
Then Return(True)
Else flag_true;
mask4_'740000000000;
mask8_'776000000000;
word_-1;
sstuffbytecnt_0;
" Strip off the device name and use it instead of DSK:"
device!name_"DSK";
For i_1 Step 1 Until length(io!file!name) Do
If Equ(io!file!name[i For 1],":")
Then
Begin "strip"
device!name_io!file!name[1 to i-1];
io!file!name_io!file!name[i+1 to inf];
End "strip";
If iheader[0]="N"
Then iomode_0 Else iomode_'10;
Open(channum_GETCHAN,
device!name,iomode,10,0,68000,brchar,eoflag);
LOOKUP(channum,io!file!name,eoflag);
If eoflag
Then Return(True);
If header[0]="N"
Then Return(False);
bytecounter_0;
twocounter_2;
#---------------------------------------------------
# CHECK TO DETERMINE WHETHER FILE CONTAINS A
# header. If SO EXTRACT IT INTO THE Integer array
# 'iheader'.
#--------------------------------------------------;
If iheader[0]=1
Then
Begin "BHEAD"
Integer Temp, Jh1,Jh2;
For num_0 Step 1 Until 127 Do
Begin
jh1_2*num;
jh2_jh1+1;
iheader[jh1]_GET8BIT;
iheader[jh2]_GET8BIT;
temp_GET8BIT;
iheader[jh1]_iheader[jh1] Lor
((temp Lsh 4) Land '7400);
iheader[jh2]_iheader[jh2] Lor
((temp Lsh 8) Land '7400);
End;
End "BHEAD";
# --------------------------------------------------------
# Force the header size for earlier DDTG types.
# --------------------------------------------------------;
i_iheader[5];
If (i=9) or (i=11)
Then iheader[80]_255;
If (i=10) or (i=12)
Then iheader[80]_1023;
Return(false);
End "GETDDTG";
COMMENT
.NEXT PAGE
.sss(Procedure CVTHEADER)
.INDEX(Procedure CVTHEADER)
.;
Internal Simple Procedure CVTHEADER(Reference Integer submode;
Reference String io!file!name, com;
Reference Integer Array iheader);
Begin "CVTHEADER"
Define CVI7(X) ="(IF ((X) Land '77) <'40
Then ((X) Land '77)+'100
Else IF ((X) Land '77)=0
Then '40 Else ((X) Land '77))";
Integer K,J;
# - convert a header Array into the
# submode inFormation (see table 2), the
# io!file!name, Comment (com) from oheader.;
# [CH.1] GET THE submode;
submode_iheader[5];
# [CH.2] GET THE io!file!name;
io!file!name_null;
For k_12 Step 1 Until 15 Do
Begin "MAKE-io!file!name"
# TRASH THE FIRST 4 null byteS;
# CONVERT THE LAST 2 6-BITS TO 7BIT;
J_iheader[K];
io!file!name_io!file!name&CVI7(J Lsh -6)&CVI7(J);
End "MAKE-io!file!name";
# [CH.3] GET THE Comment FIELD;
com_null;
For k_16 Step 1 Until 51 Do
Begin "MAKE-Comment"
# TRASH THE FIRST 4 null byteS;
# CONVERT THE LAST 2 6-BITS TO 7BIT;
If ((J_iheader[K]) Land '7700)=0 Then Done;
com_com&CVI7(j Lsh -6);
If (J Land '77)=0 Then Done;
com_com&CVI7(J);
End "MAKE-Comment";
End "CVTHEADER";
COMMENT
.NEXT PAGE
.sss(Procedure GETPIX)
.INDEX(Procedure GETPIX)
.;
Internal Boolean Simple Procedure GETPIX(
Reference Integer Array image3;
Reference String io!file!name, com;
Reference Integer Array iheader);
Begin "GETPIX"
Integer word,
i,
psize,
asize,
submode;
" Get the array size"
asize_ARRINFO(image3,0);
"set the header word so that read in the header"
If iheader[0] neq "N"
Then iheader[0]_1;
If GETDDTG(io!file!name,iheader) And iheader[0]=1
Then
Begin "failed"
CLOSEINDATA;
Return (True);
End "failed";
If iheader[0]="N"
Then
Begin "Read numbers"
Outstr("NUMBER mode"&crlf);
pz_Sqrt(4*(asize+1))-1;
For r_0 step 1 until pz Do
For c_0 step 1 until pz Do
Begin "Get datum"
data_Intin(channum) Land '777;
If eoflag
Then Done;
PACK2D(image3,r,c,data);
End "Get datum";
CLOSEINDATA;
Return(false);
End "Read numbers";
" go convert the header to the string Comment and filetype"
CVTHEADER(submode,io!file!name,com,iheader);
If (submode neq 1) And (submode neq 9) And
(submode neq 11) And (submode neq 15)
Then return (true);
" Determine the file image size"
If submode=15
Then i_iheader[80] Else i_255;
psize_( ( (((i Land '377)+1)^2)%4) min asize) - 1;
"Read in array size*4 bytes and store them in array image."
For word_0 Step 1 Until psize Do
image3[word]_(GET8BIT Lsh 27) Lor (GET8BIT Lsh 18) Lor
(GET8BIT Lsh 9) Lor GET8BIT;
CLOSEINDATA;
Return (false);
End "GETPIX";
COMMENT
.NEXT PAGE
.sss(Procedure GETBMASK)
.INDEX(Procedure GETBMASK)
.;
Internal Boolean Simple Procedure GETBMASK(
Reference Integer Array mask3;
Reference String io!file!name, com;
Reference Integer Array iheader);
Begin "GETBMASK"
Integer word,
asize,
submode;
" Get the array size"
asize_ARRINFO(mask3,0)-1;
"set the header word so that read in the header"
If iheader[0] neq "N"
Then iheader[0]_1;
If GETDDTG(io!file!name,iheader) And iheader[0]=1
Then
Begin "failed"
CLOSEINDATA;
Return (True);
End "failed";
If iheader[0]="N"
Then
Begin "Read numbers"
Outstr("NUMBER mode"&crlf);
pz_Sqrt(36*asize)-1;
For r_0 step 1 until pz Do
For c_0 step 1 until pz Do
Begin "Get datum"
data_Intin(channum) Land '1;
If eoflag
Then Done;
MSK!PACK2D(mask3,r,c,data);
End "Get datum";
CLOSEINDATA;
Return(false);
End "Read numbers";
" go convert the header to the string Comment and filetype"
CVTHEADER(submode,io!file!name,com,iheader);
If (submode neq 14)
Then Return(true);
"Read in array asize words and store them in array mask."
# note: must do modulo 36 bit input.....;
For word_0 step 2 until asize Do
Begin "pack it"
mask3[word]_(GET8BIT Lsh 28) Lor
(GET8BIT Lsh 20) Lor
(GET8BIT Lsh 12) Lor
(GET8BIT Lsh 4) Lor
(((i_GET8BIT) Lsh -4) Land '17);
" Protect the mask array from too much garbage data"
If (word+1) leq asize
Then
Begin "2nd word"
mask3[word+1]_(i Lsh 32) Lor
(GET8BIT Lsh 24) Lor
(GET8BIT Lsh 16) Lor
(GET8BIT Lsh 8) Lor
GET8BIT;
End "2nd word";
End "pack it";
CLOSEINDATA;
Return (false);
End "GETBMASK";
COMMENT
.NEXT PAGE
.sss(Procedure GETBOUNDARY)
.INDEX(Procedure GETBOUNDARY)
.;
Internal Boolean Simple Procedure GETBOUNDARY( Reference Integer
Array boundary3;
Reference String io!file!name, com;
Reference Integer Array iheader;
Reference Integer bnd!length);
Begin "GETBOUNDARY"
# the boundary is stored as 4 8-bit bytes/36 bit word
thus two (x,y) pairs are stored from left to right.
The occurance of (0,0) is illegal and denotes an eof;
Label all!Done;
Integer word,
x1,
x2,
y1,
y2,
asize,
submode;
" Get the array size"
asize_ARRINFO(boundary3,0)-1;
"set the header word so that read in the header"
If iheader[0] neq "N"
Then iheader[0]_1;
If GETDDTG(io!file!name,iheader) And iheader[0]=1
Then
Begin "failed"
CLOSEINDATA;
Return (True);
End "failed";
If iheader[0]="N"
Then
Begin "Read numbers"
Outstr("NUMBER mode"&crlf);
x1_-1; y1_-1;
pz_0;
While not eoflag Do
Begin "Get datum"
x2_x1;
y2_y1;
x1_Intin(channum) Land '377;
y1_Intin(channum) Land '377;
X!BND!PACK(boundary3,pz,x1);
Y!BND!PACK(boundary3,pz,y1);
If ((x1=0 and y1=0) And (x2=0 and y2=0)) Or
((pz_pz+1) > 2047)
Then Done;
End "Get datum";
CLOSEINDATA;
bnd!length_pz;
Outstr("Read "&CVS(pz)&" points"&crlf);
Return(false);
End "Read numbers";
" go convert the header to the string Comment and filetype"
CVTHEADER(submode,io!file!name,com,iheader);
If (submode neq 7) And (submode neq 8)
Then Return(true);
"Read in array size*4 bytes and store them in array boundary."
For word_0 Step 1 Until asize Do
Begin "pack it"
boundary3[word]_(x1_(GET8BIT Lsh 27)) Lor
(y1_(GET8BIT Lsh 18)) Lor
(x2_(GET8BIT Lsh 9)) Lor
(y2_GET8BIT);
If (x1=0 and y1=0)
Then
Begin "Done even"
bnd!length_2*(word);
Goto all!Done;
End "Done even";
If (x2=0 and y2=0)
Then
Begin "Done odd"
bnd!length_2*(word)+1;
Goto all!Done;
End "Done odd";
End "pack it";
all!Done: CLOSEINDATA;
Return (false);
End "GETBOUNDARY";
COMMENT
.NEXT PAGE
.sss(Procedure GETARRAY)
.INDEX(Procedure GETARRAY)
.;
Internal Boolean Simple Procedure GETARRAY( Reference Integer
Array data!array;
Reference String io!file!name, com;
Reference Integer Array iheader;
Reference Integer total!array!size);
Begin "GETARRAY"
# the ARRAY is stored as 3 12-bit bytes/36 bit word;
Integer word,
max!array!size,
submode;
" Get the maximum array size"
max!array!size_ARRINFO(data!array,0)-1;
"set the header word so that read in the header"
iheader[0]_1;
If GETDDTG(io!file!name,iheader)
Then Return (True);
" go convert the header to the string Comment and filetype"
If iheader[0]=1
Then
CVTHEADER(submode,io!file!name,com,iheader);
If (submode neq 16)
Then Return(true);
"Read in array size and store them in total!array!size"
total!array!size_iheader[3]+4096*iheader[2];
For word_0 Step 1 Until (total!array!size Min max!array!size)-1 Do
Begin "pack it"
data!array[word]_(GET12BIT Lsh 24) Lor
(GET12BIT Lsh 12) Lor GET12BIT;
End "pack it";
CLOSEINDATA;
Return (false);
End "GETARRAY";
End "GET";
COMMENT
.next page
.SS(PUT IO.SAI procedures)
.index(PUT IO.SAI procedures)
.;
Begin "PUT"
#------------------------------------------------------------
# THIS SECTION OF THE PROGRAM HANDLES OUTPUT TO A DISK
# FILE. AT EACH CALL, A 256 word BUFFER 'Oline' IS
# PASSED TO THESE ProcedureS. THE BUFFER IS STORED IN THE
# IN THE INTERMEDIATE BUFFER 'ostuff' WHICH WHEN FILLED
# WITH 270 PACKED byteS WILL BE DUMPED TO DISK FILE.
# WHEN THE USER HAS comPLETED WRITING THE FILE, A CALL
# TO THE Procedure closePIC WILL close THE DISK FILE
# AND MAKE IT AVAILABLE For LATER USE.
#---------------------------------------------------------;
Safe Own Integer Array
ostuff[1:60];
Own Integer
twocounter, oby1, oby2, oby3,
i,
odevice!name,
obyte,
k,
m,
n,
Onum,
ochannum,
Obrchar,
Oeoflag,
Oflag,
ostuffbytecnt,
obytecount,
oword;
COMMENT
.NEXT PAGE
.SSS(Procedure CLOSEOUTDATA)
.INDEX(Procedure CLOSEOUTDATA)
.;
Internal Simple Procedure CLOSEOUTDATA;
#---------------------------------------------------------
# THIS Procedure WILL close THE CURRENTLY OpenED
# OUTPUT PICTURE FILE, ForCING THE BUFFER TO BE
# WRITTEN. Oflag IS ALSO RESET SO THAT
# A NEW OUTPUT FILE MAY BE OpenED.
#---------------------------------------------------------;
Begin "CLOSEOUTDATA"
ARRYOUT(ochannum,ostuff[1],60);
close(ochannum);
Oflag_false;
End "CLOSEOUTDATA";
COMMENT
.NEXT PAGE
.SSS(Procedure PUT8BIT)
.INDEX(Procedure PUT8BIT)
.;
Internal Simple Procedure PUT8BIT(Integer obyten);
Begin "PUT8BIT"
#-----------------------------------------------------------
# THIS Procedure PACKS AN 8-BIT byte obyten INTO BUFFER 'ostuff'.
# WHENEVER THE BUFFER 'ostuff' IS FILLED (270
# PACKED byteS) THE BUFFER IS WRITTEN ONTO DISK.
#---------------------------------------------------------;
Integer
J,
K,
L;
#------------------------------------------------------------
# INCREMENT COUNT OF TOTAL numBER OF PACKED byteS IN THE
# INTERMEDIATE BUFFER 'ostuff'.
#-----------------------------------------------------------;
"make sure that it is only 8-bit"
obyten_obyten Land '377;
ostuffbytecnt_ostuffbytecnt+1;
#----------------------------------------------------------
# DETERMINE HOW byte IS TO BE PACKED. A byte WILL BE
# SPLIT INTO ITS high AND low comPONENTS OR LEFT IN
# TACK DEPEndING UPON WHERE IT IS TO PLACED IN THE
# INTERMEDIATE BUFFER 'ostuff'. THE VARIABLE 'L'
# DETERMINES WHICH DEcomPOSITION OPERATION (If ANY)
# IS TO BE PERForMED ON THE CURRENT byte. notE THAT
# L IS CYCLIC MODULO 9 AND 'oword' IS INCREMENTED
# BY TWO. THIS IS BECAUSE EXACTLY NINE byteS ARE
# PACKED IN TWO PDP10 wordS.
#---------------------------------------------------------;
If (obytecount MOD 9)=0 Then oword_oword+2;
obytecount_obytecount+1;
L_((obytecount-1) MOD 9);
#----------------------------------------------------------
# DETERMINE WHICH ONE OF THE NINE possible OPERATIONS
# TO PERForM.
#---------------------------------------------------------;
CASE L OF
Begin "SPLITIT"
"0" ostuff[oword]_(obyten Lsh 24) Lor ostuff[oword];
"1" ostuff[oword]_(obyten Lsh 12) Lor ostuff[oword];
"2" Begin "high1-low1"
J_((obyten Land '360) Lsh 28) Lor (k_ostuff[oword]);
ostuff[oword]_((obyten Land '17) Lsh 20) Lor J;
End "high1-low1";
"3" ostuff[oword]_obyten Lor ostuff[oword];
"4" ostuff[oword+1]_(obyten Lsh 24) Lor ostuff[oword+1];
"5" Begin "high2-low2"
ostuff[oword]_((obyten Land '360) Lsh 4) Lor ostuff[oword];
ostuff[oword+1]_((obyten Land '17) Lsh 32)
Lor ostuff[oword+1];
End "high2-low2";
"6" J_(obyten Lsh 12) Lor (k_ostuff[oword+1]);
"7" ostuff[oword+1]_obyten Lor J;
"8" Begin "high3-low3"
J_((obyten Land '360) Lsh 16) Lor (k_ostuff[oword+1]);
ostuff[oword+1]_((obyten Land '17) Lsh 8) Lor J;
End "high3-low3";
End "SPLITIT";
#---------------------------------------------------------
# If 'ostuffbytecnt' IS 270, THE INTERMEDIATE BUFFER
# 'ostuff' IS FULL. AT THIS POINT THE BUFFER 'ostuff'
# IS DUMPED TO DISK AND VARIABLE ARE RESET.
#---------------------------------------------------------;
If ostuffbytecnt=270 Then
Begin "DUMPIT"
ARRYOUT(ochannum,ostuff[1],60);
ARRCLR(ostuff);
oword_-1;
ostuffbytecnt_0;
End "DUMPIT";
End "PUT8BIT";
COMMENT
.NEXT PAGE
.SSS(Procedure PUT12BIT)
.INDEX(Procedure PUT12BIT)
.;
Internal Simple Procedure PUT12BIT(Integer N12BIT);
Begin "PUT12BIT"
#
# write a 12-bit byte N12BIT into the output buffer
# already Opened with PUTLINE;
If twocounter=2 Then
Begin "write-3-bytes"
PUT8BIT(oby1);
PUT8BIT(oby2);
PUT8BIT(oby3);
twocounter_0;
End "write-3-bytes";
twocounter_twocounter+1;
If twocounter=1
Then
Begin "pack-word-1"
oby1 _ n12bit Land '377;
oby3 _ (n12bit Lsh -4) Land '7400;
End "pack-word-1"
Else
Begin "pack-word-2"
oby2 _ n12bit Land '377;
oby3 _ (n12bit Lsh -8) Land '7400;
End "pack-word-2";
End "PUT12BIT";
COMMENT
.NEXT PAGE
.SSS(Procedure PUTLINE)
.INDEX(Procedure PUTLINE)
.;
Internal Simple Procedure PUTLINE(Integer Array Oline);
#-------------------------------------------------------------
# THIS Procedure ACCEPTS AS ARGUMENTS A 256 word BUFFER
# 'Oline' (THE DATA TO BE WRITTEN IN THE DISK FILE).
# THE Procedure IS CALLED WHENEVER
# THE USER DESIRES TO write A 256 byteS OF DATA TO THE
# DISK. THE DATA IS WRITTEN SEQUENTIALLY WITH EACH CALL.
#------------------------------------------------------------;
Begin "PUTLINE"
# If Oflag=TRUE Then write out the line;
#------------------------------------------------------------;
If Oflag Then
Begin "write-line"
For Onum_0 Step 1 Until 255 Do
Begin
#-------------------------------------------------------
# AFTER EVERY 9 byteS A PAIR OF PDP10 wordS
# IN THE INTERMEDIATE BUFFER 'ostuff' IS FILLED.
# THE index INTO THIS BUFFER IS INCREMENTED BY 2
# WHENEVER THIS OCCURS.
#-------------------------------------------------------;
PUT8BIT(Oline[Onum]);
End;
End "write-line";
End "PUTLINE";
COMMENT
.NEXT PAGE
.SSS(Procedure PUTDDTG)
.INDEX(Procedure PUTDDTG)
.;
Internal Boolean Simple Procedure PUTDDTG(String Oio!file!name;
Integer Array oheader);
Begin "PUTDDTG"
# ENTER THE io!file!name Oio!file!name AND RETURN True If not
# possible, Then write oheader If oheader[0] not 0;
#------------------------------------------------------------
# THIS SECTION OF THE PROGRAM HANDLES OUTPUT TO A DISK
# FILE. AT EACH CALL, A 256 word BUFFER 'Oline' IS
# PASSED TO THESE ProcedureS. THE BUFFER IS STORED IN THE
# IN THE INTERMEDIATE BUFFER 'ostuff' WHICH WHEN FILLED
# WITH 270 PACKED byteS WILL BE DUMPED TO DISK FILE.
# WHEN THE USER HAS comPLETED WRITING THE FILE, A CALL
# TO THE Procedure closePIC WILL close THE DISK FILE
# AND MAKE IT AVAILABLE For LATER USE.
#---------------------------------------------------------;
#------------------------------------------------------
# THE FIRST TIME A REQUEST IS MADE TO write A
# A BUFFER THE FILE IS OpenED AND VARIABLES ARE
# INITIALIZED.
#------------------------------------------------------;
If Oflag Then Return(True);
oword_-1;
ostuffbytecnt_0;
" Strip off the device name and use it instead of DSK:"
odevice!name_"DSK";
For i_1 Step 1 Until length(oio!file!name) Do
If Equ(oio!file!name[i For 1],":")
Then
Begin "strip"
odevice!name_oio!file!name[1 to i-1];
oio!file!name_oio!file!name[i+1 to inf];
End "strip";
Open(ochannum_GETCHAN,odevice!name,'10,0,10,0,Obrchar,Oeoflag);
ENTER(ochannum,Oio!file!name,Oeoflag);
If Oeoflag Then RETURN (True);
obytecount_0;
#------------------------------------------------------
# If THE header word header[0] IS 0, A header IS not
# TO BE WRITTEN OTHERWISE write THE header.
#-----------------------------------------------------;
If oheader[0] neq 0 Then
Begin "write-HEAD"
For Onum_0 Step 1 Until 127 Do
Begin
PUT8BIT(oheader[(2*Onum)] Land '377);
PUT8BIT(oheader[(2*Onum+1)] Land '377);
PUT8BIT(
((oheader[(2*Onum)] Lsh -4) Land '360)
Lor
((oheader[(2*Onum+1)] Lsh -8) Land '017));
End;
End "write-HEAD";
Oflag_TRUE;
RETURN (false);
End "PUTDDTG";
COMMENT
.NEXT PAGE
.SSS(Procedure MAKEHEADER)
.INDEX(Procedure MAKEHEADER)
.;
Internal Simple Procedure MAKEHEADER(Integer submode;
String Oio!file!name, com;
Reference Integer Array oheader);
Begin "MAKEHEADER"
Integer K,L,M;
Label ext;
INTEGER date,day,month,year;
String S1,S2,S,SS;
# - setup an initial header Array based on the
# submode inFormation (see table 2), the
# io!file!name, Comment (com) and store it in oheader.;
# [MH.1] ZERO THE header;
ARRCLR(oheader);
# [MH.2] TEST For ILLEGAL submode;
If not(1 leq submode leq 16) Then
Begin "FAILED"
OUTSTR("ILLEGAL DDTG submode!"&CRLF);
RETURN;
End "FAILED";
# [WH.3] START PACKING SUBFIELDS (A) THROUGH (H);
CASE submode OF
Begin "SET (i)"
Begin "0 - illegal"
Outstr("NEVER IN MAKHEADER"&crlf);
End "0 - illegal";
Begin "1- BM 8-BIT"
oheader[0]_7;
oheader[1]_171;
oheader[2]_16;
oheader[3]_0;
oheader[4]_'0203;
oheader[5]_1;
oheader[6]_0;
oheader[7]_0;
oheader[8]_0;
End "1- BM 8-BIT";
Begin "2- BM 16-BIT"
oheader[0]_7;
oheader[1]_342;
oheader[2]_16;
oheader[3]_0;
oheader[4]_'0403;
oheader[5]_2;
oheader[6]_3;
oheader[7]_0;
oheader[8]_0;
End "2- BM 16-BIT";
Begin "3 mask"
oheader[0]_10;
oheader[1]_8;
oheader[2]_0;
oheader[3]_1024;
oheader[4]_2;
oheader[5]_3;
oheader[6]_1;
oheader[7]_3;
oheader[8]_1;
End "3 mask";
Begin "4 QMT"
oheader[0]_11;
oheader[1]_8;
oheader[2]_0;
oheader[3]_1018;
oheader[4]_6;
oheader[5]_4;
oheader[6]_1;
oheader[7]_4;
oheader[8]_1;
End "4 QMT";
Begin "5 GRAF-PEN 10-BIT VECTOR"
oheader[0]_12;
oheader[1]_0;
oheader[2]_0;
oheader[3]_0;
oheader[4]_2;
oheader[5]_5;
oheader[6]_1;
oheader[7]_1;
oheader[8]_1;
End "5 GRAF-PEN 10-BIT VECTOR";
Begin "6 GRAF-PEN 10-BIT NOVECTOR"
oheader[0]_12;
oheader[1]_0;
oheader[2]_0;
oheader[3]_0;
oheader[4]_2;
oheader[5]_6;
oheader[6]_1;
oheader[7]_1;
oheader[8]_1;
End "6 GRAF-PEN 10-BIT NOVECTOR";
Begin "7 GRAF-PEN 8-BIT VECTOR"
oheader[0]_12;
oheader[1]_0;
oheader[2]_0;
oheader[3]_0;
oheader[4]_'0403;
oheader[5]_7;
oheader[6]_0;
oheader[7]_1;
oheader[8]_0;
End "7 GRAF-PEN 8-BIT VECTOR";
Begin "8 GRAF-PEN 8-BIT NOVECTOR"
oheader[0]_12;
oheader[1]_0;
oheader[2]_0;
oheader[3]_0;
oheader[4]_'0403;
oheader[5]_8;
oheader[6]_0;
oheader[7]_1;
oheader[8]_0;
End "8 GRAF-PEN 8-BIT NOVECTOR";
Begin "9 256 RASTER"
oheader[0]_13;
oheader[1]_171;
oheader[2]_16;
oheader[3]_0;
oheader[4]_'0203;
oheader[5]_9;
oheader[6]_0;
oheader[7]_0;
oheader[8]_0;
End "9 256 RASTER";
Begin "10 1024 RASTER"
oheader[0]_13;
oheader[1]_1736;
oheader[2]_64;
oheader[3]_0;
oheader[4]_'0203;
oheader[5]_10;
oheader[6]_0;
oheader[7]_0;
oheader[8]_0;
End "10 1024 RASTER";
Begin "11 256 RASTER-maskED"
oheader[0]_13;
oheader[1]_171;
oheader[2]_16;
oheader[3]_0;
oheader[4]_'0203;
oheader[5]_11;
oheader[6]_0;
oheader[7]_0;
oheader[8]_0;
End "11 256 RASTER-maskED";
Begin "12 1024 RASTER-maskED"
oheader[0]_13;
oheader[1]_1736;
oheader[2]_64;
oheader[3]_0;
oheader[4]_'0203;
oheader[5]_12;
oheader[6]_0;
oheader[7]_0;
oheader[8]_0;
End "12 1024 RASTER-maskED";
Begin "13 STATE"
oheader[0]_15;
oheader[1]_1;
oheader[2]_0;
oheader[3]_0;
oheader[4]_2;
oheader[5]_13;
oheader[6]_1;
oheader[7]_4;
oheader[8]_1;
End "13 STATE";
Begin "14 BINARY MASK"
oheader[0]_16;
oheader[1]_0;
oheader[2]_0;
oheader[3]_0;
oheader[4]_12;
oheader[5]_14;
oheader[6]_4;
oheader[7]_5;
oheader[8]_0;
End "14 BINARY MASK";
Begin "15 VARIABLE SIZE IMAGE"
oheader[0]_17;
oheader[1]_0;
oheader[2]_0;
oheader[3]_0;
oheader[4]_'0203;
oheader[5]_15;
oheader[6]_0;
oheader[7]_0;
oheader[8]_0;
End "15 VARIABLE SIZE IMAGE";
Begin "16 36-BIT PDP10 DATA"
oheader[0]_18;
oheader[1]_0;
oheader[2]_0;
oheader[3]_0;
oheader[4]_'0301;
oheader[5]_16;
oheader[6]_2;
oheader[7]_6;
oheader[8]_1;
End "16 36-BIT PDP10 DATA";
End "SET (i)";
# [MH.4] SET THE DATE, WONDoW COORDINATES;
call(0,"DATE");
day_date-((date%31)*31)+1;
month_(date%31)-(((date%31)%12)*12)+1;
year_4+(date%(31*12));
oheader[9]_((month Lsh 8) Land '7400)
Lor ((day Lsh 3) Land '0370)
Lor (year Land '0007);
oheader[10]_0;
oheader[11]_0;
# [MH.5] CONVERT THE FILE NAME AND EXTENSION;
" convert the name to upper case"
ss_null;
While length(oio!file!name) Do
If (k_lop(oio!file!name)) geq '141 and k leq '172
Then ss_ss & (k-'40)
Else ss_ss & k;
oio!file!name_ss;
For k_ 12 Step 1 Until 15 Do
Begin "CVT-io!file!name"
If (L_LOP(Oio!file!name))="." Then GOTO EXT;
If (M_LOP(Oio!file!name))="." Then M_null;
oheader[K]_((L Land '77) Lsh 6) Lor (M Land '77);
End "CVT-io!file!name";
" Do THE EXTENSION"
EXT: L_LOP(Oio!file!name);
M_LOP(Oio!file!name);
oheader[K]_((L Land '77) Lsh 6) Lor (M Land '77);
# [MH.6] CONVERT THE 72 CHARACTER Comment;
" convert the name to upper case"
ss_null;
While length(com) Do
If (k_lop(com)) geq '141 and k leq '172
Then ss_ss & (k-'40)
Else ss_ss & k;
com_ss;
For k_ 16 Step 1 Until 51 Do
Begin "CVT-Comment"
L_LOP(com);
M_LOP(com);
oheader[K]_((L Land '77) Lsh 6) Lor (M Land '77);
End "CVT-Comment";
End "MAKEHEADER";
# ----------------------------------------------------;
COMMENT
.NEXT PAGE
.SSS(Procedure PUTPIX)
.INDEX(Procedure PUTPIX)
.;
Internal Boolean Simple Procedure PUTPIX(
Reference Integer Array image1;
String io!file!name, com; Reference Integer Array oheader);
Begin "PUTPIX"
Integer i,
ddtgtype,
asize,
word;
" write out array size*4 bytes from array image."
asize_ARRINFO(image1,0)-1;
" Enter the output file and write the oheader"
" note that submode 9 and 11 is the packed 256x256 galv.scan,
only make the oheader If not 9 or 11"
If (oheader[0]=0) or
((oheader[5] neq 9) And (oheader[5] neq 11))
Then
Begin "make header"
If asize < 16000
Then ddtgtype_15
Else ddtgtype_9;
MAKEHEADER(ddtgtype,io!file!name,com,oheader);
End "make header";
" set the size"
oheader[80]_sqrt(4*(asize+1))-1;
If PUTDDTG(io!file!name,oheader) Then Return(True);
For i_0 Step 1 Until asize Do
Begin "pack 4 bytes"
word_image1[i];
PUT8BIT((word Lsh -27) Land '777);
PUT8BIT((word Lsh -18) Land '777);
PUT8BIT((word Lsh -9) Land '777);
PUT8BIT(word Land '777);
End "pack 4 bytes";
CLOSEOUTDATA;
Return (false);
End "PUTPIX";
COMMENT
.NEXT PAGE
.SSS(Procedure PUTBMASK)
.INDEX(Procedure PUTBMASK)
.;
Internal Boolean Simple Procedure PUTBMASK(
Reference Integer Array mask1;
String io!file!name, com; Reference Integer Array oheader);
Begin "PUTBMASK"
Integer i,
asize,
word;
" write out array asize words from array mask."
asize_ARRINFO(mask1,0)-1;
" Enter the output file and write the oheader"
" note that submode 14 is the packed binary mask,
only make the oheader If not 14"
If (oheader[0]=0) or (oheader[5] neq 14)
Then MAKEHEADER(14,io!file!name,com,oheader);
" set the mask size as (power of 2) -1"
oheader[80]_sqrt((asize-1)*36);
If PUTDDTG(io!file!name,oheader) Then Return(True);
For word_0 step 2 until asize Do
Begin "pack it"
m_mask1[word];
" output the first word"
PUT8BIT(m Lsh -28);
PUT8BIT(m Lsh -20);
PUT8BIT(m Lsh -12);
PUT8BIT(m Lsh -4);
" output the 2nd word"
" dont access array if odd"
If (word+1) leq asize
Then
Begin "2nd word"
n_mask1[word+1];
PUT8BIT((m Lsh 4) Lor (n Lsh -32));
PUT8BIT(n Lsh -24);
PUT8BIT(n Lsh -16);
PUT8BIT(n Lsh -8);
PUT8BIT(n);
End "2nd word";
End "pack it";
CLOSEOUTDATA;
Return (false);
End "PUTBMASK";
COMMENT
.NEXT PAGE
.SSS(Procedure PUTBOUNDARY)
.INDEX(Procedure PUTBOUNDARY)
.;
Internal Boolean Simple Procedure PUTBOUNDARY(
Reference Integer Array boundary1;
String io!file!name, com; Reference Integer Array oheader;
Integer bnd!length);
Begin "PUTBOUNDARY"
Label all!Done;
Integer i,
asize,
bsize,
notthere,
x1,
x2,
y1,
y2,
word;
" write out array size*4 bytes from array boundary."
asize_ARRINFO(boundary1,0)-1;
" Enter the output file and write the oheader"
" note that submode 7 or 8 is the packed boundary ,
only make the oheader If not 7 or 8"
If (oheader[0]=0) or
((oheader[5] neq 7) And (oheader[5] neq 8))
Then
Begin "make header"
MAKEHEADER(8,io!file!name,com,oheader);
End "make header";
" set the size"
oheader[80]_bnd!length;
notthere_PUTDDTG(io!file!name,oheader);
If notthere
Then Return(True);
bsize_((bnd!length+1)%2 min asize);
For i_0 Step 1 Until bsize Do
Begin "pack 4 bytes"
word_boundary1[i];
PUT8BIT(x1_((word Lsh -27) Land '777));
PUT8BIT(y1_((word Lsh -18) Land '777));
PUT8BIT(x2_((word Lsh -9) Land '777));
PUT8BIT(y2_(word Land '777));
If ((x1=0) and (y1=0)) or ((x2=0) and (y2=0))
Then Goto All!Done;
End "pack 4 bytes";
all!Done:
" write 4 more zeros for eof"
PUT8BIT(0);
PUT8BIT(0);
PUT8BIT(0);
PUT8BIT(0);
CLOSEOUTDATA;
Return (false);
End "PUTBOUNDARY";
COMMENT
.NEXT PAGE
.SSS(Procedure PUTARRAY)
.INDEX(Procedure PUTARRAY)
.;
Internal Boolean Simple Procedure PUTARRAY(
Reference Integer Array data!array;
String io!file!name, com;
Reference Integer Array oheader;
Integer total!array!size, array!type, number!tuples);
Begin "PUTARRAY"
Integer i,
word;
" write out array size*3 bytes from array data!array"
" Enter the output file and write the oheader"
" note that submode 16 is the packed 36-bit ARRAY ,
only make the oheader If not 16"
If (oheader[5] neq 16)
Then MAKEHEADER(16,io!file!name,com,oheader);
" set the size"
oheader[2]_total!array!size/4096;
oheader[3]_(total!array!size Land '7777);
oheader[80]_array!type;
oheader[81]_number!tuples;
If PUTDDTG(io!file!name,oheader)
Then Return(True);
For i_0 Step 1 Until total!array!size Do
Begin "pack 3 bytes"
word_data!array[i];
PUT12BIT(word Lsh -24);
PUT12BIT(word Lsh -12);
PUT12BIT(word);
End "pack 3 bytes";
CLOSEOUTDATA;
Return (false);
End "PUTARRAY";
End "PUT";
End "IO.SAI";