Low Level Filesystem Access: Difference between revisions
Line 130: | Line 130: | ||
== Published ROM Calls for Manipulating RAM Files == | == Published ROM Calls for Manipulating RAM Files == | ||
Most of the following routines can be used only to | Most of the following routines can be used only to manipulate DO files in RAM. | ||
The routine '''MAKTXT''', called at 220F, creates a DO file in the RAM directory with the name specified in the buffer at FC93 through FC98. If the file already exists, the routine returns with the carry flag set. | The routine '''MAKTXT''', called at 220F, creates a DO file in the RAM directory with the name specified in the buffer at FC93 through FC98. If the file already exists, the routine returns with the carry flag set. |
Revision as of 00:01, 7 April 2009
RAM File System
(Significantly extended from "Published RAM File Handling Routines" in "Inside the TRS-80 Model 100" by Carl Oppedahl)
Table Structure
User files reside in RAM starting at the lowest installed RAM address, with BA files at the bottom, followed by DO files and CO files. The directory is located in high memory from $F962 to $FA8B. The directory is terminated by a sentinel value $FF byte. Thus there are 297 bytes in the table itself; dividing by 11 yields 27 slots. The format of the filename information is given in table 18.1.
Byte | Description |
---|---|
0 | Directory flag (see table 18.2) |
1-2 | File start address |
3-10 | Eight-byte file name |
Bit | Description |
---|---|
7 | 0 if a killed file |
6 | 1 if a DO file |
5 | 1 if a CO file |
4 | 1 if located in ROM |
3 | 1 for invisible file |
2-1 | Reserved |
0 | Internal use only |
Notice that no entry exists for filesize. To determine filesize, either of two techniques may be used. By comparing the various start addresses, one can determine the next file's starting address. The two start addresses may simply be subtracted.
However, the filenames in the directory are not in order by start address, so one must search the entire directory to find the next file up. The ending address of the top file is stored at FBB2+.
Another way to determine file size is by examining the files themselves, since the file itself always contains enough information to determine its size. With BA and DO files, you must scan the file, beginning at the start address, to locate the end-of-file marker. For DO files, the EOF characters is $1A (26 decimal). For BA files, it is a three character sequence, 00H,00H,00H.
For CO files, there is no end-of-file character as such, but the length of the file is determined by adding the value of the third byte to the product of 256 times the fourth byte, plus six.
Suzuki, Hayashi and RickY
Note the difference between the number of slots you can see on the screen, 24, and the number of directory entries, 27. That means there are 3 hidden entries.
If you are experimenting with a Model 100 (as apposed to T102), sooner or later you will stumble across the NUL-prefixed names Suzuki, Hayashi and RickY in the directory.
Hayashi ($F9A4) and RickY ($F9AF) are .DO files. Hayashi is the PASTE buffer. RickY is the current BASIC line when in EDIT mode.
Suzuki ($F999) is the location of the BASIC program, if any, that has not yet been SAVEd and therefore does not have a name. (It is the file you sometimes see listed as BASIC*.) Sometimes you select BASIC from the main menu and find that some lines are still present from the last time you were in BASIC; these lines were hiding in Suzuki.
Suzuki and Hayashi take up memory, of course, like any other files. Suzuki can be emptied by entering BASIC and typing NEW. Hayashi can be emptied by copying a zero-length selection to the PASTE buffer. RickY should only exist while the EDIT command runs.
On the T102, these names were removed. Reportedly, programmers embedding their name in the ROM was considered bad form by Tandy.
DO Files
A DO file's first character is that which would be returned if you accessed it with TEXT or with BASIC's OPEN and INPUT statements. The file ends with the $1A described above.
BA File Format
A BA file in RAM is set up as a sequence of lines, each with the following form:
2 bytes | Address of the line number to follow (little endian) |
2 bytes | Current line number (little endian) |
Numerous bytes | Program line in tokenized form |
1 byte | Null (00H) |
The file ends with two more nulls (00H), making the last three characters nulls.
CO File Format
The format of a CO file is as follows:
2 bytes | Address to load file to (little endian) |
2 bytes | Number of bytes to load (little endian, six fewer than the size of the RAM file, because of these six address bytes) |
2 bytes | Transfer (start) address |
many bytes | Contents of file |
Accessing Files
BASIC's PEEK statement can be used to examine the file contents without the danger of altering the file. The use of POKEs with files, however, is discouraged unless you know precisely what you are doing. If you must POKE, keep the following in mind.
- POKE only within the files, not elsewhere in RAM. In particular, do not POKE to addresses at or above 62960 (F5F0).
- If you create an end-of-file (EOF) marker within a DO file, you must delete any characters from there up to the beginning of the next file. Use MASDEL, described below.
- If, within a BA file, you tamper with any of the file format addresses described above in memory, such as the BASIC address of the following line number, the program will no longer function properly.
Published ROM Calls for Manipulating RAM Files
Most of the following routines can be used only to manipulate DO files in RAM.
The routine MAKTXT, called at 220F, creates a DO file in the RAM directory with the name specified in the buffer at FC93 through FC98. If the file already exists, the routine returns with the carry flag set.
Upon exiting the routine, the HL register points to the TOP address of the new file (the address at which new characters would be added), and DE points to the address of the directory file flag, located somewhere in the directory starting at F962.
The routine CHKDC, called at 5AA9, examines the directory to determine if a specified filename is present in the directory as a valid file. Prior to the call, DE should point to the first in a series of memory addresses (RAM or ROM) containing a filename in ASCII followed by a null.
(Jhoger 22:39, 4 April 2009 (PDT) note: I've found that I need to call LNKFIL before calling CHKDC if the file I want to access was recently created by SAVEM)
Upon return, the Z flag is set if no such file was found. If the file was found, HL points to the directory entry.
A complementary routine, GTXTTB, called at 5AE3, finds the TOP address of the file assuming its location in the directory is known. If you provide the address of the directory entry in HL, it returns the TOP address of the file.
The routine KILASC, called at 1FBE, kills a DO file. Prior to the call, DE must be set to the starting address of the file, and HL must be set to the address of the directory entry. Everything above it in user memory (CO files and other DO files) is moved down to fill in the space.
The routine INSCHR, called at 6B61, inserts one character in a DO file, Prior to the call, HL points to the address at which to insert the character, and A contains the character to be inserted. Everything above in user area (all CO files and some DO files) is moved up one position.
If there is no more room in RAM, the routine returns with the carry flag set.
The routine MAKHOL, called at 6B6D, inserts a specified number of spaces in a file. Everything is moved up in memory to accommodate the spaces. These spaces may later be changed as desired. Prior to the call, BC must contain the number of spaces to be inserted, and HL must point to the address at which to insert the spaces. HL and BC are preserved, which is handy. If there was insufficient room in RAM, the routine returns with the carry flag set.
The routine MASDEL, called at 6B9F, deletes a specified number of characters from a file. Prior to a call, BC must containt the number of characters to be deleted, and HL should point to the address at which to begin deleting. HL and BC are preserved.
How RAM File Creation Works
(Steve Adolph)
There are a number of pointers in high memory that are used to demarcate the area used for basic files text files the three scratchpads machine language files
These pointers need to be modified according to what you need to insert or delete. For example, if you add a .CO file, then you don't need to modify the pointers that deal with the lower file space. (Jhoger 20:27, 6 April 2009 (PDT): I think you would still need to call MAKHOL to avoid smacking up BASIC variable region) But, adding a .BA moves all the pointers.
To create a file you need to
- wedge open the file space at a precise location, depending on the file type and the pointer values...placement is critical because of a fundamental assumption in the directory management
- load all the appropriate data into that memory hole, representing the actual file data
- create a directory entry with the right stuff in the entry to connect with that file
- run the magic LNKFIL ($2146) routine that re-assigns all the directory links and connects them to the right files again
Deleting a file is kinda similar.
The fundamental assumption is that the order of the files must be maintained within each file type. That way the linker can deduce which file directory entry is associated with a specific file.
IE the next .BA directory entry must be associated with the next found file in the .BA area. and so on.