Jump to content
IGNORED

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


Lee Stewart

Recommended Posts

More Graphics mode musings—

 

I should probably dig this one out for myself but thought one of y'all might know: TI Forth (and fbForth, by extension) sets VDP register 1 (VR01) to B0h while it sets up VRAM and the other VDP registers for the selected graphics mode—except for bitmap mode. It sets VR01 to A0h for bitmap mode setup. They both blank the screen, which is the point. The only difference is that bit 3 (from the left) is on with VR01 = B0h. That sets text mode; but, with the screen blank, I don't think the mode matters. It seems to do just fine for graphics mode (32 column). After all, when the setup finishes, the mode is properly set before the screen reappears. If possible, I want to use the same screen-blanking code while I set up all VDP modes. Does anyone know whether it matters which code I use for VR01 to blank the screen during setup, B0h or A0h?

 

...lee

 

Well—unless someone comes up with a contrary example, my tests of flipping back and forth among the VDP modes using B0h to blank the screen seems to work just fine.

 

...lee

Link to comment
Share on other sites

Re Screen Fonts (again!)—

 

I think I'm going to handle screen fonts as follows:

  • At boot time or after a cold start, load the fbForth screen font (characters 0 – 127) from cartridge ROM.
  • Provide a Forth word ( NEWFONT ?) to load into the PDT a 1024-byte PROGRAM-format file (user-supplied pathname), containing the desired character patterns. The file shall be headerless, i.e., no non-font information at the beginning of the file as with CHARAx font files. NEWFONT will save information, using new variables, SCRFNT and FNTFIL (see next bullet), that will allow fbForth to reload that font when modes are changed.
  • Any time the user changes VDP modes, the system reloads the screen font indicated by SCRFONT (0 = cartridge font; nonzero = use value as the font file pointer, FNTFIL ). The user-supplied font file's pathname will be saved in VRAM and SCRFONT FNTFIL will contain its address.

I will also provide utilities to

  • Convert CHARAx files to the format fbForth expects,
  • Copy the cartridge font to a screen-font file,
  • Edit a screen-font file.

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Speaking of files—

 

I think I'm going to make some major changes with how fbForth 2.0 will mange file access. I like how TI Basic manages PABs as a linked list. That would allow fbForth to manage where any given PAB goes in VRAM and it might make it easier to devise some sort of memory management scheme for VRAM that would help with VDP mode switching's need to move things around. Thoughts?

 

...lee

Link to comment
Share on other sites

I'm having a little difficulty trying to figure out how to use the low-level fbForth support routines outside of high-level Forth in such a way that preserves fbForth's interrupt structure. The routines in question are listed in the spoiler below. Each routine's high-level Forth name is precede by the code-table number used to call it.

 

 

 

CODE=-20 WBLK (write block to blocks file)
CODE=-18 RBLK (read block from blocks file)
CODE=-16 MKBFL (create blocks file)
CODE=-14 USEBFL (use blocks file)
CODE=-12 GOTOXY
CODE=-10 ?KEY
CODE=-8  ?TERMINAL
CODE=-6  CRLF
CODE=-4  EMIT
CODE=-2  KEY
CODE=0   VSBW
CODE=2   VMBW
CODE=4   VSBR
CODE=6   VMBR
CODE=8   VWTR
CODE=10  GPLLNK
CODE=12  XMLLNK
CODE=14  DSRLNK
CODE=16  CLS
CODE=18  VMOVE
CODE=20  VFILL
CODE=22  VAND
CODE=24  VOR
CODE=26  VXOR 

 

 

 

It's proving quite difficult to call these particular routines from ALC through high-level Forth without quite a bit of code bloat. I can call them directly, but the individual routines (with two exceptions) do not mess with the interrupt mask. That is handled by the system calling code, which disables interrupts at entry and re-enables them upon return to the calling routine unless there's a pending, user-programmed interrupt. I suppose I could call them as in the following code example:

       LIMI 0
       BLWP VMBR
       LIMI 2

I just don't like scattering LIMIs all over the place, but maybe it's the best way. The only other alternative I see is re-writing the utilities I need in the bank in which I'm using them. Any ideas?

 

...lee

Link to comment
Share on other sites

It looks like the example code in the following spoiler ought to fill the bill regarding calling low-level fbForth system code. I think it gets the job done with the least code bloat and still preserves fbForth's interrupt structure.

 

 

 

*=====================================================================
* Screen Font (1024 bytes of patterns for characters 0-127)
*
* ...For now, we will simply load the font from DSK1.FBCHARA1.  We will
*    also presume that there are no user files at PABS.
*=====================================================================

*++ Font file PAB data: Load File opcode = 5,
*++ VDP address of buffer=@PDT, supplied by FONT routine.
*++ Maximum number of bytes to transfer = >400 = size of file.
*++ Name-length byte = Dh (length of file descriptor)
*++ File descriptor="DSK1.FBCHARA1"

FNTPAB DATA >0500,0,0,>400,>000D
       TEXT 'DSK1.FBCHARA1'
       EVEN

*++ This routine should only be called after PDT has the expected value!
*++ It presumes that there is no file using the PABS area.

*++ Called with:  BL  @FONT

*++  Copy font file's PAB to PABS
FONT   LI   R1,FNTPAB       RAM source of PAB data
       MOV  @$PABS(U),R0    VRAM destination of PAB data to R0
       LI   R2,23           bytes of PAB data to move
       LIMI 0               disable interrupts because VMBW doesn't
       BLWP @VMBW           write the PAB
*++  Copy VRAM destination (PDT) to PABS+2
       MOV  @PDT,R1         RAM source (PDT variable contents) to R1
       MOV  @$PABS(U),R0    PAB location to R0
       INCT R0              VRAM address of the PDT (destination = PABS+2)
       LI   R2,2            bytes of data to move (PDT address)
       BLWP @VMBW           write the VRAM address to the PAB
*++  Load the font from the file
       MOV  @$PABS(U),R0    PAB location to R0
       AI   R0,9            Convert to point to filename length byte
       MOV  R0,@SUBPTR      Copy to location needed by DSRLNK
       BLWP @DSRLNK         Copy the font to the PDT
       DATA 8
       B    @BKLINK         Return via low-level system return, which checks
                            ...for active user-defined ISR.  <--We probably
                            ...don't need to do this, but ... 

 

 

 

I included a LIMI 0 at line 27 just prior to the first BLWP @VMBW. The code executed by B @BKLINK (see below) checks for an active user ISR and, if none, issues a LIMI 2 before returning. Otherwise,the interrupt mask is left at 0.

BKLINK MOV  @INTACT,TEMP7
       JNE  BKLIN1
       LIMI 2
BKLIN1 B    *LINK

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Not to sidetrack but I am confused by your source statement MOV @$PAB(U),R0.

 

What is 'U' because my understanding (which may very well be wrong) is that the index has to be a reg ?

 

Sorry about that! You are correct—and, U is a register. It points to the base of the user variable table and $PABS is the offset into it of the PABS user variable, which points to the available space for file PABs. The registers, R8 – R15, in the fbForth workspace are labeled for convenience as follows:

EDIT--> These are notes, not ALC.  Shown are equivalent representations set in ALC by EQUates such as U EQU 8 for the first one---
   U    = R8   (base of user variable table)
   SP   = R9   (parameter stack pointer)
   W    = R10  (inner interpreter current word pointer)
   LINK = R11  (return linkage for CODE routines)
   CRU  = R12  (used for CRU instructions)
   IP   = R13  (inner interpreter's CFA [code field address] pointer)
   R    = R14  (return stack pointer)
   NEXT = R15  (points to Inner Interpreter's next instruction fetch routine, $NEXT)

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Testing for Running on TI-99/4—

 

I am considering doing away with the test for whether fbForth is running on a TI-99/4 and just assume it is running on a TI-99/4A. The only time fbForth tests for the TI-99/4 is at the point of loading the screen font. Lowercase patterns are not loaded if the TI-99/4 is detected. My problem is that I don't think fbForth would run on a TI-99/4 anyway and that the test is a waste of time. Anybody have any ideas? Anybody know whether a TI-99/4 has 16KB of VRAM?

 

...lee

Link to comment
Share on other sites

The 4 has the full 16K of VRAM--but the VDP doesn't have all of the features of the 9918A (I'd have to check the manual to be sure what they are, as I don't have those differences in my head at the moment).

 

With the 4 having the full 16K, I don't see the harm in not doing the test and just loading the lowercase patterns anyway. Even though they won't get used by the keyboard scanning routine, they would be available for program use. It actually seems a little short-sighted on TI's part to not load the LC patterns just because you can't type them with the keyboard. You ought to be able to use them to display LC characters. Even if not, not running the test would eliminate unnecessary code at startup. I should be able to test this in Classic99. I don't know why I didn't think of that before I posed the question. Oh, well....

 

...lee

Link to comment
Share on other sites

The only difference on the VDP in the TI console from a software point of view is the lack of bitmap mode on the 4.

 

I did detection of 4 versus 4A in my multicart loader, more to see if I could than for any practical reason, but the GROMs are different. The GPLLNK vector for lowercase is completely absent in the 4 (trying to call it will cause a crash), and the character set is only 6 bytes per character instead of 7 in the 4A (important in my case as I was loading it myself instead of using GPLLNK).

 

All that said, I don't think anyone /uses/ the 4 anymore - it's more a collector's item today. Assuming 4A is pretty safe.

  • Like 1
Link to comment
Share on other sites

The only difference on the VDP in the TI console from a software point of view is the lack of bitmap mode on the 4.

 

I did detection of 4 versus 4A in my multicart loader, more to see if I could than for any practical reason, but the GROMs are different. The GPLLNK vector for lowercase is completely absent in the 4 (trying to call it will cause a crash), and the character set is only 6 bytes per character instead of 7 in the 4A (important in my case as I was loading it myself instead of using GPLLNK).

 

All that said, I don't think anyone /uses/ the 4 anymore - it's more a collector's item today. Assuming 4A is pretty safe.

 

I know what you're saying about 7 bytes per character in the 4A; but, in actual fact, the characters in the PDT are 8 bytes per character—at least, they are in the 4A. The GPL routine provides the first >00 byte for the top row of pixels of every character to save 96 bytes of storage. For fbForth 2.0, I am supplying my own font by simply copying from ROM space the 1K for 8 bytes X 128 characters (ASCII 0 – 127). I was unaware of the 6-byte storage for the 4 and can't figure out how that would work unless the fact that there is also a vertical byte of zeroes for every letter could be efficiently worked into the GPL routine.

 

...lee

Link to comment
Share on other sites

I was unaware of the 6-byte storage for the 4 and can't figure out how that would work unless the fact that there is also a vertical byte of zeroes for every letter could be efficiently worked into the GPL routine.

Nope, the characters are only 6 bytes tall with two bytes of 0 instead of one - you can see this in Classic99 by selecting the 99/4 system.

 

Since you are supplying your own fault, the contents of GROM won't matter to you :) I thought you were reading the built-in one. In that case there's no reason not to copy lowercase letters even on the 4 - the uppercase-only limitation is only in the keyboard, nowhere else. :)

Link to comment
Share on other sites

Nope, the characters are only 6 bytes tall with two bytes of 0 instead of one - you can see this in Classic99 by selecting the 99/4 system.

 

Since you are supplying your own font, the contents of GROM won't matter to you :) I thought you were reading the built-in one. In that case there's no reason not to copy lowercase letters even on the 4 - the uppercase-only limitation is only in the keyboard, nowhere else. :)

 

You are correct. I was using the built-in font. I have changed that for fbForth 2.0 (cartridge version).

 

BTW, fbForth 2.0 (beta) seems to load and run alright in TI-99/4 mode in Classic99, albeit with a few issues I would need to track down were I to advertise the fact. Right off the bat, the load enters a 'C' on the command line that is not there in TI-99/4A mode. Backspacing over it works, but it should not be there. In light of the likely lack of need/desire to run fbForth on a 4, I'm not sure it's worth the time to make it 4-functional.

 

...lee

Link to comment
Share on other sites

Or you could just identify the issues and leave them alone, Lee--but describe them (and any known workarounds) in a special appendix of the manual. That way, the rare 99/4 user will know exactly what things to avoid doing from the get go. . .and won't have expectations of programming perfection. :)

  • Like 1
Link to comment
Share on other sites

I'm beginning to think really seriously about how I'm going to get fbForth into ROM. Right now, I'm planning to use up to 4 ROM banks. I suppose I have to presume that the cartridge might start up in any ROM bank and that I'll need to direct it to the proper startup code from each ROM bank. I'm probably going to need some direction here because I'm not at all sure of what I'm about to do.

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Do you have the capability to burn ROMs, Lee? If you do, I can get you a module to use for development. . .I still have a couple of the 64K cart board that I haven't used up, a few of the 128Kx4 boards, and a bunch of the 512K boards.

Edited by Ksarul
Link to comment
Share on other sites

Do you have the capability to burn ROMs, Lee? If you do, I can get you a module to use for development. . .I still have a couple of the 64K cart board that I haven't used up, a few of the 128Kx4 boards, and a bunch of the 512K boards.

 

Thanks for the offer. I have a handful of 64K boards and parts, except for EPROMs, which I also plan to get soon. I do not yet have a burner, but plan to get one in the near future. Though I have never burned EPROMs, I don't expect that to be a problem. It's the software I'm puzzling over. I was marginally unclear in my last post, which I have edited—I omitted 'bank'. I'm not having a conceptual problem with bank switching—it's the startup machinations that have me a little concerned.

 

...lee

Link to comment
Share on other sites

I'm beginning to think really seriously about how I'm going to get fbForth into ROM. Right now, I'm planning to use up to 4 ROM banks. I suppose I have to presume that the cartridge might start up in any ROM bank and that I'll need to direct it to the proper startup code from each ROM bank. I'm probably going to need some direction here because I'm not at all sure of what I'm about to do.

 

...lee

 

In studying @Willsy's source code for TurboForth 1.2, I'm finally getting a pretty clear picture of what I need to do, which is pretty much what I articulated in my above post. It will still be awhile before I manage all the balls I have in the air—one of which is figuring out exactly how I deal with GPL returns. I cannot do the same thing TI did with TI Forth and, by extension, what I did with fbForth 1.0, which was to save the GPL return address from the E/A loader. I will probably need to do something similar to what MG did with their universal GPLLNK/DSRLNK routine, which was to snag code in the console. I need to think on it a bit. :ponder: Any suggestions are, of course, very welcome.

 

...lee

Link to comment
Share on other sites

Lee, you could potentially keep things the same--if you put an E/A grom in your cartridge using an ÜberGROM board. . .bonus there is that the cart then can become a dual-use item if you leave the option to boot it into the E/A. Gazoo's GPL loader could also be modified to help here, as it then guarantees the boot bank of the cartridge by setting it during the GPL power-up routines. I may be off-base here, but I hope the idea is of use.

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