!lm11
!rm76
Text File I/O in Assembly Language Programs

A surprisingly large number of people have written or called to ask the same question:
!lm16
!rm71

"How can I read or write a text file from my program?  I know I can issue OPEN, READ, WRITE, and CLOSE commands just like in Applesoft -- by outputting a control-D and the command string.  But after that, where is the data?"
!lm11
!rm76

It is really very simple, and after I tell you, you may be just as embarrassed as they were!

Remember that in Applesoft, after opening a file and setting it up to read with the OPEN and READ commands, you actually read it with normal INPUT statements.  In assembly language you do the same thing.  You can either input a line by calling the monitor routine at $FD6F, or you can read character-by-character by calling the character input routine at $FD0C.  After a JSR $FD0C, the input character will be in the A-register.  After a JSR $FD6F, the input line will be in the monitors buffer starting at $0200, and the X-register will contain the number of characters in the line (not counting the carriage return).

Also remember that after using the OPEN and WRITE commands, all you do in Applesoft to write on a text file is use the normal PRINT statement.  In the same way, from assembly language, you just call the monitor print character routine at $FDED.  The character to be written should be in the A-register, and then use JSR $FDED.

Here is a little program which opens a text file and reads it into a buffer at $4000.  It demonstrates a few more tricks you might need to know, as well.

Lines 1180-1270 patch DOS so that it thinks you are executing an Applesoft program.  (If you really are calling this from a RUNning Applesoft program, you can skip lines 1190 and 1200.)  We want to be able to issue DOS commands by printing control-D and the command string, so we have to be RUNning.  We want to be able to tell when the end-of-file comes without getting an "OUT OF DATA" error, so we turn on the Applesoft ON ERR flag and set it up to branch to our own END.OF.DATA routine.

Lines 1310-1350 print the DOS OPEN and READ commands.  The message printer is a very simple loop at lines 1630-1690.

Lines 1380-1500 read the characters from the file and store them in a buffer at $4000.  I save the stack pointer before the loop so I can restore it after the end-of-file occurs.  Lines 1530-1570 restore the stack pointer, close the file, and return to DOS.

I really should clean up the mess I created with lines 1180-1270, but I will leave that as an exercise for the reader.
