Willsy Posted January 7, 2014 Share Posted January 7, 2014 (edited) Regarding case, I think you just need to add some preamble at the beginning to make it clear what it is, and what it is used for. Then, the descriptions for each word can be left as they are. Here is my attempt from my book on TurboForth:CASE and ENDCASE are Forth's version of switch() in C or Select Case in some versions of BASIC. It allows you to evaluate a list of choices, without resorting to long, potentially error-prone lists of IF...THEN phrases. Let's have a look at an example program that uses a CASE construct: : TEST KEY CASE 32 OF ." SPACE " ENDOF 42 OF ." STAR " ENDOF 13 OF ." ENTER " ENDOF ." UNKNOWN " ENDCASE ; : TEST-CASE BEGIN TEST BREAK? AGAIN ; The above program waits for you to press a key, and checks the actual key pressed against a list of key presses that we are interested in. Namely, the space key, the ENTER key, and the asterisk (shift . Any other key shall produce the message UNKNOWN and the program will then continue. Let's have a look at how it works: KEY pauses and waits for you to press a key. When a key is pressed, the key's ASCII code is pushed to the stack. We then begin 'case by case processing'. CASE compares the value on the stack (removing it as it does so) against each case in the case list. If a matching case is found, the associated code is executed. Note that the code to be executed for a case should be enclosed within the words OF and ENDOF. It is important to realise that, in the event of a matching case, your code between OF and ENDOF is executed, and then case by case processing ends, and the program continues executing at the word immediately following ENDCASE. As you can see, the code is very clear, and quite easy to follow. Let's have a look at an equivalent written using IF...THEN: : TEST KEY DUP 32 = IF .” SPACE” ELSE DUP 42 = IF .” STAR” ELSE DUP 13 = IF .” ENTER” ELSE .” UNKNOWN” THEN THEN THEN DROP ; Ouch. All that 'noise' with DUPing values on the stack (because IF consumes the value on the stack, you have to DUP it for the next IF test). You also have to DROP the test value at the end. Noisy, and not very nice. Note also the phrase THEN THEN THEN – as we have already learned, each IF requires a matching THEN. Since the code above uses nested IF...THEN constructs, we need to close them down at the end: IF something IF something else IF something else THEN THEN THEN Nasty isn't it? Clearly, CASE processing offers much better advantages in terms of code clarity, and ease of editing later on the down the line. Whenever you want to test a value against a list of cases, CASE is your friend. Edited January 7, 2014 by Willsy 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 7, 2014 Author Share Posted January 7, 2014 (edited) I think your post was posted 6 time! LMAO! I presume something went wrong at the Atariage end - no big deal, but made me laugh! ... Yeah, it was frustrating! I gave up last night. Sorry about that! [ EDIT: They've mercifully been removed ] ... This code presumes that the stack was empty before calling the word (apart from the arguments that the word itself needs, of course). ... Uh-oh! Nice catch—thanks! I'll re-post in a bit. ...lee Edited January 14, 2014 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 7, 2014 Author Share Posted January 7, 2014 Here is the revised example— The following example could have been written more efficiently; but, this version makes use of all of the above words. The word 8X8SRCH defined below looks on the stack for the address of an 8x8 array addr of numbers to search and a number n to match. The result will be only a false flag if there is no match, but a true flag, row r and column c of the array if there is a match. You will notice that the stack depth is stored on the return stack before entering the outer DO loop and moved to the parameter stack when that loop is exited to then calculate the difference. The reason for this maneuver is that there is no way for 8X8SRCH to anticipate how many cells there may be on the stack below n before 8X8SRCH executes.: : 8X8SRCH «Search an 8x8, row-major array for a number ( n addr --- F | c r T ) «In: n = number to match; addr = array address; Out: false (0), if not found—or c = column; r = row; true (non-zero), if found DEPTH >R «Store stack depth to return stack to check at end 8 0 DO «Array row loop 8 0 DO «Array column loop OVER OVER «Copy n and addr to top of stack J 8 * I + «Convert row and column to address offset into array + @ «Add offset to addr and get value at that location = IF «Do we have a match to n? DROP DROP «Yes; DROP top 2 numbers from the stack I J 1 LEAVE «Leave column c, row r and 1 for outer loop test; leave inner loop when we next get to LOOP ELSE «No match 0 «Leave 0 for outer loop test THEN LOOP «Inner loop end IF «Did we have a match? 1 «Yes; leave true (1) [stack now: c r 1] LEAVE «Leave outer loop at LOOP THEN LOOP «Outer loop end DEPTH R> - «Get current stack depth, previous depth & difference 2 = IF «# cells on stack out of loops = 2? DROP DROP 0 «Yes; loop exhausted with no match; DROP everything and leave only false (0) THEN ; Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 11, 2014 Author Share Posted January 11, 2014 Contriving these examples is getting the best of me, mostly because I'm getting bored with them. I promise I'll finish them today or tomorrow and post them for comments for a short while before I declare the fbForth 1.0 Manual a fait accompli! ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 14, 2014 Author Share Posted January 14, 2014 One more example and I'll post the lot in PDF—probably within the hour. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 14, 2014 Author Share Posted January 14, 2014 Here 'tis— ControlStructures.pdf The relevant section is §2.5 "Control Structures". Have a look and give me your feedback if you're so inclined. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 15, 2014 Author Share Posted January 15, 2014 No feedback yet, so I think I will post the fbForth 1.0 Manual later tonight or in the morning. Before I post, however, I will add hyperlinks to the TOC page numbers and cross-references. The TOC hyperlinks are easy; but, I may miss some of the cross-references if I can't find an easy way to search for them in OOO Writer. Anybody have any idea how? ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 16, 2014 Author Share Posted January 16, 2014 Never mind—I guess I wasn't paying attention before when I exported to PDF from OOO Writer—the hyperlinks for cross-references are part of the export! I'll have the manual ready in a few hours. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 16, 2014 Author Share Posted January 16, 2014 (edited) At long last—TADA!! : fbForth 1.0: A File-Based Implementation of TI Forth fbForth_Manual.pdf <---[EDIT] See replacement PDF file (minor corrections) in this post. ...lee Edited January 21, 2014 by Lee Stewart 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 17, 2014 Author Share Posted January 17, 2014 (edited) A few minor corrections and a minor renaming of the file: fbForth_1.0_Manual.pdf <---[EDIT] See replacement PDF file (minor corrections) in this post. I had an error in the PAD RAM memory map at address 83FAh, a page-number-reference problem in the TOC-page-number hyperlinks and an "Editor's note:" reference somewhere in the Glossary that should have been removed. ...lee Edited January 21, 2014 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
Willsy Posted January 17, 2014 Share Posted January 17, 2014 FWIW: I Have read the document and I think it's brilliant. No comments from me so far. Will let you know if I see anything! Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 18, 2014 Author Share Posted January 18, 2014 FWIW: I Have read the document and I think it's brilliant. No comments from me so far. Will let you know if I see anything! You're too kind. Thank you. It's worth a lot. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 21, 2014 Author Share Posted January 21, 2014 (edited) In the interest of getting it right, I fixed another pagination problem with the manual. I discovered it when I was printing the manual and 3-hole-punching it. You will notice that there is no page 181. I believe the problem lay with OOO Writer and my attempt at inserting a different page style in the middle of the document. The section beginning at page 182 seems to have been forced to start on a left-facing, i.e., even-numbered page; so, I had to make the page before it end on an odd-numbered page!?! This will be a problem in the future if I ever add to the manual. Anyway, the corrected manual is attached. fbForth_1.0_Manual_a.pdf <---[EDIT] See replacement PDF file (minor corrections) in this post. ...lee Edited January 21, 2014 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
Willsy Posted January 21, 2014 Share Posted January 21, 2014 Oh, I feel your pain. That is a constant pain the ass in OOO writer. IIRC, when you are actually writing text and it spills across to the next page, it will correctly create a new page with the correct odd/even page style (you're using page styles, right?) but if you go further up and insert something, you can sometimes find that the stuff after it has the wrong page styles - i.e. odd numbered pages with an even style, and vice-versa. What I did to make it visually obvious was place the page number at the hard left on even pages, and the hard right on odd pages (in the footer). Then, if things go awry, you can actually see it. It's then very simple to back to the first page where the problem occurs and apply the correct page style, and the others should automatically correct themselves (if you've set the "next page style" option in your page style setup). Bit arcane, really, isn't it? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 21, 2014 Author Share Posted January 21, 2014 And—once more with feeling! fbForth_Manual_20140121.pdf ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 31, 2014 Author Share Posted January 31, 2014 I could not find anywhere that I had uploaded the last upadte to FBLOCKS that includes the mods for JOYST and the additions of JMODE , JKBD and JCRU , so here it is. I will package it up with the rest of fbForth later. FBLOCKS22DEC2013.zip ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted February 26, 2014 Author Share Posted February 26, 2014 (edited) I haven't done very much with fbForth lately—except some keyboard scanning stuff in PMs with @Willsy. I am now beginning to work out how I will put fbForth into cartridge space. So far my plan involves the following: Put all high-level Forth code in the same ROM bank. (Involving more than one bank is fraught with too much bank switching as far as I can tell.) Put all variables into low RAM space after the Forth block buffers. Resident vocabulary words ( FORTH , ASSEMBLER ) will need to be modified per TI Forth's FORTH to use variables for the link fields and the pseudo-name field. I may put all, or as much as possible, of FBLOCKS into ROM. Make some or all optional by devising a modifiable link system in RAM space. Manage the editors by a modifiable link as suggested above. Convert as much of ROM-based FBLOCKS as possible to ALC to allow dictionary space to reside exclusively in one block. Any comments or implementation ideas are welcome. ...lee Edited February 27, 2014 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
Asmusr Posted February 27, 2014 Share Posted February 27, 2014 This made me thinking, when converting disk based software to cartridge based software it would be nice to have a generic framework for a virtual file system in ROM where you access files by file names instead of by bank number/offset/length. If only you could put a DSR in a cartridge ROM... Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted February 27, 2014 Author Share Posted February 27, 2014 This made me thinking, when converting disk based software to cartridge based software it would be nice to have a generic framework for a virtual file system in ROM where you access files by file names instead of by bank number/offset/length. If only you could put a DSR in a cartridge ROM... There must be many ways to skin that cat. One way might be to write your own DSRLNK that includes a way to branch to your ROM DSR that does not involve the CRU. It could be either the first option before searching peripheral ROMs or the last option after their failure. You would need unique device names that wouldn't be found by other DSRs. That might be fun to work on—like I need a digression right now! ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted February 28, 2014 Author Share Posted February 28, 2014 Re my fbForth-to-cartridge plan, the use of more than one non-high-level Forth bank may complicate bank switching. I am thinking it may be useful to implement a bank-switching stack to make that easier. I suppose that will all depend on whether I allow code in one bank to be called by more than one other bank. Thoughts? ...lee Quote Link to comment Share on other sites More sharing options...
Willsy Posted February 28, 2014 Share Posted February 28, 2014 (edited) One of the biggest issues with high level code in multiple banks is how do you tick it? In forth when we tick a word we get a single datum: the word's compilation address (or in some dialects the PFA). However, with forth code in more than one bank, you need two datums: the compilation address and bank, since they're in the same address range. Now you also need a new non-standard word to comma those to memory when compiling calls etc. Also consider that you're building a colon Def in ram: : A b c ; A is in the 32k Ram somewhere, b is in bank 0 and c is in bank 1. C needs to add code to the definition to effect the bank switch, as well as leave data somewhere to indicate which bank to return to. Presumably the return stack. How do we add that code? One can either build extra complexity into the compiler, or make every word in the dictionary (in ROM) immediate so that it compiles itself on its own behalf. None of this makes for a very standard forth. The complexity rapidly snowballs. Forth just wasn't made for a bank switching type of environment! Edited February 28, 2014 by Willsy Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted February 28, 2014 Author Share Posted February 28, 2014 (edited) One of the biggest issues with high level code in multiple banks is how do you tick it? ... I am well aware of that complexity; but, that was not my question. I plan, indeed, to keep all of the linked Forth word list in ROM in one bank. My question had to do with all of the ALC (non-high-level Forth code—awkwardly stated—sorry | ) in more than one other bank that I may want to access from more than ROM-based Forth words—particularly, from other ROM banks. I should probably try to avoid that scenario. It should not be too difficult. ...lee Edited February 28, 2014 by Lee Stewart Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 1, 2014 Share Posted March 1, 2014 Okay sorry for the confusion. Well your suggestion about some sort of stack sounds like a good idea to me. My first thought was that you would save the address to return to to the "bank stack" among with the bank - two cells per entry. However it occurs to me that the least significant bit of the address would never be used, so that represent banks 0 and 1, and, since cart addresses are from 0 to $7fff the most sig. bit is free too. There's another two banks. In practice I'd probably shift the address to branch to left by one bit and use the two least sig. bits for the bank. However, I'm running away with things I fear, as I'm prone to do. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 1, 2014 Author Share Posted March 1, 2014 Okay sorry for the confusion. Well your suggestion about some sort of stack sounds like a good idea to me. My first thought was that you would save the address to return to to the "bank stack" among with the bank - two cells per entry. However it occurs to me that the least significant bit of the address would never be used, so that represent banks 0 and 1, and, since cart addresses are from 0 to $7fff the most sig. bit is free too. There's another two banks. In practice I'd probably shift the address to branch to left by one bit and use the two least sig. bits for the bank. However, I'm running away with things I fear, as I'm prone to do. No, not at all! Those are exactly the kinds of ideas I'm talking about. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 2, 2014 Author Share Posted March 2, 2014 I can tell this conversion of fbForth to cartridge is going to be a long, arduous process. I guess the best thing to do at the outset is to do only the minimum conversion to get the system into cartridge space—then, try to improve the system by hoisting more of FBLOCKS into the fbForth kernel. For the minimum conversion, I will still likely need to do more than the bare minimum because the kernel presently occupies 200 bytes more than 8 KB! I suppose I could stash a small amount of the end of the resident dictionary at A000h to minimize my initial effort for a version 2.0 and then start working on 3.0 (or maybe 2.1?) as soon as 2.0 is operational. I'm rambling; but, you get the idea. ...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.