[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 2 Applesoft BASIC questions/1 Hyper C question



In article <9406081756.AA25635@phy.mtu.edu>,
Sean M. McAfee <smmcafee@phy.mtu.edu> wrote:

[snip]

> Recently, I un-shrunk the first of the pieces, and found that, somehow, all
> of the carriage returns (control-M's) in the file had been turned into
> control-J's.  How to reverse the change?  Since I don't (yet) have any kind
> of programming shell, and since none of the text editors I have can replace
> text with a control-M, I tried Applesoft BASIC first:

[snip]

As others have explained, the problem with your BASIC program is that
the READ and WRITE commands are cancelled by the next DOS command.
You could do a loop which does a READ, then GETs a byte, then does a
WRITE, then PRINTs a byte, but it would be horribly slow.

A slight improvement would be to do a READ, then use GET to fill a
string or array, then WRITE and PRINT it to the destination file.

A still better method follows.

> So then, I figured "Hey, maybe I can just load the file directly into memory
> and make the control-J replacements with PEEKs and POKEs."  But when I
> typed "BLOAD XAA,A$2000,TTXT" I got "NO BUFFERS AVAILABLE".  I even tried
> rebooting the disk and making this the first command I entered upon starting
> BASIC, but to no different effect.  How can I be out of memory before even
> doing anything?

NO BUFFERS AVAILABLE probably means that the file is larger than 40k
(or thereabouts).  BASIC.SYSTEM will not let you load a file which
overwrites areas of memory which are used (e.g. BASIC.SYSTEM itself).

What you could do is BLOAD the file in small chunks, patch the chunk,
then write it out to another file.  The following fragments of a BASIC
program demonstrate the principle.  I'm assuming that you know the
name of the file in advance.

5 LOMEM: 24576: REM end address of buffer plus 1
10 D$ = CHR$(4)
20 BUF% = 8192: REM start address of buffer
30 BSZ% = 16384: REM size of buffer

[you may be able to fine-tune the above sizes to get a larger buffer,
depending on how big your program is and how many variables you need.
The LOMEM is very important, and must go before any variables are
defined.  Do _not_ use HIMEM in a ProDOS program!]

[more code in here]

996 REM GOSUB 1000 to copy and patch a file
997 REM F$ is the name of the text file
998 REM O$ is the name of the output text file
999 REM IF F$=O$, then GOSUB 1010 instead

1000 PRINT D$;"CREATE ";O$;",TTXT"
1010 B = 0: REM start at offset 0 into the file
1020 ONERR GOTO 1200
1030 PRINT D$;"BLOAD ";F$;",TTXT,A";BUF%;",L";BSZ%;",B";B
1040 ASZ% = PEEK(48859) + 256 * PEEK(48860)
1050 REM ASZ% is the actual number of bytes read from the file
1060 FOR I = BUF% TO BUF% + ASZ% - 1
1070 IF PEEK(I) = 10 THEN POKE I,13
1080 NEXT
1090 PRINT D$;"BSAVE ";O$;",TTXT,A";BUF%;",L";ASZ%;",B";B
1100 B = B + ASZ%
1110 IF ASZ% = BSZ% THEN GOTO 1030
1120 POKE 216,0: REM turn off ONERR GOTO
1130 RETURN

1200 REM We should only get here if the file was exactly a multiple
1210 REM of the buffer size - the BLOAD would return END OF DATA error

[Should add code here to clean up the stack after an error - I don't
have it handy.]

1220 POKE 216,0
1230 RETURN


The key here is the B parameter in the BLOAD and BSAVE commands.
Several versions of BASIC.SYSTEM have bugs in their handling of this
parameter, so make sure you are using BASIC.SYSTEM 1.4.1 or (better
still) 1.5.

An example of the above BLOAD and BSAVE commands might be:

BLOAD inputfile,TTXT,A8192,L16384,B32768    (after we've done two passes)
BSAVE outputfile,TTXT,A8192,L15332,B32768   (this is the last segment)

A is the memory address at which the data will be loaded, L is the
number of bytes to be read into memory, and B is the byte offset into
the file.


The other trick I've used is PEEKing into the BASIC.SYSTEM global page
to determine the actual number of bytes which were loaded by the
BLOAD.  The two bytes being peeked are the "transfer count" field of
the parameter block which BASIC.SYSTEM uses to do file read calls to
ProDOS.  (This is documented in the ProDOS-8 Technical Reference
Manual.)


If the file is not a multiple of the buffer size, then the last pass
will read less bytes than the buffer size, so the "IF ASZ%=BSZ%" test
will fail, and we return from the subroutine with the file fully
patched.

If the file _is_ a multiple of the buffer size, then we'll go around
once more and attempt to read 16k from just past the end of the file,
which will cause an error.  The ONERR GOTO catches this case.
-- 
David Empson
dempson@actrix.gen.nz
Snail mail: P.O. Box 27-103, Wellington, New Zealand