Jump to content

Photo

Simple file IO disk operations question


35 replies to this topic

#1 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Tue Jan 2, 2018 3:54 PM

I'm talking basic, I mean extended BASIC OPEN/CLOSE stuff.

 

Tursi, (in case you see this) - gave me the following OPEN line so I can save variable out to a file that is easily opened in windows as plain text.
 

OPEN #1:"DSK3.?W.049DEBUG.TXT",APPEND,DISPLAY,VARIABLE 80
PRINT #1: C
PRINT #1: TRAP
CLOSE #1
 
First question: Is this the proper way to retrieve that information? Both C and TRAP are variables from the main program.

OPEN #1:"DSK3.?W.049DEBUG.TXT",APPEND,DISPLAY,VARIABLE 80
INPUT #1: C
INPUT #1: TRAP
CLOSE #1
Also, those OPEN statements above, I believe are classic99 specific so I can open the created file in windows as plain text.

Will the exact syntax above work on real iron? If not, what is the proper OPEN statement I should be using. The TI Ext. BASIC book is confusing me.

 


Edited by Sinphaltimus, Tue Jan 2, 2018 3:58 PM.


#2 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,332 posts

Posted Tue Jan 2, 2018 4:03 PM

On real iron, you would leave out the .?W part:

 

"DSK3.DEBUG.TXT"

 

Bear in mind on file names on real iron:

- They can be a maximum of ten characters

- There's no such thing as an extension, although you can certainly add one if you want to

- They have a much greater range of characters permitted than the PC does. For example a forward slash is allowed, because the native TI FDC doesn't support directory structures



#3 jedimatt42 ONLINE  

jedimatt42

    Stargunner

  • 1,632 posts
  • Location:Beaverton, OR

Posted Tue Jan 2, 2018 4:51 PM

I believe Classic99 is the only place that '.' is a legal file name character... The convention on real-iron was generally '/' for extensions... or nothing... cause, well, only 10 characters.

 

CODES, CODEO

CODE/S, CODE/O

 

---

 

The file you are creating is 'DISPLAY' format, so ascii. which I believe means you have to read them into strings.. 

 

INPUT #1:LINE$

C = INT(LINE$)          <--- is INT function a thing?  there is something that is like atoi... no XB manual handy... 

 

The conventional way ( but you don't get an ascii file to look at ) is to use INTERNAL format. 

Then the C variable can be written in some encoded form and read back directly back into a numeric variable.

String variables can be written as well to INTERNAL files... But then it is hard to read what happened if you are using it as a log to debug your code. But it is easier for data exchange, I expect between 2 basic instances, I expect.

 

---

 

Now if you happen to be in the TIPI beta program, you can use host os ascii text files... but I'd be interested if you run into problems sharing with Classic99 given the EOL differences. 

On TIPI, a host file named  "DEBUG.TXT" can be opened as "DEBUG/TXT" if it already exists.  I already don't remember if I implemented writing back to host os files..   I did for BLAH/BAS files.

 

-M@



#4 Casey OFFLINE  

Casey

    Chopper Commander

  • 246 posts

Posted Tue Jan 2, 2018 6:05 PM

Close - I think you would need VAL.  C=VAL(LINE$) - this only works of course if LINES$ contains valid numeric characters.  I'm not sure also if this works because of there may be a carriage return in LINES$ also.  I haven't done any testing.


Edited by Casey, Tue Jan 2, 2018 6:06 PM.


#5 jedimatt42 ONLINE  

jedimatt42

    Stargunner

  • 1,632 posts
  • Location:Beaverton, OR

Posted Tue Jan 2, 2018 6:18 PM

Close - I think you would need VAL.  C=VAL(LINE$) - this only works of course if LINES$ contains valid numeric characters.  I'm not sure also if this works because of there may be a carriage return in LINES$ also.  I haven't done any testing.


Thanks for the correction! I always had trouble finding that.. It never sunk in. icon_smile.gif

I'm also not sure, but when you PRINT #1:C to a DISPLAY file, you might have to
 
PRINT #1:STR$(C)
-M@

#6 Casey OFFLINE  

Casey

    Chopper Commander

  • 246 posts

Posted Tue Jan 2, 2018 6:38 PM

I did some testing just now on my 99/4A.  This worked fine:

100 OPEN #1:"DSK2.TEST",OUTPUT,DISPLAY,VARIABLE 80
110 C=87
120 TRAP=1
130 PRINT #1:C
140 PRINT #1:TRAP
150 CLOSE #1

100 OPEN #1:"DSK2.TEST",INPUT,DISPLAY,VARIABLE 80
110 INPUT #1:LINE$
120 C=VAL(LINE$)
130 INPUT #1:LINE$
140 TRAP=VAL(LINE$)
150 PRINT C,TRAP
160 CLOSE #1

One thing I meant to comment on above.  APPEND in the open statement will only add to the end of a file.  You can't read from it in APPEND mode.  You can either use INPUT or OUTPUT to be specific, or you can use UPDATE mode to both read and write from the file.  It may need to be RELATIVE for UPDATE mode though - that I'm not sure of without playing around.



#7 jedimatt42 ONLINE  

jedimatt42

    Stargunner

  • 1,632 posts
  • Location:Beaverton, OR

Posted Tue Jan 2, 2018 6:51 PM

You aren't allowed to use RELATIVE with variable length records. It would have to be FIXED.

-M@

#8 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Tue Jan 2, 2018 7:37 PM

They would definitely be fixed length, at most 2 digits.

 

The above OPEN command works, I've confirmed this in my debuglogs.txt - but I've never had a reason to retrieve anything in the TXT on the console. It was for my eyes only opened in  a text editor.

So I do not need strings at all really, I just have to remember the order of the variables myself like the first one might be a player indicator, second x coordinate of player and third y coordinate of player etc...

So I would use something like this?

 

to save data

 

OPEN #1:"DSK3.SHAREDFILE",UPDATE,OUTPUT,FIXED2 80

 

and

 

to retrive data

OPEN #1:"DSK3.SHAREDFILE",UPDATE,INPUT,FIXED2 80

 

??



#9 Casey OFFLINE  

Casey

    Chopper Commander

  • 246 posts

Posted Tue Jan 2, 2018 7:48 PM

I did some additional testing on my real iron 99/4A just now.

 

You can use OPEN #1:"DSK3.SHAREDFILE",UPDATE,DISPLAY,VARIABLE 80 and read and write to the file.

 

You can use RESTORE #1 to go back to the beginning of the file if you want, but if you are going to overwrite a record in the file, you have to be careful to overwrite it with the exact same number of characters or you may wreck something because of the VARIABLE 80.

 

But I had no trouble getting this to work:

100 OPEN #1:"DSK2.TEST",UPDATE,DISPLAY,VARIABLE 80
110 C=87
120 TRAP=1
130 PRINT #1:C
140 PRINT #1:TRAP
150 RESTORE #1
160 INPUT #1:LINE$
170 D=VAL(LINE$)
180 INPUT #1:LINE$
190 TRAP2=VAL(LINE$)
200 PRINT D,TRAP2
210 CLOSE #1


#10 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,691 posts
  • Location:Silver Run, Maryland

Posted Wed Jan 3, 2018 7:02 AM

They would definitely be fixed length, at most 2 digits.

 

The above OPEN command works, I've confirmed this in my debuglogs.txt - but I've never had a reason to retrieve anything in the TXT on the console. It was for my eyes only opened in  a text editor.

So I do not need strings at all really, I just have to remember the order of the variables myself like the first one might be a player indicator, second x coordinate of player and third y coordinate of player etc...

So I would use something like this?

 

to save data

 

OPEN #1:"DSK3.SHAREDFILE",UPDATE,OUTPUT,FIXED2 80

 

and

 

to retrive data

OPEN #1:"DSK3.SHAREDFILE",UPDATE,INPUT,FIXED2 80

 

??

 

What is “FIXED2”?

 

...lee



#11 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Wed Jan 3, 2018 8:13 AM

 

What is “FIXED2”?

 

...lee

I think I am misunderstanding how to use FIXED. second from last paragraph of page 139 extended basic manual talks about using FIXED. it says 

"If you like, you may specify a maximum length of a record by following VARIABLE or FIXED with a numeric expression.

So I took that to mean FIXED2 would limit the fixed size to a max length of 2 (for 2 digit numbers)

But now that i look at all these answers, is that what the ,80 is for at the end?
So I would use 

OPEN #1:"DSK3.SHAREDFILE",UPDATE,OUTPUT,FIXED 2 

instead?

And by length are they describing integers? The longest length record I would need to save is two digits long. (From 0 - 99)

 



#12 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Wed Jan 3, 2018 8:15 AM

 

I did some additional testing on my real iron 99/4A just now.

 

You can use OPEN #1:"DSK3.SHAREDFILE",UPDATE,DISPLAY,VARIABLE 80 and read and write to the file.

 

You can use RESTORE #1 to go back to the beginning of the file if you want, but if you are going to overwrite a record in the file, you have to be careful to overwrite it with the exact same number of characters or you may wreck something because of the VARIABLE 80.

 

But I had no trouble getting this to work:

100 OPEN #1:"DSK2.TEST",UPDATE,DISPLAY,VARIABLE 80
110 C=87
120 TRAP=1
130 PRINT #1:C
140 PRINT #1:TRAP
150 RESTORE #1
160 INPUT #1:LINE$
170 D=VAL(LINE$)
180 INPUT #1:LINE$
190 TRAP2=VAL(LINE$)
200 PRINT D,TRAP2
210 CLOSE #1

 

Thanks Casey!

I think if the records are shorter, it will pad them and if longer is will truncate as part of the function.


Edited by Sinphaltimus, Wed Jan 3, 2018 8:17 AM.


#13 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,691 posts
  • Location:Silver Run, Maryland

Posted Wed Jan 3, 2018 8:34 AM

I think I am misunderstanding how to use FIXED. second from last paragraph of page 139 extended basic manual talks about using FIXED. it says 

"If you like, you may specify a maximum length of a record by following VARIABLE or FIXED with a numeric expression.

So I took that to mean FIXED2 would limit the fixed size to a max length of 2 (for 2 digit numbers)

But now that i look at all these answers, is that what the ,80 is for at the end?
So I would use 

OPEN #1:"DSK3.SHAREDFILE",UPDATE,OUTPUT,FIXED 2 

instead?

And by length are they describing integers? The longest length record I would need to save is two digits long. (From 0 - 99)

 

 

Yes, that is what the 80 at the end is for.  However, for FIXED, I would not term it “the maximum length”, but rather, just “the length”, i.e., every record in such a file is the same length.

 

Having a record length of 2 seems wasteful unless you actually need to go to the disk for each and every 2 bytes of information.

 

...lee

 

[Edit in this color.]



#14 Casey OFFLINE  

Casey

    Chopper Commander

  • 246 posts

Posted Wed Jan 3, 2018 1:14 PM

I think I am misunderstanding how to use FIXED. second from last paragraph of page 139 extended basic manual talks about using FIXED. it says 
"If you like, you may specify a maximum length of a record by following VARIABLE or FIXED with a numeric expression.
So I took that to mean FIXED2 would limit the fixed size to a max length of 2 (for 2 digit numbers)
But now that i look at all these answers, is that what the ,80 is for at the end?
So I would use 
OPEN #1:"DSK3.SHAREDFILE",UPDATE,OUTPUT,FIXED 2 
instead?And by length are they describing integers? The longest length record I would need to save is two digits long. (From 0 - 99)


UPDATE and OUTPUT are 2 options for the same operation in OPEN. You cannot specify both.

This may help I hope - the generic format of an OPEN statement:
OPEN #x - where x is any number between 1 and 255
:device-file name - a variable or string constant that specifies the device and file name
,file access mode (RELATIVE or SEQUENTIAL) - defaults to SEQUENTIAL if you leave it off
,file mode (INPUT, OUTPUT, UPDATE or APPEND) - UPDATE is the default option if you leave it off.
,file type (INTERNAL or DISPLAY) - defaults to DISPLAY if you leave it off
,record type + optional record length (FIXED or VARIABLE) (I think VARIABLE is the default)

So, in your case, you would want: OPEN #3:”DSK3.SHAREDFILE”,UPDATE,DISPLAY,FIXED 80 as in the example code from above.
It can be more generic of course.
100 X=37
110 FILE$=“DSK3.SHAREDFILE”
120 OPEN #X:FILE$,UPDATE,DISPLAY,FIXED 80
xxx
200 CLOSE #X

Specifying UPDATE allows the TI to both read and write to the file at the same time.

Some devices can only used certain record lengths. Cassette for instance will only support 64, 128 and 192. If you specify VARIABLE 80, I think you get a maximum length of 80, but the cassette system will pad it to 128.

#15 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Wed Jan 3, 2018 5:32 PM

Good stuff. I'll pay with it this weekend and report back if I am able to use this as I intend to.

Thanks as always everyone. Much to learn. ..

#16 Casey OFFLINE  

Casey

    Chopper Commander

  • 246 posts

Posted Wed Jan 3, 2018 5:45 PM

The user's reference guide that comes with the 99/4A (there is a PDF of it on whtech) has very thorough documentation for all the parameters for the OPEN statement, in much more detail than the Extended BASIC manual.  You many want to have a look through there as well.  There are many examples and they are all very well documented.  The manual tells you about all the defaults if you leave them off a well.  Good luck with your project!  Happy to help as always.  I learn so much from everyone else on here with the assembly language and the hardware stuff - I'm happy to help with TI BASIC whenever I can. :)



#17 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,071 posts
  • HarmlessLion
  • Location:BUR

Posted Wed Jan 3, 2018 6:34 PM

Lots of good explanation above, but I want to touch on the Classic99 specific part -- you don't want to use the "?W" part to write a Windows text file if you intend Classic99 to read it back in. Forcing a Windows file format implies you want Windows to use the resulting file, that's really what it's for. While a write/read cycle to Windows text will probably work, it's not intended use and I don't promise it will. ;)



#18 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Thu Jan 4, 2018 7:21 PM

Lots of good explanation above, but I want to touch on the Classic99 specific part -- you don't want to use the "?W" part to write a Windows text file if you intend Classic99 to read it back in. Forcing a Windows file format implies you want Windows to use the resulting file, that's really what it's for. While a write/read cycle to Windows text will probably work, it's not intended use and I don't promise it will. ;)

Indeed. I've never had the need to read back from a file. That ?W part came from you a while back and I was unable to find our conversation about its usage. At the time, I just needed to dump variables out to a file that i could edit in windows so it was perfect. Just now thinking about going the other way. If I can wrap my head around the proper way to approach my idea, I may have a small demo to release at the end of this weekend.


Edited by Sinphaltimus, Thu Jan 4, 2018 7:24 PM.


#19 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Fri Jan 5, 2018 4:41 PM

OK, another related question.

In XB - is there a way to check if a file exists on DSK1 and if it does, delete it?

 

EDIT: OK, I know how to delete it but haven't figure out to check for its existence yet.

 

EDIT2: Well no I don't know how to delete it.

 

If I use 

DELETE "DSK1.DELFILE"

OR 

OPEN #1:"DSK1.DELFILE",UPDATE,DISPLAY,FIXED 80
CLOSE #1:DELETE
 
i GET THE SAME I/O ERROR 73
 
I'm using classic99.

Edited by Sinphaltimus, Fri Jan 5, 2018 5:23 PM.


#20 Casey OFFLINE  

Casey

    Chopper Commander

  • 246 posts

Posted Fri Jan 5, 2018 5:41 PM

I have questions about your question. :)

 

You won't get an error if you try to DELETE a file that doesn't exist.  With that said, I'm not sure you need to even check if it exists first if the only action you are going to take if it is found is to delete it.

 

However, you can test if a file does not exist and then handle that in a program.  Opening a file for input that doesn't exist produces an I/O ERROR that you can trap with ON ERROR.  Once you handle that (set a flag, do something else), you can put ON ERROR STOP to set error handling back to the normal method and continue on with your program.  You have to be careful though, since a file with different data type than you are checking for will also produce an I/O ERROR and get trapped by the error handling.  There may be a CALL PEEK that you can use to find the digits for the I/O ERROR and look specifically for the file not found condition.  I thought CALL ERR might give you that information, but all it tells you is the file number that caused the error.  Unfortunately, the CALL ERR built into the CC-40 would give us that information, but not 99/4A Extended BASIC.

 

If we can assume that the file type will always be the same, or is known, this seems to work:

100 ON ERROR 150
110 OPEN #1:"DSK1.DUMMY",INPUT,INTERNAL,FIXED
120 ON ERROR STOP
130 DELETE "DSK1.DUMMY"
140 END
150 PRINT "FILES DOES NOT EXIST"


Edited by Casey, Fri Jan 5, 2018 5:53 PM.


#21 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Fri Jan 5, 2018 6:21 PM

OK, sorry, that on error stuff is a bit above my head.<- I understand now.

So can you rephrase your answer without the error checking?

 

As you said "You won't get an error if you try to DELETE a file that doesn't exist.  With that said, I'm not sure you need to even check if it exists first if the only action you are going to take if it is found is to delete it."

 

That statement is true. I no longer care if it exists or not. I want to delete the file right before the program ends with the END statement.

So here's a new question with more details to follow and more questions. :)

Is this all I need? <- No, I see how the on error works and I'd need it if using the open statement.

OPEN #1:"DSK1.DUMMY",INPUT,INTERNAL,FIXED

DELETE "DSK1.DUMMY"

END

 

I don't use CLOSE #1 at all? < - this still true?

 

My second question is this because i still don't get it and it may be part of some issues I'm running into.

INTERNAL vs DISPLAY - Should all my open statements be internal if i do not plan to display the data?

Or is DISPLAY needed because I am writing to the file (PRINT so I need something to print to) but not needed if I am reading from it (INPUT)

UPDATE vs INPUT vs OUTPUT

 

If I am not going to be reading and writing to a file at the same time (within the OPEN and CLOSE statements) then do I use OUTPUT when writing to the file and INPUT when reading from it?

So If I'm only using PRINT:data$ then it's OUTPUT but if I'm using INPUT:data$ then I use INPUT in the OPEN statement?

Or just stick with UPDATE because it works fine regardless?

So far, my issue is this. I get varios IO errors when I first run my program if certain files created during the runtime of the program exist. Sometimes it's about reading past the end of the file (I know to use RESTORE and I am) and sometimes I get an error that a file is write protected.


 


Edited by Sinphaltimus, Fri Jan 5, 2018 6:42 PM.


#22 Casey OFFLINE  

Casey

    Chopper Commander

  • 246 posts

Posted Fri Jan 5, 2018 7:20 PM

If you are testing for a file's existence with something like OPEN #1:"DSK1.DUMMY",INPUT,INTERNAL,FIXED and it doesn't exist, you don't need a CLOSE #1 because the OPEN #1 didn't succeed.  (I think you'll get a FILE ERROR if you try to CLOSE #1 actually). 

 

If you are just using the file temporarily in a program run and you don't need it at the end, (that's what I took your explanation to me, but please correct me if I misunderstood) you can make it easier on yourself with something like the following:

 

100 OPEN #1:"DSK1.FILE",UPDATE,INTERNAL,VARIABLE

110 REM program lines

200 PRINT #1:"SOME DATA GOES IN THE FILE"

210 REM program lines

300 RESTORE #1

310 INPUT #1:A$::PRINT A$

320 REM rest of the program

500 CLOSE #1:DELETE

510 END

 

This allows the program to open the file, read it, write to it, do whatever it needs to do with what it did with the data in the file, and then clean it up at the end.  Then you don't have to worry about the file existing when you run it again, because the file will only live as long as the program is running.

 

INTERNAL/DISPLAY - Think of it like this and I think it will help.  INTERNAL is great if the only thing that's going to read the contents of the file is the computer itself.  DISPLAY is perfect if a human is going to read it.  Disk and cassette files are good candidates for INTERNAL, whereas the printer would be something you'd open with DISPLAY.  At the same time though, if you have to transfer the file to another computer (say, Windows) you'll want to use DISPLAY.  INTERNAL files are stored in TI's own proprietary format that another computer might not understand, but DISPLAY is standard ASCII.  

 

INPUT/OUTPUT/UPDATE - I tend to use INPUT and OUTPUT more often than UPDATE.  It's much clearer what you intend to do with the file with INPUT and OUTPUT for one thing, and if you were going to read one file and write to another, this gives you some insurance that you won't wreck your input file by accident.  UPDATE is perfect for a RELATIVE file where all the records are the same size and you want to change individual records in the file.  But it works fine with sequential files too if you need to read some data in the file to affect other data later in the file.  

 

Be sure to use the EOF function when you are reading to check that you haven't hit the end of the file.  

 

In the case above, you can set up a read loop that tests for end of file and then gets you out before you get an I/O ERROR with something like this:

 

100 OPEN #1:"DSK1.DUMMY",INPUT,INTERNAL,VARIABLE

110 IF EOF(1) THEN 150

120 INPUT #1:A$

130 PRINT A$

140 GOTO 110

150 CLOSE #1



#23 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Fri Jan 5, 2018 7:34 PM

ok, GREAT. Things are starting to make sense but my scenario is a bit different and I am deliberately hiding TMI because I kind of want it to be a surprise (this demo I'm working on). So I'm going to PM you what it is I am actually doing in the hopes we can keep it quiet for now.



#24 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • Topic Starter
  • 2,494 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Fri Jan 5, 2018 10:10 PM

OK here's the surprise and why I really needed to ask all these Disk IO questions.- http://atariage.com/...ased-game-demo/

EDIT: And thank you everyone here. I still have a lot to learn and understand but ya'll helped me get over some basic hurdles. (pun intended)


Edited by Sinphaltimus, Sat Jan 6, 2018 7:36 AM.


#25 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,071 posts
  • HarmlessLion
  • Location:BUR

Posted Sat Jan 6, 2018 3:34 PM

Classic99 doesn't support DELETE on FIADs, because I believe you should use the Windows file manager to manage files. I can't remember if it does on disk images, it probably should since Windows can't. ;)






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users