jshaver@APG-5.ARPA (John Science Fiction & Resume Service Shaver) (05/06/87)
The Pascal to Dos transfer requires two programs. The first one is Basic and follows immediately.
The second is binary. I have a chart which lists the pokes. That program
starts a 16384 or $4000 in Hex.
2 GOTO 200
100 REM WRITJEJ FILE (SKIP NULLS)
105 CH = PEEK (I)
110 IF CH = 16 THEN I = I + 1:CH = 0: IF PEEK (I) > 32 THEN FOR J = 33 TO PEEK (I): PRINT " ";: NEXT J:I = I + 1: GOTO 105
115 IF CH = 0 AND I > EN THEN RETURN
120 IF CH = 0 THEN I = I + 1: GOTO 105
125 I = I + 1: PRINT CHR$ (CH);: GOTO 105
130 REM READ A BLOCK
135 SL% = SS:DR% = SD
140 TR% = INT (BLOCK / 8)
145 PT% = INT ((BLOCK / 8 - TR%) * 8)
150 SE% = M%(PT%,0): CALL RWTS
155 GOSUB 190:BU% = BU% + PAGE
160 SE% = M%(PT%,1): CALL RWTS
165 GOSUB 190:BU% = BU% + PAGE
170 RETURN
175 REM CENTER TITLE
180 HTAB 20 - LEN (T$) / 2: PRINT T$: RETURN
185 REM ERR TRAP
190 IF ER% < > 0 THEN VTAB 20: CALL - 868: PRINT "DOS ERROR...": POP : POP : GOTO 290
195 RETURN
200 REM INITIALIZE
205 RWTS = 16384: HIMEM: RWTS
210 PRINT CHR$ (4);"BLOADRWTS.OBJ0"
215 PAGE = 256
220 BU% = RWTS + PAGE:CM% = 1
225 BEG = BU%:EN = BU% + PAGE
230 M%(0,0) = 0:M%(0,1) = 14
235 M%(1,0) = 13:M%(1,1) = 12
240 M%(2,0) = 11:M%(2,1) = 10
245 M%(3,0) = 9:M%(3,1) = 8
250 M%(4,0) = 7:M%(4,1) = 6
255 M%(5,0) = 5:M%(5,1) = 4
260 M%(6,0) = 3:M%(6,1) = 2
265 M%(7,0) = 1:M%(7,1) = 15
270 REM GET FILE NAMES
275 HOME : VTAB 3
280 T$ = "*** CONVERT: PASCAL TO TEXT ***": GOSUB 180: PRINT
285 REM
290 VTAB 8: HTAB 1
295 PRINT "SOURCE SLOT : 6";
300 HTAB PEEK (36): GET IN$
305 SS = VAL (IN$)
310 IF SS = 0 THEN SS = 6
315 IF SS < 0 OR SS > 7 THEN 290
320 PRINT SS
325 VTAB 10: HTAB 1
330 PRINT "SOURCE DRIVE: 1";
335 HTAB PEEK (36): GET IN$
340 SD = VAL (IN$)
345 IF SD = 0 THEN SD = 1
350 IF SD < 1 OR SD > 2 THEN 325
355 PRINT SD
360 VTAB 12: HTAB 1
365 PRINT "DESTINATION SLOT: 6";
370 HTAB PEEK (36): GET IN$
375 DS = VAL (IN$)
380 IF DS = 0 THEN DS = 6
385 IF DS < 1 OR DS > 7 THEN 360
390 PRINT DS
395 VTAB 14: HTAB 1
400 PRINT "DESTINATION DRIVE: 2";
405 HTAB PEEK (36): GET IN$
410 DD = VAL (IN$)
415 IF DD = 0 THEN DD = 2
420 IF DD < 1 OR DD > 2 THEN 395
425 PRINT DD
430 VTAB 16: HTAB 1
435 INPUT "SOURCE FILE: ";SF$: IF LEN (SF$) = 0 THEN 430
440 VTAB 18: HTAB 1
445 INPUT "DESTINATION FILE: ";DF$
450 IF LEN (DF$) = 0 THEN DF$ = SF$: VTAB 18: PRINT "DESTINATION FILE: ";DF$
455 L2 = LEN (SF$)
460 VTAB 20: CALL - 868: PRINT "PRESS <RET> TO PROCEED; <ESC> TO END ";: GET IN$: IF IN$ = CHR$ (27) THEN 605
465 PRINT : IF IN$ < > CHR$ (13) THEN 290
470 IF SD = DD THEN VTAB 20: PRINT "INSERT THE SOURCE DISK; PRESS <RET> ";: INPUT "";IN$
475 REM GET DIRECTORY
480 VTAB 20: CALL - 868: PRINT "READING DIRECTORY..."
485 BU% = RWTS + PAGE: FOR BLOCK = 2 TO 5: GOSUB 135: NEXT BLOCK
490 EN = BU%
495 REM FIND FILE NAME
500 FOR I = BEG TO EN STEP 26:NA$ = ""
505 SB = PEEK (I) + 256 * PEEK (I + 1):NB = PEEK (I + 2) + 256 * PEEK (I + 3):L1 = PEEK (I + 6)
510 IF L1 < > L2 THEN 525
515 FOR J = I + 7 TO I + L1 + 6:NA$ = NA$ + CHR$ ( PEEK (J)): NEXT J
520 IF NA$ = SF$ THEN 540
525 NEXT I
530 IF NA$ = "" THEN VTAB 20: CALL - 868: PRINT "FILE NOT FOUND: PRESS <RET> ";: INPUT "";IN$: GOTO 290
535 REM READ SOURCE
540 VTAB 20: CALL - 868: PRINT "READING FILE..."
545 SB = SB + 2:EB = NB - 1:BU% = RWTS + PAGE
550 FOR BLOCK = SB TO EB: GOSUB 135: NEXT BLOCK
555 IF SD = DD THEN VTAB 20: CALL - 868: PRINT "INSERT DESTINATION DISK; PRESS <RET> ";: INPUT "";IN$
560 REM WRITE DEST
565 VTAB 20: CALL - 868: PRINT "WRITING..."
570 PRINT CHR$ (4);"OPEN ";DF$,"D",DD
575 PRINT CHR$ (4);"DELETE ";DF$
580 PRINT CHR$ (4);"OPEN ";DF$,"D",DD
585 PRINT CHR$ (4);"WRITE ";DF$
590 I = BEG:EN = BU% - PAGE: GOSUB 105
595 PRINT CHR$ (4);"CLOSE ";DF$
600 VTAB 20: CALL - 868: PRINT "ANOTHER FILE (Y/N) ";: GET IN$: IF IN$ = "Y" THEN 270
605 PRINT : END
CLOSE
-----------------
The pokes for RWTS.OBJ0 follow.
----------------------------------
16384 32 227 3 132 72 133 73 165
16392 184 133 30 165 185 133 31 32
16400 121 64 10 10 10 10 160 1
16408 145 72 32 127 64 160 2 145
16416 72 169 0 160 3 145 72 32
16424 133 64 160 4 145 72 32 139
16432 64 160 5 145 72 32 145 64
16440 160 8 145 72 160 0 177 131
16448 160 9 145 72 32 151 64 240
16456 39 160 12 145 72 32 157 64
16464 32 227 3 32 217 3 160 13
16472 177 72 176 2 169 0 160 1
16480 145 131 177 72 160 15 145 72
16488 160 2 177 72 160 16 145 72
16496 165 30 133 184 165 31 133 185
16504 96 32 163 64 83 76 37 32
16512 163 64 68 82 37 32 163 64
16520 84 82 37 32 163 64 83 69
16528 37 32 163 64 66 85 37 32
16536 163 64 67 77 37 32 163 64
16544 69 82 37 104 133 184 104 133
16552 185 230 184 208 2 230 185 32
16560 227 223 160 1 177 131 96 0
---------------------------------
As the article in April 1982 Byte indicate, the Pascal language is easier
to do. the program is complete in itself.
--------------------------
{ $L #11:getdos.list }
{ $s++}
program getdos;
const max = 18432;{ 36 blocks of 512 bytes max }
page = 256;{ dos sector length }
cleareol= 29; clearscreen = 12;
type byte = 0..255;
units = 1..12;
untyped_file=file;
sector=record
block:0..7;
half:(first,second)
end;
var map: packed array[0..15] of sector;
buf: packed array[0..511] of byte;
text: packed array[0..max] of byte;
sourcefile, destfile: string;
sourceunit, destunit: units;
drives : set of units;
block, trak, sec, blockcount, i: integer;
ptr : integer; { pointer to text array }
done, found : boolean; ch : char;
f : file of char;
diskfile : untyped_file; { for use with blockwrite }
procedure initialize;
begin
map[0].block := 0; map[0].half := first;
map[1].block := 7; map[1].half := first;
map[2].block := 6; map[2].half := second;
map[3].block := 6; map[3].half := first;
map[4].block := 5; map[4].half := second;
map[5].block := 5; map[5].half := first;
map[6].block := 4; map[6].half := second;
map[7].block := 4; map[7].half := first;
map[8].block := 3; map[8].half := second;
map[9].block := 3; map[9].half := first;
map[10].block:= 2; map[10].half:= second;
map[11].block:= 2; map[11].half:= first;
map[12].block:= 1; map[12].half:= second;
map[13].block:= 1; map[13].half:= first;
map[14].block:= 0; map[14].half:= second;
map[15].block:= 7; map[15].half:= second;
end;{ initialize }
PROCEDURE PRINTAT(y: integer; s: string);
begin gotoxy(0,y); write(chr(cleareol),s) end;
PROCEDURE GETNAMES;
var ok : boolean; dest : string;
begin
drives := [4,5];
repeat
write(chr(clearscreen));
printat(2,'*** GETDOS ***');
printat(5,'Units: 1. Console: 4. drive #4:');
printat(6,' 5. Drive #5: 6. Printer:');
printat(8,'Source Unit (4-5)? '); readln(sourceunit);
printat(10,'Destination unit (1-6)? ');readln(destunit);
printat(12,'Source file name: ');readln(sourcefile);
destfile := sourcefile; str(destunit,dest);
if pos('.',sourcefile ) = 0 then destfile := concat(sourcefile,'.text');
case destunit of
1: destfile := 'console:';
2: destfile := 'systerm:';
3: destfile := 'not available';
4,5:destfile := concat('#',dest,':',destfile);
6: destfile := 'printer:';
7,8,9,10,11,12: destfile := 'not implemented';
end; { case of destunit }
printat(14,concat('Destination file: ',destfile));
printat(16,'<cr> accepts, <e> exits, <sp> restarts ');
read(keyboard, ch); ok := eoln(keyboard);
if ch in ['e','E',chr(27)] then exit(program);
until ok;
end; { getnames }
PROCEDURE READSEC;
begin
block := (trak*8) +map[sec].block;
unitread(sourceunit,buf,512,block);
case map[sec].half of
first : moveleft(buf[0],text[ptr],page);
second: moveleft(buf[page],text[ptr],page);
end; { cases of map }
ptr := ptr+page;
end; {readsec}
procedure readsource;
const bytes_per_entry=35; header=11;
blanks=' ';
var name: string[30]; filetype: byte;
limit, sectorcount, entry: integer;
list: packed array[1..80,0..1] of byte;
begin
printat(18,'Reading catalog...');
trak := 17 ; ptr:=0;
for sec := 15 downto 1 do readsec;
limit := ptr-1;
ptr := header;
entry := 0;
sourcefile :=concat(sourcefile,' ') ;
repeat
name := copy(blanks,1,length(sourcefile));
entry := entry + 1;
for i := 1 to length(sourcefile) do
name[i] := chr(text[ptr+i+2]-128);
found := name = sourcefile;
if not found then
begin if (entry mod 7) = 0 then ptr := ptr + header;
ptr := ptr + bytes_per_entry
end;
until (found or (ptr> limit));
if not found then
begin printat(18,'File not found...'); exit(readsource) end;
trak := text[ptr];
sec := text[ptr+1];
filetype := text[ptr+2];
sectorcount := text[ptr+33] -1 ;
if ((filetype <>0) and (filetype <>128)) or (sectorcount>72 )then
begin founD := false; printat(18,'Not a TEXT file...');
exit(readsource) end;
ptr := 0;
readsec;
ptr := 12;
for i := 1 to sectorcount do
begin list[i,0] := text[ptr];
ptr := ptr + 1;
list[i,1] := text[ptr];
ptr := ptr + 1;
end;
if odd(sectorcount) then blockcount := (sectorcount + 1) div 2
else blockcount := sectorcount div 2;
fillchar(text[0],blockcount*512,chr(0));
printat(18,'Reading file...');
ptr := 0;
for i := 1 to sectorcount do
begin trak := list[i,0];
sec := list[i,1];
readsec
end;
end; { readsource }
PROCEDURE WRITEDEST;
var nextbyte : byte;
begin
ptr := 0;
printat(18,concat('Put ',destfile,' on line; press <cr> '));
read(keyboard,ch);
if destunit in drives then
begin
printat(18,'One moment please...');
fillchar(buf[0],512,chr(0));
for i := 0 to blockcount*512 do
if text[i]>127 then text[i] := text[i] - 128;
printat(18,concat('Writing to ',destfile,'...'));
rewrite(diskfile,destfile);
i := blockwrite(diskfile,buf,1,0);
i := blockwrite(diskfile,buf,1,1);
i := blockwrite(diskfile,text[0],blockcount,2);
close(diskfile,lock);
end
else
begin
printat(18,concat('Writing to ',destfile,'...'));
rewrite(f,destfile);
writeln(f);
repeat
nextbyte := text[ptr+1];
ch := chr(text[ptr]-128);
write(f,ch);
ptr := ptr + 1
until nextbyte = 0;
close(f,lock);
end; { else }
end; { writedest }
begin { MAIN PROGRAM }
initialize;
repeat
getnames;
readsource;
if found then writedest;
writeln;
writeln;
write('Another file? (y/nn) ');
read(keyboard,ch);
done := ch in ['N','n'];
until done
end { MAIN }.