Willsy Posted March 5, 2015 Share Posted March 5, 2015 Here's an article I'm preparing for the TurboForth website. I thought I'd chuck it out here for 'yall to have a look at. It presents a library that allows Forth programmers to use the SAMS memory expansion very easily indeed. In fact, I'll stick my neck out and say that I can't really think of a way to make it any easier. Comments warmly welcomed. A SAMS Programming Library for TurboForth IntroductionThe SAMS memory expansion for the TI-99/4A is a useful, though woefully underutilised device. Despite offering a full megabyte of memory, literally only a handful of programs exist that can take advantage of it. TurboForth has built in support for the SAMS unit, allowing memory pages to be paged in and out. However, it has no inherent programming support for the SAMS unit. This paper discusses a tiny support library written in high-level Forth which allows colon definitions to be hosted in SAMS paged memory. The dictionary entries for the colon definitions continue to be defined and linked in “normal” memory, meaning that a colon definition can be found, ticked, and executed regardless of the SAMS bank in which it is hosted, and regardless of whether it is paged into memory or not. Colon definitions can be written (in any bank) which reference code in any bank, with complete disregard to the mechanics of paging memory in and out; the paging and un-paging of banks is handled completely transparently by the support library. Declaring the Number of BanksBefore the library can be used, the number of SAMS that you wish to use must be declared. 248 banks are available, numbered from 0 to 247, giving up to 992K or usable memory. The remaining banks of the SAMS constitute the standard 32K of the TI. The declaration is made with the BANKS word. BANKS ( n -- ) As can be seen from the above stack comment, BANKS requires a value on the stack. For example: 20 BANKS This actually reserves some memory (in the standard 24K segment, which is not paged) to track the ‘HERE’ pointers for each bank. HERE in Forth parlance gives the address of the next datum to be compiled to memory. Writing “Banked” Colon DefinitionsIt is very easy to write a colon definition in a particular bank. Simply use the word SETBANK to set the active bank. All colon definitions will be defined in the selected bank until another bank is selected: SETBANK ( n -- ) For example: 3 SETBANK Now, any colon definition defined will be defined in bank 3: : test ( -- a b c ) 1 2 3 ; This definition will be compiled into bank 3. Note that after each colon definition is defined a report is given on the amount of free memory in the bank. A bank is 4K (4096 bytes) in size. Care should be taken not to allow code to spill outside of the 4096 byte limit. Switch to a new bank if you think the next definition will not fit in the available space. Disabling Banked CompilationTo disable banked compilation and resume compilation in “normal” un-banked memory simply give the value -1 to SETBANK as follows: -1 SETBANK At this point, compilation resumes in normal un-paged memory. Variables, Values and ConstantsVariables, values, and constants continue to be compiled into normal un-paged memory regardless of the active bank setting. Due to their small size there’s no particular advantage to putting them in banked memory, and the overhead of a bank switch to obtain their value would not make sense. Calling Code in Different BanksIt is possible for a word in any bank to refer to a word in any other bank. No special action is required on the part of the programmer. For example: 4 BANKS 0 SETBANK : TOM ( -- ) .” Tom “ ; 1 SETBANK : DICK ( -- ) .” Dick “ ; 2 SETBANK : HARRY ( -- ) .” Harry “ ; 3 SETBANK : TDH ( -- ) CR TOM DICK HARRY CR ; Here, code in bank 3 refers to code in banks 0, 1 and 2. Although they all occupy the same physical address in the TI’s memory map (the 4K region at >3000 to >3FFF) the banking is all handled automatically. Nesting of Banked DefinitionsBanked words/definitions can call words in other banks, which in turn call words in other banks, which in turn call words in other banks etc. This is achieved through the use of a “bank stack” implemented in the support library which pages the banks in and out as required. No action is required on the part of the programmer. For example: 0 SETBANK : TOM ( -- ) ." TOM " ; 1 SETBANK : DICK ( -- ) TOM ." DICK " ; 2 SETBANK : HARRY ( -- ) DICK ." HARRY" ; 3 SETBANK : GO ( -- ) CR HARRY CR ." FINISHED!!" CR ; -1 SETBANK GO In the above example, GO, which is in bank 3, immediately calls HARRY in bank 2. HARRY immediately calls DICK in bank 1. DICK immediately calls TOM in bank 0, which displays TOM then exits back to DICK in bank 1, which displays DICK, then exits back to HARRY in bank 2 which displays HARRY, then exits to GO in bank 3, which displays FINISHED!! Then exits. Note that the bank nesting and un-nesting is handled completely transparently. Ticking and Executing Banked WordsThe dictionary entries for banked words are actually compiled into normal, standard, un-banked memory. Only the executable code for a colon definition is compiled into the appropriate bank. This was a deliberate design decision as it allows words to be found with FIND (the word in the Forth system that searches the dictionary for words), allows them to be ticked with ‘ and [‘] and also allows them to be compiled with COMPILE and/or [COMPILE] and executed with EXECUTE with no special treatment required whatsoever. The CodeThe code for the SAMS programming support library is presented below. As written below, it occupies 694 bytes of memory (0.6K). It is a testament to the power and flexibility of Forth that such functionality can be ‘grafted’ into the Forth system, whilst being implemented in Forth itself. create _bnkstk 20 cells allot \ bank stack _bnkstk value _bsp \ pointer into bank stack -1 value _bank \ current bank 0 value _heres \ holds "here" for each bank 0 value _nhere \ "normal" here 0 value _maxBank : >bank ( bank -- ) \ push bank to bank stack 2 +to _bsp dup _bsp ! $3000 >SAMS ; : bank> ( -- ) \ pop bank from bank stack -2 +to _bsp _bsp @ $3000 >SAMS ; : banks ( n -- ) \ reserve space for here pointers for n banks here to _heres dup to _maxBank dup 0 do $3000 , loop \ init "here" for each bank to $3000 cr 4 * n>s type ." K of banked memory reserved." cr ; : b: ( bank -- ) \ begin compiling a banked definition in bank bank _bank -1 <> if : compile lit _bank , compile >bank compile branch _bank cells _heres + @ dup , here to _nhere \ save "normal here" h ! \ set h to _bank's "here" _bank $3000 >SAMS \ map in the appropriate bank else : then ; : _bfree ( -- ) \ determine free memory in the bank... $4000 _bank cells _heres + @ - . ." bytes free." cr ; : ;b ( -- ) \ end banked compilation compile branch _nhere , here _bank cells _heres + ! \ update here for bank _bfree _nhere h ! \ restore h to "normal" memory compile bank> [compile] ; ; : : ( -- ) \ banked / non-banked compilation _bank -1 = if : else b: then ; : setBank ( bank -- ) \ sets the bank number that will receive colon definitions dup -1 _maxBank within if to _bank _bank -1 <> if cr ." Bank " _bank . ." is now active. " _bfree else cr ." Compiling to standard 32K memory." cr then else true abort" Illegal bank number specified" then ; : ; _bank -1 = if [compile] ; else ;b then ; immediate 7 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted March 5, 2015 Share Posted March 5, 2015 Nice. I will definitely have to do a run of these cards again. . .with RXB, Assembly, C, and Forth all supporting it now, it is getting ever-easier to program for it. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 5, 2015 Share Posted March 5, 2015 Wow! That's very impressive, Mark! I wish I could do something like that in fbForth 2.0; but, I'm afraid that, in my effort to preserve compatibility with TI Forth, I may have boxed myself in with the ALC support code, block buffers and the return stack all in low RAM. I'm also not entirely sure how I could maintain dictionaries with your scenario. Perhaps I could gain some insight with the answer to the following question: Does loading your TurboForth Floating Point Library into low memory work transparently with your SAMS Programming Library? I will certainly study your code at length when I get back home next week. I am sure the answer is there. Again, a very nice piece of work! ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 5, 2015 Share Posted March 5, 2015 Nice. I will definitely have to do a run of these cards again. . .with RXB, Assembly, C, and Forth all supporting it now, it is getting ever-easier to program for it. If I can manage to incorporate into fbForth 2.0 what Mark has just done with TurboForth, I will definitely be wanting one+ from you, Jim! ...lee Quote Link to comment Share on other sites More sharing options...
Gary from OPA Posted March 5, 2015 Share Posted March 5, 2015 Does this work on Classic99, I have not tried the it for expanded memory, but it how well is the emulation, since sadly my own AMS is in storage back in Canada, so I don't have one here to use on my real iron machine. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 5, 2015 Share Posted March 5, 2015 Does this work on Classic99, I have not tried the it for expanded memory, but it how well is the emulation, since sadly my own AMS is in storage back in Canada, so I don't have one here to use on my real iron machine. Yes. Classic99 has 1024kB SAMS support, all of which is supported by TurboForth. ...lee 1 Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 5, 2015 Author Share Posted March 5, 2015 Does this work on Classic99, I have not tried the it for expanded memory, but it how well is the emulation, since sadly my own AMS is in storage back in Canada, so I don't have one here to use on my real iron machine. Hi Gary. Yes, as Lee notes above, classic99 supports the SAMS 100% In fact, I developed it with classic99 1 Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 5, 2015 Author Share Posted March 5, 2015 Nice. I will definitely have to do a run of these cards again. . .with RXB, Assembly, C, and Forth all supporting it now, it is getting ever-easier to program for it. Yeah - a "programmers special edition" cart would be a fantastic idea. Don't do a run yet though. I need to do a new release of TurboForth as I have found a bug in the SAMS handling. It meant that while developing the SAMS library, I had to develop a replacement word for it in assembly language. Of course, TurboForth (and fbForth) have integral assemblers, so I was able to type in the machine code right there at the keyboard and run it :-) I'll have a new build of TurboForth released this evening. And when you do a run of Programming Edition carts I'll have three or four off you! Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 5, 2015 Author Share Posted March 5, 2015 (edited) Perhaps I could gain some insight with the answer to the following question: Does loading your TurboForth Floating Point Library into low memory work transparently with your SAMS Programming Library? I will certainly study your code at length when I get back home next week. I am sure the answer is there. Again, a very nice piece of work! ...lee Hiya Lee - Thanks for the kind words! To answer your question re the FP library: Yes and no. You could have both libraries loaded and FP will work fine. However you would have to ensure that words that access the FP are NOT executed from banked memory because the banking would page out some of the FP ALC! However, there is a work around that I can implement to get around that problem. I have a cunning plan! Stand by for a new edition of the SAMS library! That first version didn't last long did it? What have you done Mr. Stewart Regarding porting it to fbForth - hell yeah. Let rip! It's all good! I'm planning to do a write up of how it works for the website which will aid you in porting. It just uses a magic trick but like all magic tricks: a) it's not magic, and b) it's really simple! Edited March 5, 2015 by Willsy 1 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted March 5, 2015 Share Posted March 5, 2015 On the boards, I was speaking of doing a new run of SAMS boards--they look to be a potentially popular PEB card lately. . .although the thought of an Ubercart with all four of the SAMS programming tools on it would be interesting too. . . 1 Quote Link to comment Share on other sites More sharing options...
atrax27407 Posted March 5, 2015 Share Posted March 5, 2015 I'll be checking my inbox for the new build!!!! 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 5, 2015 Share Posted March 5, 2015 Regarding Classic99 and SAMS, here's a program that supports SAMS: a picture slideshow viewer. But the strange thing is that in Classic99 it only shows 2 picture files to choose from, while on my real TI with 128K SAMS it shows about 8-10 files. Is that a problem with the SAMS support or something else? AMS Slideshow (1997)(Bruce Harrison)(PD).dsk Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 5, 2015 Author Share Posted March 5, 2015 Regarding Classic99 and SAMS, here's a program that supports SAMS: a picture slideshow viewer. But the strange thing is that in Classic99 it only shows 2 picture files to choose from, while on my real TI with 128K SAMS it shows about 8-10 files. Is that a problem with the SAMS support or something else? Hmmm.... does Classic99 show any AMS activity in the debugger window? Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 5, 2015 Share Posted March 5, 2015 Hmmm.... does Classic99 show any AMS activity in the debugger window? It does show SAMS activity in the debugger. In MESS it shows all 10 files. Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 5, 2015 Author Share Posted March 5, 2015 Hmmm... I wonder if Classic99 is failing to catalog the disk properly, rather than it being a AMS problem. In my quite extensive use of the AMS emulation in Classic99 I've never uncovered any problems with it. Experiment: Try a .DSK image with the software and some pictures on it (assuming you aren't already). Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 5, 2015 Share Posted March 5, 2015 Classic99 can catalog the disk from TI Workshop. I guess this is a mystery for Tursi to solve. Quote Link to comment Share on other sites More sharing options...
atrax27407 Posted March 5, 2015 Share Posted March 5, 2015 It's blokes like you that make the rest of us feel redundant! Quote Link to comment Share on other sites More sharing options...
Tursi Posted March 6, 2015 Share Posted March 6, 2015 (edited) Weird one. I didn't write the AMS support but it's pretty simple, and seems to be working even here. After trying a few other folders, it's something in the file discrimination code. Even my pictures folder (which has hundreds of images) only gets about a dozen onscreen, but I haven't figured out what the difference is between files that show and files that don't. Source is on the disk, but it takes a while to make sense of someone else's assembly. I'll poke at it. But the AMS side seems to be working okay. Edit: confirmed. When I use the TI disk controller, all ten images on the disk show up. I'll figure out what I am reporting wrong. Edited March 6, 2015 by Tursi 2 Quote Link to comment Share on other sites More sharing options...
Tursi Posted March 6, 2015 Share Posted March 6, 2015 Found it... it was a misconception I had on the directory listings. Since the record type is FIXED, I assumed the filename would be padded to 10 characters like it is on the disk itself. Of course most programs still worked, because they either read the sectors themselves (in which case they dealt with the padding), or they passed it into the DSR which ignored the padding. But this tool was manipulating the filename (_P to _C, etc), and used the returned filename length to figure that out. Since I was always padding to 10 characters, it failed, unless of course the filename actually WAS 10 characters. It was wrong for both FIAD (where I was explicitly padding) and Images (where I was just taking it from the FDR). Thanks for calling it out, that fix will be in the next version. 3 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted March 6, 2015 Share Posted March 6, 2015 Insidious little bug there, Tursi, especially as you noted that it works almost all of the time with your original method. Edge cases are a killer, but at least it was easy to find once you knew it was there. Many thanks for all of the development you do on Classic99--it is really nice to have fully-supported emulators out there (and kudos to Michael too, for his similar level of dedication in MESS). Being able to validate new code in both of them pretty much assures operation on real iron. 3 Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 6, 2015 Author Share Posted March 6, 2015 Lee, Here's how it works: 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 7, 2015 Share Posted March 7, 2015 (edited) Lee, Here's how it works: banking.png Thanks! But, like I said earlier, I will look at it more closely when I get home in a couple of days. Just to remind you, fbForth's 4 block buffers occupy all of the lower 4kB of low RAM and the upper 4kB (actually, >3020 – >3FFF) contains fbForth's ISR as well as block I/O code, user variable table, all variables, the TIB*, the return stack and a lot of other low-level ALC system support, including ROM-bank-switching code. I think this would cause a lot of thrashing. ...lee *[EDIT: the TIB is not in low RAM—it’s at >FFA0.] Edited March 13, 2015 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
RobertLM78 Posted March 7, 2015 Share Posted March 7, 2015 Nice. I will definitely have to do a run of these cards again. . .with RXB, Assembly, C, and Forth all supporting it now, it is getting ever-easier to program for it. I definitely will scrounge up money for one!! 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.