brain Posted September 6, 2020 Share Posted September 6, 2020 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 1 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 6, 2020 Share Posted September 6, 2020 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. 2 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 6, 2020 Share Posted September 6, 2020 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. -M@ 1 Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 7, 2020 Share Posted September 7, 2020 (edited) 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 September 7, 2020 by Lee Stewart clarification 2 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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. Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 (edited) 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 September 7, 2020 by brain typos Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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. 1 Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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. Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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 1 Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 1 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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. Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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.. Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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. Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 Here is a public doc on TIFILES... I stand on the shoulders of giants... http://ti99-geek.nl/Doc/Ti99_dsk1_fdr.html under his main site: http://ti99-geek.nl -> Documentation -> Comparison of a file descriptor record (FDR) and a TIFILES header Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 2 Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted September 7, 2020 Share Posted September 7, 2020 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... 1 Quote Link to comment Share on other sites More sharing options...
brain Posted September 7, 2020 Author Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted September 7, 2020 Share Posted September 7, 2020 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. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 7, 2020 Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 7, 2020 Share Posted September 7, 2020 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 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.