Jump to content
IGNORED

fbForth—TI Forth with File-based Block I/O [Post #1 UPDATED: 06/09/2023]


Lee Stewart

Recommended Posts

I have MKBFL working now on the real iron with nanoPEB. I will clean up the ALC and post fbForth v0.92 today or tomorrow.

 

To summarize the situation, TI Forth's block I/O support ALC has three functions: drive-select. read-disk and write-disk. There is no need of a special drive-select function in fbForth. I have four functions in fbForth for block I/O support: "open"-blocks-file, create-blocks-file, read-block and write-block. The latter two are file-sector equivalents of TI Forth's read/write-disk. Three of the four I/O functions in fbForth call DSRLNK only once and each time they get a new TB and AIB, so there is no issue with the TB and AIB getting trashed. The issue is with the create-blocks-file function because, after the first call to DSRLNK, which creates the file, I am looping through a block of code that writes four sectors of blanks for each block in the new file and I was relying on the survival of most of the TB and AIB between calls. I was renewing only what the docs say changes and then what changed in Classic99. Now, of course, I should probably renew everything each time through the loop. Like I said, I'll clean up the ALC and re-post soon. :P

 

...lee

It is also good practice to reset the pointers into the PAB (0x8356, for example) to known states, if for no other reason than your own sanity. :)

Link to comment
Share on other sites

With the buzz in another thread about an IDE controller for the PEB, I suppose I should consider other devices for blocks files for fbForth. I believe that would require a different method of access from the Level 2 Subprogram access (DSRLNK Ah) I am using. I believe that Level 3 access (DSRLNK 8 ) will properly parse the DSR chain until it finds one with IDE (or whatever device name is used) or fails; but, it does not appear to me that Level 1 and Level 2 access methods work that way. Of course, I could be missing something. It looks like the first DSR that has a match for the subprogram name will execute. The TI disk controller has subprograms 10h, 11h, 12h, 13h, 14h, 15h and 16h. Do the IDE, SCSI, etc. DSRs even provide the same type of access at Levels 1 and 2? If they do, are the subprograms named differently, i.e., 20h, 21h, ... so long as they are different from 10h–16h? @InsaneMultitasker? @Tursi? @matthew180? @Willsy? @senior_falcon? Anyone?

 

...lee

Link to comment
Share on other sites

With the buzz in another thread about an IDE controller for the PEB, I suppose I should consider other devices for blocks files for fbForth. I believe that would require a different method of access from the Level 2 Subprogram access (DSRLNK Ah) I am using. I believe that Level 3 access (DSRLNK 8 ) will properly parse the DSR chain until it finds one with IDE (or whatever device name is used) or fails; but, it does not appear to me that Level 1 and Level 2 access methods work that way. Of course, I could be missing something. It looks like the first DSR that has a match for the subprogram name will execute. The TI disk controller has subprograms 10h, 11h, 12h, 13h, 14h, 15h and 16h. Do the IDE, SCSI, etc. DSRs even provide the same type of access at Levels 1 and 2? If they do, are the subprograms named differently, i.e., 20h, 21h, ... so long as they are different from 10h–16h? @InsaneMultitasker? @Tursi? @matthew180? @Willsy? @senior_falcon? Anyone?

 

...lee

Short answer: Yes to your observations. The subprograms are named differently for hard disk access. The HFDC and SCSI share the same subprogram names (20, 21, 22, etc) for compatibility; though this leads to problems when both cards are in the same system. The IDE card subprogram names are different (80, 81, 82, etc) which is nice for multi-card systems; not so nice for legacy program compatibility.

 

I cannot copy links on this machine, but if you read Matthew's recent topic, you'll find a little more info. Locate the Myarc HFDC manual as it is easy to compare and contrast the subprograms using that as your guide.

Link to comment
Share on other sites

Short answer: Yes to your observations. The subprograms are named differently for hard disk access. The HFDC and SCSI share the same subprogram names (20, 21, 22, etc) for compatibility; though this leads to problems when both cards are in the same system. The IDE card subprogram names are different (80, 81, 82, etc) which is nice for multi-card systems; not so nice for legacy program compatibility.

 

I cannot copy links on this machine, but if you read Matthew's recent topic, you'll find a little more info. Locate the Myarc HFDC manual as it is easy to compare and contrast the subprograms using that as your guide.

 

Thanks, Tim. I guess the best course of action for fbForth is to go to Level 3 file access. It was just so simple using SPs 14h and 15h to read/write an entire 4-sector block in one pass. TI Forth could not use anything but Floppies for its blocks, so, at least, fbForth does that. I may wait until I'm ready to do the cartridge version to change to record-level access, however.

 

...lee

Link to comment
Share on other sites

Is TurboForth set up for IDE? (not fbForth related, just seems like a good place and time to ask)

 

Owen...

 

I would think the answer is "yes" because TurboForth uses Level 3 file I/O for blocks, though @Willsy only reserved 20 spaces for the filename, so dir/subdir use would be limited. And...you could claim that your post is fbForth-related by virtue of the fact that I might lift some of Mark's code for this purpose before this makes it to cartridge. :P

 

...lee

  • Like 1
Link to comment
Share on other sites

Well then. =) Looks like I'm not quite as off-topic as I'd thought. =)

 

Haven't had any time for Forthing lately. I still REALLY want to port Lemonade Stand to Forth. It would be relatively simple... It's not much graphically and the primary stuff is simple KSCANs for plugging values into variables. Really as simple a setup as you could possibly imagine... Would be a nice intro into TF or fbForth.

 

 

 

 

Owen

Link to comment
Share on other sites

Owen...

 

I would think the answer is "yes" because TurboForth uses Level 3 file I/O for blocks, though @Willsy only reserved 20 spaces for the filename, so dir/subdir use would be limited. And...you could claim that your post is fbForth-related by virtue of the fact that I might lift some of Mark's code for this purpose before this makes it to cartridge. :P

 

...lee

 

Hmmm... Only reserved 20 bytes... So I did... Bugger... I thought I reserved more than that. I'll have to up it.

 

TF runs perfectly fine on IDE. We've tested it on IDE, SCSI, HDK (Fred's RS232 thingy) CF7, nanPEB, BwG disk controllers, TI disk controllers, Myarc disk controllers, Myarc HD controller, and just about every type of RAM disk available. All works. There's no magic in TF at all that makes it "so" compatible, it's just that I stick to the level 3 DSR access only, which does seem to be consistently implemented by different system vendors. Once you get to level 2 and level 1, all bets are off! Stick to level 3! :grin:

Link to comment
Share on other sites

I have MKBFL working now on the real iron with nanoPEB. I will clean up the ALC and post fbForth v0.92 today or tomorrow.

...

 

I've decided to just post the QAD code as Version 0.91a and start working on converting the blocks-file I/O code to Level 3 file I/O for Version 0.92. That may be a few days! Meanwhile, the attached fbForth v0.91a should work on nanoPEB/CF7+ systems. [fbForth still appears as v0.91, however.]

 

...lee

 

fbForth091a.zip

  • Like 1
Link to comment
Share on other sites

I am looking at how to handle default files when DSK1 is not the boot device for fbForth. If there were a way to do boot tracking in ALC, my problem would be solved, I think. I plan to use @Willsy's method of holding down a key to boot from some other device than DSK1; but, I'm not sure what to do if the user doesn't hold down a key. I can issue an error message; but, I've been relying on the message file being on DSK1, as well! The only message at this point would be a '?'. I would have to waste more RAM for an unambiguous message. Oh, well...

 

...lee

Link to comment
Share on other sites

@Willsy...

 

Regarding USEBFL (TurboForth's USE ), I am pretty sure I currently have it wrong for compile mode and need to change my implementation. If I understand it correctly, when USE executes while loading a block, that's the end of interpretation of that block, right? If that is so, I am not sure how useful it is for it to ever occur in a block in compile mode. Am I missing something?

 

...lee

Link to comment
Share on other sites

I guess I'm talking to myself, here. My main concern with trying to figure out whether boot-tracking is possible has to do with devices other than DSK, such as IDE or SCSI and subdirectory use on same. I suppose I could have the system ask for the path to system files if it can't find them—that just seems so unrefined, but I may have no choice!

 

...lee

Link to comment
Share on other sites

Anybody done boot-tracking in ALC? @InsaneMultitasker? @Tursi? @matthew180? @Willsy? @senior_falcon? @apersson850?

 

...lee

Floppy boot tracking is generally do-able through some DSR gymnastics. Honestly, I tend to use a simple configuration file to avoid pitfalls of the various routines and devices.

 

One trick I've used is a dedicated image file in the load chain specifically and only containing the path(s) and configuration data. Because it is in the chain it loads automatically; and since it is a simple file, I can use LOAD/SAVE image (opcodes 05/06) to save/load the data to/from disk. Then if the program cannot find the files, I display the currently stored path and request the user point to the proper files. Once a path is provided I allow the user to continue or to save the path back to the file.

Link to comment
Share on other sites

Floppy boot tracking is generally do-able through some DSR gymnastics. Honestly, I tend to use a simple configuration file to avoid pitfalls of the various routines and devices.

 

One trick I've used is a dedicated image file in the load chain specifically and only containing the path(s) and configuration data. Because it is in the chain it loads automatically; and since it is a simple file, I can use LOAD/SAVE image (opcodes 05/06) to save/load the data to/from disk. Then if the program cannot find the files, I display the currently stored path and request the user point to the proper files. Once a path is provided I allow the user to continue or to save the path back to the file.

 

Thanks, Tim. This sounds like what I might want to do. I know how to do the LOAD/SAVE, but I don't know what "in the load chain" might mean. Do you need to use something like "DSK.<disk-name>.<file-name>"? If so, how would you do that with IDE or SCSI disks?

 

...lee

Link to comment
Share on other sites

Thanks, Tim. This sounds like what I might want to do. I know how to do the LOAD/SAVE, but I don't know what "in the load chain" might mean. Do you need to use something like "DSK.<disk-name>.<file-name>"? If so, how would you do that with IDE or SCSI disks?

 

...lee

Ah. Sorry, that does sound a bit muddled.

 

Say for instance you loaded Fred's DM2K. The program consists of DM2K, DM2L, DM2M, DM2N. These files are chained together by a 6-byte header (within each file) to indicate to the E/A option 5 loader the length, the type of file, and the load address. The key here is a flag that tells the loader if there is another file "in the chain"; if so, the last character of the filename is incremented and the next file loaded.

 

Thus the four files are chained. If I wanted to create a file to hold configuration data, I could include a fifth file (call it DM2O) holding the data and use the properties of the loader to include it. In this manner no tracking is required because the config would be loaded during the initial load of Fred's Disk Manager.

 

I made an assumption that you are loading your Forth 'interpreter' from disk as an EA5 image. Sorry about that.

  • Like 1
Link to comment
Share on other sites

Ah. Sorry, that does sound a bit muddled.

 

Say for instance you loaded Fred's DM2K. The program consists of DM2K, DM2L, DM2M, DM2N. These files are chained together by a 6-byte header (within each file) to indicate to the E/A option 5 loader the length, the type of file, and the load address. The key here is a flag that tells the loader if there is another file "in the chain"; if so, the last character of the filename is incremented and the next file loaded.

 

Thus the four files are chained. If I wanted to create a file to hold configuration data, I could include a fifth file (call it DM2O) holding the data and use the properties of the loader to include it. In this manner no tracking is required because the config would be loaded during the initial load of Fred's Disk Manager.

 

I made an assumption that you are loading your Forth 'interpreter' from disk as an EA5 image. Sorry about that.

 

Nice! That's really clever. Right now fbForth is a compressed object file, so I'd have to redesign it to use E/A's SAVE utility, I guess. I don't want to do what TI did with TI Forth, which was to hard-code "DSK1." into the BOOT program (FORTH) to load FORTHSAVE. Whatever I do in this regard will probably need redesigning when I move fbForth to cartridge. By then, however, I hope to only need to worry about the FBLOCKS file. I plan to hoist FBCHARS and FBMSGS into cartridge space—though I may need to reconsider that for FBMSGS. Thanks, again!

 

...lee

Link to comment
Share on other sites

@Willsy...

 

Regarding USEBFL (TurboForth's USE ), I am pretty sure I currently have it wrong for compile mode and need to change my implementation. If I understand it correctly, when USE executes while loading a block, that's the end of interpretation of that block, right?

 

No. Interpretation of that block continues until the next "thing" that invokes some kind of block operation. E.g. -->

 

I think that's what TF does. In addition, I think TF does an EMPTY-BUFFERS (which won't stop the current buffer from being interpreted - it just sets the buffers to 'un-used'. That in itself will not stop the buffer from continuing to be interpreted to the end of the buffer, or until something invokes a block operation.

 

I'll have to try it. It's been a while, and I'm sure I broke something else in the meantime :twisted:

Link to comment
Share on other sites

I guess I'm talking to myself, here. My main concern with trying to figure out whether boot-tracking is possible has to do with devices other than DSK, such as IDE or SCSI and subdirectory use on same. I suppose I could have the system ask for the path to system files if it can't find them—that just seems so unrefined, but I may have no choice!

 

...lee

 

Sounds like you need two types of paths. One for user blocks and one for system blocks. So, rather than USE or equivalent, I think you need two words:

 

S" HDK1.FBFORTH.BLOCKS" SYS-BLK

 

This sets the systems blocks file to HDK1/FBFORTH/BLOCKS

 

S" DSK3.MYBLOCKS" USR-BLK

 

Users project disk/blocks is DSK3.MYBLOCKS

 

Now the system knows where to go for it's error messages etc, and you don't need to nest/un-nest things like file names; the system can simply switch between them. Most of the time the user blocks will be the 'active' blocks file.

 

It would be cool if your block buffer system could be expanded to know which buffer he is holding - a SYS block or a USR block. This would be essential when FLUSH time comes around...!

 

FWIW!

Link to comment
Share on other sites

No. Interpretation of that block continues until the next "thing" that invokes some kind of block operation. E.g. -->

 

I think that's what TF does. In addition, I think TF does an EMPTY-BUFFERS (which won't stop the current buffer from being interpreted - it just sets the buffers to 'un-used'. That in itself will not stop the buffer from continuing to be interpreted to the end of the buffer, or until something invokes a block operation.

 

I'll have to try it. It's been a while, and I'm sure I broke something else in the meantime :twisted:

 

I think I know what I've done wrong. I'm using the same mechanism with USEBFL for tracking the currently interpreting block as when I'm temporarily switching blocks for character-loading or messages, making USEBFL essentially useless |:). I obviously need to change that!

 

...lee

Link to comment
Share on other sites

Sounds like you need two types of paths. One for user blocks and one for system blocks. So, rather than USE or equivalent, I think you need two words:

 

S" HDK1.FBFORTH.BLOCKS" SYS-BLK

 

This sets the systems blocks file to HDK1/FBFORTH/BLOCKS

 

S" DSK3.MYBLOCKS" USR-BLK

 

Users project disk/blocks is DSK3.MYBLOCKS

 

Now the system knows where to go for it's error messages etc, and you don't need to nest/un-nest things like file names; the system can simply switch between them. Most of the time the user blocks will be the 'active' blocks file.

 

It would be cool if your block buffer system could be expanded to know which buffer he is holding - a SYS block or a USR block. This would be essential when FLUSH time comes around...!

 

FWIW!

 

Good point!—except that all I need is the system path once. As far as I'm concerned, USEBFL should be agnostic as to system vs. user blocks.

 

...lee

Link to comment
Share on other sites

Good point!—except that all I need is the system path once. As far as I'm concerned, USEBFL should be agnostic as to system vs. user blocks.

 

Is that true? What if the system needs to look up an error message? Doesn't it go to disk for the error messages?

Link to comment
Share on other sites

Is that true? What if the system needs to look up an error message? Doesn't it go to disk for the error messages?

 

Yes, but I'm not using USEBFL to get there. It's a very similar mechanism, but not that particular word. It's also hard-wired to expect the message file to be on DSK1. I plan to remedy that with whatever path mechanism I can dream up, like asking the user for the path when the file can't be found. As I change to Level 3 file I/O for blocks, I think I need to rethink this whole character-file/message-file/blocks-files scenario. I kind of like Tim's configuration-file idea, but I'd need to set up the fbForth executable as an E/A5 program. That might be difficult because I may be trashing the loader. I suppose I could AORG that part of the program somewhere else until fbForth gets control and, then, move it to its proper place. Once again, I have too many balls in the air!

 

...lee

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...