dos_compilers/Digital Research PLI-86 v1/RNDCOPY.PLI
2024-06-30 12:01:25 -07:00

254 lines
8.5 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diocopy: procedure options(main);
/*****************************************************************************
* *
* I B M D O S D i r e c t F u n c t i o n C a l l s *
* *
******************************************************************************
******************************************************************************
* *
* This program tests many of the IBM DOS direct function calls. The tests *
* are not particularly complicated, but they do serve as examples for using *
* direct DOS function calls from PL/I-86. *
* *
******************************************************************************
* *
* NOTE! YOU SHOULD STUDY THE IBM DOS DOCUMENTATION FOR MORE COMPLETE *
* INFORMATION BEFORE USING ANY OF THESE FUNCTIONS IN YOUR PROGRAMS. *
* *
* *
******************************************************************************
* To use this program, enter the command: *
* *
* A>rndcopy filename.typ newname.typ *
*****************************************************************************/
/* DIOMOD.DCL contains the declarations for the DOS functions */
%include 'diomod.dcl';
%replace
true by '1'b,
false by '0'b,
buffer_size by 64; /* word size of 128 byte buffer */
declare
(tempsrc,tempdest) char(14) var,
d_space(37) bit(8),
eofile bit(1),
ret_code fixed(7),
(i,m,num_buffs) fixed(15),
memory (0:0) bit(16) based(memptr());
declare /* source file FCB */
srcfcb_ptr ptr,
1 source_file based(srcfcb_ptr),
2 drive fixed(7),
2 name character(8),
2 type character(3),
2 current_block bit(16),
2 record_size bit(16),
2 file_size(2) bit(16),
2 date bit(16),
2 reserved(10) bit(8),
2 current_rec bit(8),
2 rand_rec_no(2) bit(16);
declare /* destination file FCB */
destfcb_ptr pointer,
1 dest_file based(destfcb_ptr),
2 drive fixed(7),
2 name character(8),
2 type character(3),
2 current_block bit(16),
2 record_size bit(16),
2 file_size(2) bit(16),
2 date bit(16),
2 reserved(10) bit(8),
2 current_rec bit(8),
2 rand_rec_no(2) bit(16);
/****************************************************************************/
/* M a i n P r o g r a m */
/****************************************************************************/
/* initialize source file FCB */
srcfcb_ptr = dfcb0();
destfcb_ptr = addr(d_space); /* set up destination FCB out in memory */
/* set drives to be default; may be changed by OPEN */
source_file.drive = 0;
dest_file.drive = 0;
/* get the file names */
call get_names(tempsrc,tempdest);
/* split up name & type; make sure they're the right length, padded with
trailing blanks if necessary */
i = index(tempsrc,'.');
source_file.name = substr(tempsrc,1,i-1) || ' ';
source_file.name = substr(source_file.name,1,8);
source_file.type = substr(tempsrc,i+1) || ' ';
source_file.type = substr(source_file.type,1,3);
/* do the same for the destination name */
i = index(tempdest,'.');
/* the following PUT EDIT statements are needed to make the register
allocator work right */
PUT SKIP EDIT('1.DEST_FILE.NAME=',DEST_FILE.NAME,'<--') (A,A,A);
dest_file.name = substr(tempdest,1,i-1) || ' ';
PUT SKIP EDIT('2.DEST_FILE.NAME=',DEST_FILE.NAME,'<--') (A,A,A);
dest_file.name = substr(dest_file.name,1,8);
PUT SKIP EDIT('3.DEST_FILE.NAME=',DEST_FILE.NAME,'<--') (A,A,A);
dest_file.type = substr(tempdest,i+1,3) || ' ';
PUT SKIP EDIT('1.DEST_FILE.TYPE=',DEST_FILE.TYPE,'<--') (A,A,A);
dest_file.type = substr(dest_file.type,1,3);
PUT SKIP EDIT('2.DEST_FILE.TYPE=',DEST_FILE.TYPE,'<--') (A,A,A);
/* open the source file, if possible */
if open(addr(source_file)) = -1 then do;
put skip list('No Source File');
call reboot();
end;
/* create the destination file */
if make(destfcb_ptr) = -1 then do;
put skip list('No Directory Space');
call reboot();
end;
/* figure out how many buffers to use */
num_buffs = divide(memwds(),buffer_size,15);
if num_buffs = 0 then do;
put skip list('No Memory Available for Buffer Space');
call reboot();
end;
/* now do the read */
eofile = false;
do while (^eofile);
m = 0;
/* fill buffers */
do i = 0 repeat (i+1) while(i < num_buffs);
call setdma(addr(memory(m)));
m = m + buffer_size;
if rdran(addr(source_file)) ^= 0 then do;
eofile = true;
/* truncate buffer */
num_buffs = i;
end;
/* increment the random record field */
if source_file.rand_rec_no(1) = 'FFFF'b4 then do;
source_file.rand_rec_no(2) =
add(source_file.rand_rec_no(2),'0001'b4);
source_file.rand_rec_no(1) = '0000'b4;
end;
source_file.rand_rec_no(1) =
add(source_file.rand_rec_no(1),'0001'b4);
end;
m = 0;
/* write buffers */
do i = 0 to num_buffs - 1;
call setdma(addr(memory(m)));
m = m + buffer_size;
if wrran(destfcb_ptr) ^= 0 then do;
put skip list('Disk Full');
call reboot();
end;
/* increment the random record field */
if dest_file.rand_rec_no(1) = 'FFFF'b4 then do;
dest_file.rand_rec_no(2) =
add(dest_file.rand_rec_no(2),'0001'b4);
dest_file.rand_rec_no(1) = '0000'b4;
end;
dest_file.rand_rec_no(1) =
add(dest_file.rand_rec_no(1),'0001'b4);
end;
end;
/* close destination file */
if close(destfcb_ptr) = -1 then do;
put skip list('Disk is Read Only');
call reboot();
end;
/* all done! */
put skip list('File Copied');
call reboot();
/****************************************************************************/
/* S u b r o u t i n e s */
/****************************************************************************/
get_names: procedure(src,dest);
/* get the filenames from the command line */
declare
(src,dest) char(14) var, /* file names */
buffptr pointer,
cmdline char(127) var based(buffptr),
indx fixed;
buffptr = dbuff();
/* delete any leading blanks */
do while(substr(cmdline,1,1) = ' ');
cmdline = substr(cmdline,2);
end;
/* find the break between the two filenames */
indx = index(cmdline,' ');
/* the next statement is needed to make the register allocator work
right */
PUT SKIP LIST('INDX=',INDX);
/* get the source filename */
src = substr(cmdline,1,indx-1);
cmdline = substr(cmdline,indx+1);
/* delete any intervening blanks */
do while(substr(cmdline,1,1) = ' ');
cmdline = substr(cmdline,2);
end;
/* put the rest of the command line in destination filename */
dest = substr(cmdline,1,14);
end get_names;
/****************************************************************************/
/* U n s i g n e d A r i t h m e t i c F u n c t i o n s */
/****************************************************************************/
add: procedure((x),(y)) returns(bit(16));
/* 16 bit unsigned add */
declare
(x,y,z) bit(16),
(xp,yp,zp) ptr,
su bit(16),
sv bit(16),
sw bit(16),
u fixed bin(15) based(xp),
v fixed bin(15) based(yp),
w fixed bin(15) based(zp);
xp = addr(x);
yp = addr(y);
zp = addr(z);
/* get sign bits of u and v */
su = x & '8000'b4;
sv = y & '8000'b4;
/* zero sign bits of x and y */
x = x & '7FFF'b4;
y = y & '7FFF'b4;
w = u + v;
sw = z & '8000'b4;
/* get sign bit of z */
z = z & '7FFF'b4;
/* XOR of su, sv, sw */
sw = xor(xor(su,sv),sw);
/* put in sign bit of z */
z = z | sw;
return(z);
end add;
xor: procedure(x,y) returns(bit(16));
/* 16 bit logical exclusive or */
declare
(x,y) bit(16);
return(bool(x,y,'0110'b));
end xor;
end diocopy;