home *** CD-ROM | disk | FTP | other *** search
- {TRUN is a program that runs Turbo .CHN type files from CP/M.
-
- Wait a minute...why make .CHN files at all? Turbo, after all,
- generates .COM files that run directly from CP/M.
- The problem is: each Turbo .COM file takes a minimum of
- 8 kb on your disk (for the Turbo runtime library).
- You can save 8 kb/file by generating .CHN files instead,
- but now you must have a way of running these. To do this,
- compile TRUN.COM, then compile your program YOURPROG.CHN.
- (Use the same start and end addresses for all files.)
- Now, from CP/M, type
-
- A>trun d:yourprog
-
- And you're in business.
-
- Written by Jim Zisfein and uploaded 10/14/85 to the
- Blaise Pascal RCP/M, (212)-604-1930, for the public
- domain. Please send comments, addressed to me, to
- the Blaise Pascal RCP/M.}
-
- label boot;
-
- const
- cr=^M^J;
-
- {If you type A>peace b:with.you at the CP/M prompt, PEACE.COM is loaded
- and run, and memory locations $005c to $005c+11 are loaded with information
- about file WITH.YOU on drive B: (ref: Lindsay J, Introduction to CP/M
- Assembly Language, Hayden, 1984, p.38). This region is called the file
- control buffer (fcb).}
-
- fcb=$5c;
-
- var
- n: integer; {all purpose variable}
- entrycode: byte; {returned by bdos calls #17 and #18}
- chainfile: file; {file variable for .CHN file}
- filename: string[14]; {name of .CHN file}
-
- {The direct memory address (dma) is where CP/M will, on command, retrieve
- information on the disk directory (ref: Lindsay, p.43).}
-
- dma: array[0..127] of byte;
-
- {Writeentry prints a directory of .CHN files on the logged disk. "Start"
- is the location within the dma array where CP/M placed the file name}
-
- procedure writeentry(start: integer);
- var n: byte;
- begin
- if (char(mem[addr(dma)+start+9])='C') and
- (char(mem[addr(dma)+start+10])='H') and
- (char(mem[addr(dma)+start+11])='N') then begin
- write(' ');
- for n:=start+1 to start+8 do write(char(mem[addr(dma)+n]));
- writeln;
- end;
- end;
-
- {TRUN - main program}
-
- begin
-
- {TRUN first attempts to chain to the file in the fcb (see above).
- This file, named "filename", consists of an optional drive name,
- a 1-8 character file identifier, and the .CHN extension.}
-
- {The disk drive, specified in the CP/M command line, is indicated
- at fcb+0 as follows: 0=none, 1=A:, 2=B:, etc.}
-
- if mem[fcb]>0 then filename:=char(mem[fcb]+64)+':' else filename:='';
-
- {The 1-8 character file name resides at fcb+1 to fcb+8. These characters,
- exclusive of spaces, are added to "filename".}
-
- for n:=fcb+1 to fcb+8 do if mem[n]>32 then filename:=filename+char(mem[n]);
-
- {Finally, the .CHN extension is added}
-
- filename:=filename+'.CHN';
-
- {If TRUN can chain to "filename", it does so, and you're finished.}
-
- assign(chainfile,filename);
- {$I-} chain(chainfile); {$I+}
-
- {If it can't, e.g., if you entered A>trun <RETURN> on the command line,
- then you get a directory of the logged disk and a chance to try again.}
-
- if ioresult>0 then begin end;
- write(cr,'TRUN routine to run Turbo .CHN files',cr,
- '------------------------------------',cr,cr,
- ' Syntax: A>TRUN B:GARBAGE (if GARBAGE.CHN is on B:)',cr,
- ' or: A>TRUN B: (gets directory on drive B:)');
-
- {And again, and again, until you chain the file or the file chains you.}
-
- repeat
-
- {The directory is obtained by making bdos calls: #26 to set the dma address,
- #17 to get the first directory entry, and #18 to get subsequent directory
- entries. Calls #17 and #18 return "entrycode", which indicates the
- directory entry offset in the dma (entrycode*32) or if no entry found
- (entrycode=255).}
-
- write(cr,cr,'Please select a Turbo .CHN file from list below,',cr,
- 'or drive identifier (e.g., B:) to change default drive,',cr,
- 'or CPM (to quit).',cr,cr);
- for n:=fcb+1 to fcb+11 do mem[n]:=ord('?');
- bdos(26,addr(dma));
- entrycode:=bdos(17,fcb);
- while entrycode<>255 do begin
- writeentry(entrycode*32);
- entrycode:=bdos(18);
- end;
-
- {User makes selection}
-
- write(' CPM',cr,cr,'Enter filename, drive identifier, or CPM --> ');
- buflen:=14;
- read(filename);
- write(cr,cr);
- for n:=1 to length(filename) do
- filename[n]:=upcase(filename[n]);
-
- {"CPM" quits}
-
- if filename='CPM' then goto boot;
-
- {If drive selected, then drive # placed at fcb and deleted from filename,
- also disk reset (bdos #13) performed.}
-
- if filename[2]=':' then begin
- mem[fcb]:=byte(filename[1])-64;
- delete(filename,1,2);
- bdos(13);
- end;
-
- {Drive prefix reinserted, .CHN suffix appended, and attempt made to chain}
-
- if mem[fcb]>0 then filename:=char(mem[fcb]+64)+':'+filename;
- filename:=filename+'.CHN';
- assign(chainfile,filename);
- {$I-} chain(chainfile); {$I+}
-
- {If at first you don't succeed...}
-
- until ioresult=0;
- boot: end.