Jump to content
brain

VARIABLE files on TI 99/4A

Recommended Posts

I apologize that I am not completely familiar with the TI 99/4A, so I am hoping there are some gurus out that who can help.

 

I am the principal developer on HEX-TI-r, the HexBus SD card drive solution for the TI cc40.  https://github.com/go4retro/HEXTIr

 

The goal is to create a compatible mass storage solution for this device, which had a drive announced but never released.

 

The good news is that primary drive operations work fine now, thanks to initial code by myself and improvements by a handful of developers.

 

Now, the group is turning their attention to variable files, which are supported by the cc40 TI BASIC, but there's little information on how such files should be created, and how the disk drive would have originally stored the resulting data.

 

I was hoping that the TI 99/4A, maybe with some expansion cart from back in the day, or some other TI platform, implemented this functionality and there was not knowledge on the implementation.  We can (and have) created a workable solution for our implementation, but I am always interested in historical correctness, if possible.

 

jim

 

 

 

  • Like 1

Share this post


Link to post
Share on other sites

On the 4A, records are stored in 256 byte block chunks. 

 

Variable record based files have a maximum specifiable record length of 254, due to the structure of the block.

The first by of a record is the length byte, followed by up to 254 bytes of content for the record. 

 

If the next record will not fit in the block, then the length byte is 0xFF ( 255 ) which indicates to skip the remainder of the block and find the next record in the next block.

 

It is common on the 4A to use a DISPLAY VARIABLE 80 file for text. There is no line separator innate in these files, as the record structure serves to separate lines. 1 line per record. 

 

Programs, or programming languages can structure these as data... a Display type file used by TI BASIC will use commas to separate fields in a record. An Internal type file knows the length of each internal field datum as either the type is flagged in the first byte of the field, and if it is a string, there is a length again before the content of the string. But all that is within the record and not a concern of the storage device on the 4A. I'd expect the CC-40 borrowed a lot of storage device vs. BASIC separation of responsibilities, given the hex-bus storage devices were meant to work with the 4A filesystem concepts.

 

There are a documents that details all of this for the 4A... I will go find the link to.   

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Fairly high level:

 

http://aa-ti994a.oratronik.de/GPL_Interface_Specification_for_the_99_4_Disk_Peripheral_V2_0_03_28_1983.pdf

 

Ok, reviewing that and the docs next to it in the developer resource sticky thread, I'm amazed TIPI works... The storage structure I described is better understood as TIFILES format FIADs, but I can't find where I learned how the internal storage is defined.  I suspect, empirical data.  I have this code as part of TIPI that works with Variable Record files stored as TIFILES: https://github.com/jedimatt42/tipi/blob/master/services/ti_files/VariableRecordFile.py

 

I would expect the CC-40 to work in units of records with the hex bus interface, and the device treat what is inside a record as opaque. I could be horribly wrong, but you are far enough along to tell already.

 

[email protected]

  • Like 1

Share this post


Link to post
Share on other sites

Hmm, is there anyway you (or someone else) can provide the TIPI (or actual TI disk) raw file image of a TI program that does this:

 

100 open #2, "dsk1.test.txt,OUTPUT,VARIABLE 254"

130 for i = 1 to 10

150 print#2,i,i^2,sqrt(i),sin(i),"""       test"""

160 next i

170 close #2

 

(I tried to convert from cc40 basic to ti basic, but perhaps I missed something). 

 

A few things I am trying to sort:

  • If the record length is 254, then does that mean the i and i^2 are separated by 254 spaces in the file, or just 9 (assuming a comma is a 10 char boundary)
  • If I print multiple things in the one line, is that 1 record, or 5 records?

 

Jim

 

 

Share this post


Link to post
Share on other sites
15 hours ago, brain said:
  • If the record length is 254, then does that mean the i and i^2 are separated by 254 spaces in the file, or just 9 (assuming a comma is a 10 char boundary)
  • If I print multiple things in the one line, is that 1 record, or 5 records?

 

Commas and semicolons are field separators. Line 150 needs a colon, not a comma, following “print#2”.  It will print one record to the file because there is no comma/semicolon at the end, which would await another print statement to close the record. The only way to get multiple records from one, fully terminated print statement is to insert space-separated colons between variable/constant lists representing the separate records and/or at the end. Two or more space-separated colons in a row will insert blank records.

 

...lee

Edited by Lee Stewart
clarification
  • Like 2

Share this post


Link to post
Share on other sites

Because it is Variable, the records are not padded... if it was FIXED then they are all padded to the fixed size. 

 

The default DISPLAY vs INTERNAL mode means the string form of the values will be written to the record, and take however much space that takes.. 

 

I'll attempt to 4A basic that, and capture the resulting output file.

 

 

Share this post


Link to post
Share on other sites
17 minutes ago, Lee Stewart said:

 

Commas and semicolons are field separators. Line 150 needs a colon, not a comma, following “print#2”.  It will print one record to the file because there is no comma/semicolon at the end, which would await another print statement to close the record. The only way to get multiple records from one, fully terminated print statement is to follow it with space-separated colons, which will only add blank records after the one-record print.

 

...lee

OK on the colon.  On the cc40, it's a comma, not a colon, for reference.

 

Hmm, so everything you put in a single print statement, barring " : " delimiters, would get dumped into 1 record.  That simplifies my disk code, I think.

 

So, if I wanted to print 4 records with that single print statement, I'd do:

print #2:i;" : ";i^2" : ";sqrt(i)" : ";sin(i)" : ";"""       test"""

 

And, with the colon chars in place to denote fields, I don't need the triple """ to capture a retain leading spaces, so i could do:

print #2:i;" : ";i^2" : ";sqrt(i)" : ";sin(i)" : ";"       test"

 

And, when I read the resulting fields back in, can I do input #2:a$,b$,c$,d$,e$ or can you share the code needed?

 

Jim

Edited by brain
typos

Share this post


Link to post
Share on other sites
100 OPEN #2:"DSK1.TESTTEXT",OUTPUT,VARIABLE 254
130 FOR I=1 TO 10
150 PRINT #2:I,I^2,SQR(I),SIN(I),"""    test"""
160 NEXT I
170 CLOSE #2

That is my translation to TI BASIC on the 4A.  

 

Here is the resulting output file in TIFILES format: TESTTEXT

 

Using xdt99 suite's xdm99.py -P to dump it to text we see: 

 

 1             1             1             .8414709848  "    test"
 2             4             1.414213562   .9092974268  "    test"
 3             9             1.732050808   .1411200081  "    test"
 4             16            2            -.7568024953  "    test"
 5             25            2.236067978  -.9589242747  "    test"
 6             36            2.449489743  -.2794154982  "    test"
 7             49            2.645751311   .6569865987  "    test"
 8             64            2.828427125   .9893582466  "    test"
 9             81            3             .4121184852  "    test"
 10            100           3.16227766   -.5440211109  "    test"

 

A hexdump of one of the sectors in the TIFILES file looks like:

 

00000080  42 20 31 20 20 20 20 20  20 20 20 20 20 20 20 20  |B 1             |
00000090  31 20 20 20 20 20 20 20  20 20 20 20 20 20 31 20  |1             1 |
000000a0  20 20 20 20 20 20 20 20  20 20 20 20 2e 38 34 31  |            .841|
000000b0  34 37 30 39 38 34 38 20  20 22 20 20 20 20 74 65  |4709848  "    te|
000000c0  73 74 22 42 20 32 20 20  20 20 20 20 20 20 20 20  |st"B 2          |
000000d0  20 20 20 34 20 20 20 20  20 20 20 20 20 20 20 20  |   4            |
000000e0  20 31 2e 34 31 34 32 31  33 35 36 32 20 20 20 2e  | 1.414213562   .|
000000f0  39 30 39 32 39 37 34 32  36 38 20 20 22 20 20 20  |9092974268  "   |
00000100  20 74 65 73 74 22 42 20  33 20 20 20 20 20 20 20  | test"B 3       |
00000110  20 20 20 20 20 20 39 20  20 20 20 20 20 20 20 20  |      9         |
00000120  20 20 20 20 31 2e 37 33  32 30 35 30 38 30 38 20  |    1.732050808 |
00000130  20 20 2e 31 34 31 31 32  30 30 30 38 31 20 20 22  |  .1411200081  "|
00000140  20 20 20 20 74 65 73 74  22 ff 00 00 00 00 00 00  |    test".......|
00000150  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

So, the records are 0x42 or 66 characters long. The numbers are well padded cause of the meaning of ',' ,  and you can see we got 3 records in one sector.

  • Like 1

Share this post


Link to post
Share on other sites
15 minutes ago, jedimatt42 said:

Because it is Variable, the records are not padded... if it was FIXED then they are all padded to the fixed size. 

 

The default DISPLAY vs INTERNAL mode means the string form of the values will be written to the record, and take however much space that takes.. 

 

I'll attempt to 4A basic that, and capture the resulting output file.

 

 

OK, thanks (FIXED versus VARIABLE).

 

If you can provide a few variations (FIXED, VARIABLE, DISPLAY, INTERNAL), that's always helpful.  Or, any guidance on how the file will change depending on the setting is likewise helpful.  I didn't realize " : " denotes a delimiter in these records.

 

And, if you want to send an actual ':' in a field, how do you do that?

 

Jim

 

 

Share this post


Link to post
Share on other sites
5 minutes ago, jedimatt42 said:
100 OPEN #2:"DSK1.TESTTEXT",OUTPUT,VARIABLE 254
130 FOR I=1 TO 10
150 PRINT #2:I,I^2,SQR(I),SIN(I),"""    test"""
160 NEXT I
170 CLOSE #2

That is my translation to TI BASIC on the 4A.  

 

Here is the resulting output file in TIFILES format: TESTTEXT

 

Using xdt99 suite's xdm99.py -P to dump it to text we see: 

 

 1             1             1             .8414709848  "    test"
 2             4             1.414213562   .9092974268  "    test"
 3             9             1.732050808   .1411200081  "    test"
 4             16            2            -.7568024953  "    test"
 5             25            2.236067978  -.9589242747  "    test"
 6             36            2.449489743  -.2794154982  "    test"
 7             49            2.645751311   .6569865987  "    test"
 8             64            2.828427125   .9893582466  "    test"
 9             81            3             .4121184852  "    test"
 10            100           3.16227766   -.5440211109  "    test"

 

A hexdump of one of the sectors in the TIFILES file looks like:

 

00000080  42 20 31 20 20 20 20 20  20 20 20 20 20 20 20 20  |B 1             |
00000090  31 20 20 20 20 20 20 20  20 20 20 20 20 20 31 20  |1             1 |
000000a0  20 20 20 20 20 20 20 20  20 20 20 20 2e 38 34 31  |            .841|
000000b0  34 37 30 39 38 34 38 20  20 22 20 20 20 20 74 65  |4709848  "    te|
000000c0  73 74 22 42 20 32 20 20  20 20 20 20 20 20 20 20  |st"B 2          |
000000d0  20 20 20 34 20 20 20 20  20 20 20 20 20 20 20 20  |   4            |
000000e0  20 31 2e 34 31 34 32 31  33 35 36 32 20 20 20 2e  | 1.414213562   .|
000000f0  39 30 39 32 39 37 34 32  36 38 20 20 22 20 20 20  |9092974268  "   |
00000100  20 74 65 73 74 22 42 20  33 20 20 20 20 20 20 20  | test"B 3       |
00000110  20 20 20 20 20 20 39 20  20 20 20 20 20 20 20 20  |      9         |
00000120  20 20 20 20 31 2e 37 33  32 30 35 30 38 30 38 20  |    1.732050808 |
00000130  20 20 2e 31 34 31 31 32  30 30 30 38 31 20 20 22  |  .1411200081  "|
00000140  20 20 20 20 74 65 73 74  22 ff 00 00 00 00 00 00  |    test".......|
00000150  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

So, the records are 0x42 or 66 characters long. The numbers are well padded cause of the meaning of ',' ,  and you can see we got 3 records in one sector.

So, where does the 254 record size get stored?  It must be in some preamble to this data (the 00-7f data now shown).  I would think, since I asked for 254 byte records, I would only get 1 record per sector. 

 

Still a bit confused, I am.  Sorry.

 

Jim

 

Share this post


Link to post
Share on other sites

Yes, in TIPI which uses TIFILES, there is a 128 byte header that captures that file type, record length, and other meta data about the file.  On a real floppy disk, this is part of the 'directory structure' called a File Descriptor Record. 

The attached file was a complete 'TIFILES' file, what we call a FIAD... 

 

Let me find the TIFILES format specification... 

 

Oh, for grins, I switched the commas to space-colon-space to see, as I hadn't heard of that before... as I said before the software like TI BASIC worries about interpreting the structure within a record (such as what is a field) and the storage device just treats it opaquely.

 

00000000  07 54 49 46 49 4c 45 53  00 02 80 01 c2 fe 02 00  |.TIFILES........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000080  03 20 31 20 03 20 31 20  03 20 31 20 0d 20 2e 38  |. 1 . 1 . 1 . .8|
00000090  34 31 34 37 30 39 38 34  38 20 0a 22 20 20 20 20  |414709848 ."    |
000000a0  74 65 73 74 22 03 20 32  20 03 20 34 20 0d 20 31  |test". 2 . 4 . 1|
000000b0  2e 34 31 34 32 31 33 35  36 32 20 0d 20 2e 39 30  |.414213562 . .90|
000000c0  39 32 39 37 34 32 36 38  20 0a 22 20 20 20 20 74  |92974268 ."    t|
000000d0  65 73 74 22 03 20 33 20  03 20 39 20 0d 20 31 2e  |est". 3 . 9 . 1.|
000000e0  37 33 32 30 35 30 38 30  38 20 0d 20 2e 31 34 31  |732050808 . .141|
000000f0  31 32 30 30 30 38 31 20  0a 22 20 20 20 20 74 65  |1200081 ."    te|
00000100  73 74 22 03 20 34 20 04  20 31 36 20 03 20 32 20  |st". 4 . 16 . 2 |
00000110  0d 2d 2e 37 35 36 38 30  32 34 39 35 33 20 0a 22  |.-.7568024953 ."|
00000120  20 20 20 20 74 65 73 74  22 03 20 35 20 04 20 32  |    test". 5 . 2|
00000130  35 20 0d 20 32 2e 32 33  36 30 36 37 39 37 38 20  |5 . 2.236067978 |
00000140  0d 2d 2e 39 35 38 39 32  34 32 37 34 37 20 0a 22  |.-.9589242747 ."|
00000150  20 20 20 20 74 65 73 74  22 03 20 36 20 04 20 33  |    test". 6 . 3|
00000160  36 20 0d 20 32 2e 34 34  39 34 38 39 37 34 33 20  |6 . 2.449489743 |
00000170  0d 2d 2e 32 37 39 34 31  35 34 39 38 32 20 ff 00  |.-.2794154982 ..|
00000180  0a 22 20 20 20 20 74 65  73 74 22 03 20 37 20 04  |."    test". 7 .|
00000190  20 34 39 20 0d 20 32 2e  36 34 35 37 35 31 33 31  | 49 . 2.64575131|
000001a0  31 20 0d 20 2e 36 35 36  39 38 36 35 39 38 37 20  |1 . .6569865987 |
000001b0  0a 22 20 20 20 20 74 65  73 74 22 03 20 38 20 04  |."    test". 8 .|
000001c0  20 36 34 20 0d 20 32 2e  38 32 38 34 32 37 31 32  | 64 . 2.82842712|
000001d0  35 20 0d 20 2e 39 38 39  33 35 38 32 34 36 36 20  |5 . .9893582466 |
000001e0  0a 22 20 20 20 20 74 65  73 74 22 03 20 39 20 04  |."    test". 9 .|
000001f0  20 38 31 20 03 20 33 20  0d 20 2e 34 31 32 31 31  | 81 . 3 . .41211|
00000200  38 34 38 35 32 20 0a 22  20 20 20 20 74 65 73 74  |84852 ."    test|
00000210  22 04 20 31 30 20 05 20  31 30 30 20 0c 20 33 2e  |". 10 . 100 . 3.|
00000220  31 36 32 32 37 37 36 36  20 0d 2d 2e 35 34 34 30  |16227766 .-.5440|
00000230  32 31 31 31 30 39 20 0a  22 20 20 20 20 74 65 73  |211109 ."    tes|
00000240  74 22 ff 00 00 00 00 00  00 00 00 00 00 00 00 00  |t"..............|
00000250  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

This is the entire thing, where each of your values is a record... it ends up being much more compact, because the comma used to specify that tabular shape with all the spaces.   0000 - 007F is the 128 byte TIFILES header, there is a 'fe' in there that is the record length... 0080 - 0017F is the first 256 byte sector.  You can see it packed in all of the data for I=1 to 5, and part of I=6... since each value was written as a seperate record.

 

If this was FIXED instead of Variable, each record is simply the length specified when opened. The records should be null padded. A Fixed file supports random access, as the starting point for each record is the record number * the record-length. Variable records do not allow random access on the 4A. As you have to traverse it like a linked list.

 

RESET is allowed on both, but again for Variable, RESET is only allowed to seek back to the beginning. By contrast, for a FIXED record file, it may seek to any record number. 

 

 

 

 

Share this post


Link to post
Share on other sites
	TIFILES File Header
	Byte	Content		Comment
	0	0x07			Contains the length of the TIFILES string
	1-7	'TIFILES'			Contains the literal string 'TIFILES' by means of identification
	8-9	Length in sectors	Number of 256 byte sectors of the file, big endian
	10	File type		Not the same as the PAB
		Bit 0			Fixed (0) or Variable (1)
		Bit 1-3			Not used
		Bit 4			Protected (meant to prevent copying, largely ignored by 3rd
					party software.)
		Bit 5			Not used
		Bit 6			Display (0) or Internal (1)
		Bit 7			Data (0) or Program Image (1)
	11	Records per Sector	number of records per sector for record based files
	12	Bytes in last sector	Used to determine the true end of the file (0 indicates 256 
					bytes in last sector)
	13	Record length		The length per record, as in the PAB
	14-15	Number records	Number of records in the file if fixed, or number of sectors
					in the file if variable. Little Endian, which is unusual for the
					machine and inconsistent with the length field!

Here, this is stolen from a Google Doc @Tursi shared with me.   That first 128 byte header of a TIFILES file, where we only use 16 bytes :)

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks.  So, it appears that the record length for a VARIABLE record is not needed, since it doesn't make any difference (well, I guess when you open the file for reading, it has to be the same number, but that's the only check, I assume).

 

Are there lots of utilities and/or emulators that use this TIFILES format? 

 

And, when you store a file in the FS in teh TIFIES format, what filename do you give it?  In this case, with TESTTEXT as the filename via BASIC, if the file on the Linux FS "TESTTEXT.FIAD" or soemthing like that?

 

Less confused, but now need to read up the TIFILES format, since we have been storing the files in native FAT format on the SD card, no special header.

 

Jim

 

 

 

 

Share this post


Link to post
Share on other sites

Also, in general, if I want to write out 4 "records", so i, i^2, sqrt(i) and sin(i) to a file using VARIABLE DISPLAY, but I don't want to do " : ", do I just do:

 

1 print#2:i

2 print#2:i^2

3print#2:sqrt(i)

4print#2:sin(i)

 

And the fact that those occur on different lines means the drive will put them in separate records?

 

Jim

 

  • Like 1

Share this post


Link to post
Share on other sites

Yes, by default each print statement would go to a separate record.. 

 

Classic99, js99er emulators work with TIFILES. 

 

my TIPI device, and Fred Kaal's HDX device use them for a TI file system on modern computer connected to the 4A.  - This is like what you are doing with files on FAT... you just need to have some pre-amble to cope with the file mode.

 

And yes, if you open a file that is not a match for the type & record length, an error is required. 

Share this post


Link to post
Share on other sites

I don't have the CC-40 manuals, but looking at the CC-40 basic reference card, the BASIC 'open' statement has identical concerns of file type as the 4A. 

 

the 'RESTORE' command is what I was refering to as RESET earlier, a seek operation. 

 

Random access is called 'RELATIVE'. Variable record files must be opened in 'SEQUENTIAL' mode. 

 

Then you have commands OLD and SAVE. On the 4A, those work with a whole different type of file... I'm assuming the CC-40 doesn't issue on OPEN and do a bunch of READ and WRITE the same as PRINT and LINPUT. On the 4A those OLD and SAVE work with PROGRAM image file types ( instead of DISPLAY|INTERNAL FIXED|VARIABLE )  

 

If you used TIFILES, we might find there is a level of interoperability... such as a database file could have a more robust data entry model on the 4A, and the the data file moved the CC-40 with a smaller read oriented client.  Although, who knows if the string representation of numbers is compatible, or the INTERNAL representations..  

Share this post


Link to post
Share on other sites

Oh, you mentioned file naming concerns... For TIPI, where I store on a linux partition, but it would work for exFAT or vFAT.. I have these rules: https://github.com/jedimatt42/tipi/wiki/File-name-rules 

 

basically '.' is a device or directory separator. So filenames cannot have '.' in them. A lot of internal code uses space to pad file names on the 4A, so a name cannot have spaces in it either. 

 

On the 'FAT' side, if a file was named 'TEST.TXT', I report it to the 4A as 'TEST/TXT' and if the 4A requests 'TEST/TXT' or 'TEST\TXT' the FAT side would look for 'TEST.TXT'

 

The TIFILES header supports having a file name embedded in the header. Some tools don't use that. I find managing files on a hosted filesystem, you want to be able to rename the file on the sd card or whatever, and have that stick... 

 

This was @Tursi model, to give credit where it is due.  Only tangable difference, is that classic99 doesn't emulate 3rd party directory extensions to disk devices.  So, having a '.' in a filename after the first dot in the device name is not ambiguous and it allows it. 

Share this post


Link to post
Share on other sites

We've

14 minutes ago, jedimatt42 said:

I don't have the CC-40 manuals, but looking at the CC-40 basic reference card, the BASIC 'open' statement has identical concerns of file type as the 4A. 

 

the 'RESTORE' command is what I was refering to as RESET earlier, a seek operation. 

 

Random access is called 'RELATIVE'. Variable record files must be opened in 'SEQUENTIAL' mode. 

 

Then you have commands OLD and SAVE. On the 4A, those work with a whole different type of file... I'm assuming the CC-40 doesn't issue on OPEN and do a bunch of READ and WRITE the same as PRINT and LINPUT. On the 4A those OLD and SAVE work with PROGRAM image file types ( instead of DISPLAY|INTERNAL FIXED|VARIABLE )  

 

If you used TIFILES, we might find there is a level of interoperability... such as a database file could have a more robust data entry model on the 4A, and the the data file moved the CC-40 with a smaller read oriented client.  Although, who knows if the string representation of numbers is compatible, or the INTERNAL representations..  

Yes, I've implemented OLD and SAVE by just directly loading the aforementioned files from FAT into the cc40.  Since all that is functioning well, the team has moved onto DATA files.  However, on the disk side, both files are opened the same way (hexBus open, hexbus read, hexbus close for old, hexbus open,write,close for save).  The only thing denoting a data file is LUN!=0 in the PAB sent.

 

Jim

 

Share this post


Link to post
Share on other sites
7 minutes ago, jedimatt42 said:

Oh, you mentioned file naming concerns... For TIPI, where I store on a linux partition, but it would work for exFAT or vFAT.. I have these rules: https://github.com/jedimatt42/tipi/wiki/File-name-rules 

 

basically '.' is a device or directory separator. So filenames cannot have '.' in them. A lot of internal code uses space to pad file names on the 4A, so a name cannot have spaces in it either. 

 

On the 'FAT' side, if a file was named 'TEST.TXT', I report it to the 4A as 'TEST/TXT' and if the 4A requests 'TEST/TXT' or 'TEST\TXT' the FAT side would look for 'TEST.TXT'

 

The TIFILES header supports having a file name embedded in the header. Some tools don't use that. I find managing files on a hosted filesystem, you want to be able to rename the file on the sd card or whatever, and have that stick... 

 

This was @Tursi model, to give credit where it is due.  Only tangable difference, is that classic99 doesn't emulate 3rd party directory extensions to disk devices.  So, having a '.' in a filename after the first dot in the device name is not ambiguous and it allows it. 

Hmm, might need to rethink how we do things, then.  We allow dots in filenames, but I can see why that would cause issues.  The ti74 allows directories, but uses '/' to denote that. 

 

In the Commodore arena, the TIFILE format is called the X00 format, and is a 32 byte header that replicates the CBM directory header, (same idea).  The X is replaced with P,S,R,U depending on file type (Program, Sequential, Relative, User), and the number is incremented as needed to ensure all names are 8.3 compliant and unique (as the format was created for an old DOS emulator long ago.

 

On newer SD-based drives for the CBM line, we support both native files (JIM.PRG) and X00 files (JIM.P00) alongside each other for loading, and for saving, there is a preference in the drive that tells the system how to format the files (if set to X00 format, all new files are stored in that format).  But, if a file is a X00 file, the filename displayed to the calling system is the one in the X00 file, not the name of the file on disk.  It does slightly slow down the system, as the file must be opened and the header read, but the AVR handily makes quick work of it, so I think the process is OK.

 

I like re-using the TIFILES format in this case (128 bytes left QUITE a bit of room for future expansion :-)), but I have a feeling folks will still want to support the native formats. 

 

Jim

 

 

 

  • Like 1

Share this post


Link to post
Share on other sites

I believe TIFILES origin is from XMODEM transfers in the terminal emulation software, to send a file up to a BBS, and then be able to get it back. 

 

We do have tools for manipulating TIFILES and moving things from cross assemblers or plain text, etc into or out of TIFILES.. so that might be a bonus.  

 

Treating records as opaque, I support native files on linux in TIPI with some rules... I never defined a mechanism to request a new file be created in native mode though... That is a feature classic99 supports. It is handy where possible to unburden data from archaic container formats... 

  • Like 1

Share this post


Link to post
Share on other sites

Yeah, I saw some references to XMODEM, and it makes sense that it developed from there.

 

Thanks for the insight.  I should have guessed there was a container format for TI files, but never really thought about it.

 

Handling directories in the TIPI way might be tough, given the precedent set by the TI74, but that's not a TIFILES issue per se.

 

Jim

 

Share this post


Link to post
Share on other sites

good reference for TIFILES can be found here.  .  @mizapf does a nice job adding intel to the site. 

https://www.ninerpedia.org/wiki/TIFILES_format

 

If you are familiar with the TI's level 2 disk IO subroutines, the TIFILE header's core 8 bytes representing the file's attributes come from the 'additional information' block, as used by disk DSR routines >14 and >15. 

 

The byte order (TIFILES header versus Additional Info block) is slightly different but there is good literature that explains, in various detail, the purpose of the bytes.  GPL File specifications and related TI docs can be found in the development resources thread if you wish to delve deeper into the old literature.

 

Share this post


Link to post
Share on other sites
7 hours ago, brain said:

Hmm, so everything you put in a single print statement, barring " : " delimiters, would get dumped into 1 record.

That is correct.

 

7 hours ago, brain said:

So, if I wanted to print 4 records with that single print statement, I'd do:

print #2:i;" : ";i^2" : ";sqrt(i)" : ";sin(i)" : ";"""       test"""

No. The delimiters should not be surrounded by quotes. This would work

PRINT #2:I : I^2 : SQRT(I) : SIN(I) : """       test"""

 

7 hours ago, brain said:

And, with the colon chars in place to denote fields, I don't need the triple """ to capture a retain leading spaces, so i could do:

print #2:i;" : ";i^2" : ";sqrt(i)" : ";sin(i)" : ";"       test"

Per my last comment, you want

PRINT #2:I : I^2 : SQRT(I) : SIN(I) : "       test"

However, for a string with leading or trailing spaces you want to keep, you do need to enclose it in explicit quotes ("") within the string-delimiting quotes as per the earlier PRINT.

 

7 hours ago, brain said:

And, when I read the resulting fields back in, can I do input #2:a$,b$,c$,d$,e$ or can you share the code needed?

Only string variable names can have a trailing ‘$’. Your line should be

INPUT #2:A,B,C,D,E$

 

...lee

 

Share this post


Link to post
Share on other sites
7 hours ago, brain said:

And the fact that those occur on different lines means the drive will put them in separate records?

 

Unless there is a trailing comma or semicolon, which would include the next PRINT statement as part of the same record.

 

...lee

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...