+dhe Posted May 25 Share Posted May 25 @Lee Stewart What I know about Forth, can fit in a sewing thimble. Back in the 80's, the TI Hoosier's User Group, had this really good programmer, named Greg Goodwin. He wrote a program call Kibbit. I can start fbForth on Classic99, is can I just copy this program in to fbForth in Classic99 and expect it to run? 84:07:04. Kibbit instructions by Greg Goodwin Kibbit is a TI Forth graphics program which draws from the keyboard or joysticks. Please note: This is a revised version of the Kibbit program which is saved on the Forth demo disk in the HUGger library. The key functions of Kibbit are: CR - Clears the current work screen. SPACEBAR Aborts program. Fire Button (or 0) Toggles graphics modes. A sprite will appear on the tip of the line. The letter is the current mode. D Draw U Undraw T Dtog (if line undrawn else draw one.) Either joystick or keys may be used in drawing (make sure the ALPHA LOCK is up!). If you have any problems getting this version to run, leave me a message on the HUGbbs or through the users group PO Box (also let me know what you think of it). A future version will include the saving of screens, and mixing with user programs. Forth … write … Greg. Kibbit revised listing ( Kibbit by G. Goodwin) 50 VARIABLE JOY 50 VARIABLE JRT 0 VARIABLE SELECT HEX 3800 SSDT : INIT_TURTLE 8050 2828 2828 1000 8A SPCHAR 8040 2424 2424 1800 8B SPCHAR 8040 201C 0808 0800 8C SPCHAR 22 22 5 8C 1 SPRITE ; DECIMAL : KIBBIT INIT_TURTLE GRAPHICS2 BEGIN 1 JOYST CASE 04 OF -1 JOY +! ENDOF 252 OF 1 JOY +! END OF ENDCASE CASE 04 OF 1 JRT +! ENDOF 252 0F -1 JRT +! ENDOF ENDCASE 18 = IF 1 SELECT +1 ENDIF SELECT @ CASE 0 OF DRAW 138 1 SPRPAT ENDOF 1 OF UNDRAW 139 1 SPRPAT ENDOF 2 OF DTOG 140 1 SPRPAT ENDOF 3 OF 0 SELECT ' ENDOF ENDCASE JRT @ JOY @ 1 SPRPUT JRT @ JOY @ DOT ?KEY 13 = IF GRAPHICS 2 ENDIF ? KEY 32 = UNTIL TEXT ; KIBBIT ;S 3 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 25 Share Posted May 25 (edited) Here is the code expanded for easier reading with corrections and some explanation: 50 VARIABLE JOY \ joystick y position 50 VARIABLE JRT \ joystick x position 0 VARIABLE SELECT \ selection HEX \ Set Sprite Descriptor Table to 3800h in VRAM <--CANNOT do in text modes! \ 3800 SSDT <--already done by GRAPHICS2 in fbForth : INIT_TURTLE \ set bitmap mode before sprites GRAPHICS2 \ clears SDT \ initialize turtle sprite chars 8050 2828 2828 1000 8A SPCHAR 8040 2424 2424 1800 8B SPCHAR 8040 201C 0808 0800 8C SPCHAR \ initialize turtle sprite 22 22 5 8C 1 SPRITE ; DECIMAL : KIBBIT INIT_TURTLE BEGIN 1 JOYST CASE \ y value 04 OF -1 JOY +! ENDOF 252 OF 1 JOY +! ENDOF ENDCASE CASE \ x value 04 OF 1 JRT +! ENDOF 252 OF -1 JRT +! ENDOF ENDCASE 18 = IF \ fire button? 1 SELECT +! \ increment selection ENDIF SELECT @ CASE 0 OF DRAW 138 1 SPRPAT ENDOF 1 OF UNDRAW 139 1 SPRPAT ENDOF 2 OF DTOG 140 1 SPRPAT ENDOF 3 OF 0 SELECT ! ENDOF ENDCASE JRT @ JOY @ 1 SPRPUT \ move turtle to current position JRT @ JOY @ DOT \ draw/undraw/toggle a dot at current position ?KEY 13 = IF \ CR? INIT_TURTLE \ set bitmap mode/re-initialize turtle to clear screen ENDIF ?KEY 32 = \ <space>? UNTIL TEXT ; \ back to text mode KIBBIT \ start program ;S \ stop scanning block You can almost drop the original into fbForth—very little change—mostly correction of typos or missed OCR. The above, corrected code can be dropped right in. You do not need the ;S . That was used to tell the interpreter to stop scanning the block for more code—saves time when loading from floppy. ...lee Edited May 25 by Lee Stewart clarification 5 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 26 Share Posted May 26 3 hours ago, dhe said: What I know about Forth, can fit in a sewing thimble. Well you know @dhe , Forth is like smoking. It's never too late to start! Also it's pretty cool that with FbForth you have a much better TI-Forth that just works. (Of course now I have to see how and if I can do that clever little program with my system. LOL) 4 Quote Link to comment Share on other sites More sharing options...
+dhe Posted May 26 Author Share Posted May 26 Thanks @Lee Stewart, I've only ever seen screens like the original KIBBIT listing. Your formatted, and of course corrected and commented version is much more approachable. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 26 Share Posted May 26 4 hours ago, dhe said: Thanks @Lee Stewart, I've only ever seen screens like the original KIBBIT listing. Your formatted, and of course corrected and commented version is much more approachable. Don’t forget the W,R,Z,C keys for the diagonal directions. ...lee 1 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 27 Share Posted May 27 For a better DRAW turtle (D), I would change the first sprite character, 8Ah (138) to 8040 3824 2424 3800 8A SPCHAR ...lee Quote Link to comment Share on other sites More sharing options...
GDMike Posted May 27 Share Posted May 27 The pencil in the sketchmate 99 handles drawing better than the joystick can do in my opinion, but you might want to look at the way they setup the menu in SM and incorporate it.. Quote Link to comment Share on other sites More sharing options...
+dhe Posted May 27 Author Share Posted May 27 Hi Lee, I'm about a quarter of the way through the fbforth v2 manual. Would you mind walking me through, a simple program that would: Set the display to graphics mode Get my name Print - Hello, $Name and launch a balloon sprite from the bottom of the screen like it's floating up? 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 27 Share Posted May 27 53 minutes ago, dhe said: Hi Lee, I'm about a quarter of the way through the fbforth v2 manual. Would you mind walking me through, a simple program that would: Set the display to graphics mode Get my name Print - Hello, $Name and launch a balloon sprite from the bottom of the screen like it's floating up? I am not an expert on FbForth, but I used TI Forth for a long time so I can get you started until Lee gets online. Video modes in the system are controlled so simply. Just use their name: TEXT 40 column GRAPHICS 32 column a la BASIC GRAPHCS2 bit map mode SPLIT which gives you bit map on the top 2/3 of the screen and a windows of GRAPHICS mode on the bottom. (cool) "Get my name" This is not as simple as BASIC, and from my review of the FbForth doc, it is not obvious to me the best way to do this in FbForth, so I am going to wait for Lee. To make a sprite at the bottom of the screen go into GRAPHICS mode GRAPHICS And then define the sprite and it's motion vector ( dotcol dotrow color char spr# ) 127 180 7 42 1 SPRITE ( x y spr# ) 0 -3 1 MOTION Then we need to tell the system how many sprites will automatically move. Since sprites numbers are 0 ..31 and we want sprite 1 to move, we need to say we want 2 sprites to have automotion. ( 0 and 1 ) 2 #MOTION And off it goes... Notice we can play with sprites interactively to see how they will work Try 0 -10 1 MOTION 3 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 27 Share Posted May 27 In terms of Forth programming style, if we were doing a project we would not use literal numbers for parameters where names would be better. So you might want to make your sprites have familiar names. 0 CONSTANT #0 1 CONSTANT #1 2 CONSTANT #2 And colors are easier to remember by name. Here is a little trick invented by the late Neil Baud. Put this code in a BLOCK with the FbForth Editor and you can LOAD it anytime you need it. \ do it yourself enumeration : ENUM ( 0 <text> -- n) DUP CONSTANT 1+ ; 0 ENUM TRANS ENUM BLACK ENUM MEDGRN ENUM LTGRN ENUM DKBLU ENUM LTBLU ENUM DKRED ENUM CYAN ENUM MEDRED ENUM LTRED ENUM DKYEL ENUM LTYEL ENUM DKGRN ENUM MAGENTA ENUM GRAY ENUM WHITE DROP And if you defined ENUM then of course you could use it for those sequential sprite numbers too. That's all for now. 3 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 27 Share Posted May 27 3 hours ago, dhe said: Hi Lee, I'm about a quarter of the way through the fbforth v2 manual. Would you mind walking me through, a simple program that would: 1. Set the display to graphics mode 2. Get my name 3. Print - Hello, $Name 4. Launch a balloon sprite from the bottom of the screen like it's floating up? Certainly! 5 hours ago, dhe said: 1. Setting to graphics mode The GRAPHICS word sets graphics mode, clears the screen, and moves system tables if necessary. It can be part of another word, but should usually be ahead of anything you want persisted on the screen. 5 hours ago, dhe said: 2. Get my name Many ways to do this. Here is one: \ Variable MYNAME with 20 as the character count at the beginning. \ Total of 24 bytes allowed, with the leading word and the 22 ALLOTed bytes. HEX 1400 DECIMAL VARIABLE MYNAME 22 ALLOT : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..get up to 20 chars ; The trouble with this is that EXPECT adds 2 nulls after the input and, if you do not correct the character count at the beginning of MYNAME , doing the following to type the name will print 20 chars including the 2 nulls (ASCII 0) and whatever follows them, which is likely not what you want: MYNAME COUNT TYPE We could add code to GETNAME to count the actual number of chars typed and store that at the beginning of MYNAME to get the correct length: HEX 1400 DECIMAL VARIABLE MYNAME 22 ALLOT : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..up to 20 chars MYNAME \ start of MYNAME BEGIN \ count actual chars 1+ \ increment address DUP \ keep a copy for next go round C@ 0= \ get char..is it 0? UNTIL MYNAME - \ subtract the 2 addresses to get char count + 1 1- \ correct to actual char count MYNAME C! \ store char count at start of MYNAME ; There are certainly other ways to do this. Perhaps you can suggest some. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 27 Share Posted May 27 (edited) Here is another GETNAME identical with the last one but a bit more concise by using COUNT to retrieve the next byte and increment to string address: : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..up to 20 chars MYNAME 1+ \ start of MYNAME string after length byte BEGIN \ count actual chars COUNT \ get next byte..increment address..addr byte to stack 0= \ retrieved char = 0? UNTIL MYNAME - \ subtract the 2 addresses to get char count + 2 2- \ correct to actual char count MYNAME C! \ store char count at start of MYNAME ; ...lee Edited May 27 by Lee Stewart comment correction 2 Quote Link to comment Share on other sites More sharing options...
+dhe Posted May 27 Author Share Posted May 27 @Lee Stewart posted the following to me: Q: How do I set graphics mode? A: The GRAPHICS word sets graphics mode, clears the screen, and moves system tables if necessary. It can be part of another word, but should usually be ahead of anything you want persisted on the screen. Q: How do I get my name? A: Many ways to do this. Here is one: \ Variable MYNAME with 20 as the character count at the beginning. \ Total of 24 bytes allowed, with the leading word and the 22 ALLOTed bytes. HEX 1400 DECIMAL VARIABLE MYNAME 22 ALLOT : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..get up to 20 chars ; The trouble with this is that EXPECT adds 2 nulls after the input and, if you do not correct the character count at the beginning of MYNAME , doing the following to type the name will print 20 chars including the 2 nulls (ASCII 0) and whatever follows them, which is likely not what you want: MYNAME COUNT TYPE We could add code to GETNAME to count the actual number of chars typed and store that at the beginning of MYNAME to get the correct length: HEX 1400 DECIMAL VARIABLE MYNAME 22 ALLOT : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..up to 20 chars MYNAME \ start of MYNAME BEGIN \ count actual chars 1+ \ increment address DUP \ keep a copy for next go round C@ 0= \ get char..is it 0? UNTIL MYNAME - \ subtract the 2 addresses to get char count + 1 1- \ correct to actual char count MYNAME C! \ store char count at start of MYNAME ; Q: How do I print Hello, $NAME A: : HELLO ." Hello, " \ print greeting MYNAME \ address of MYNAME COUNT \ get char count and address after it TYPE \ type MYNAME string as part of greeting ; Here is another GETNAME identical with the last one but a bit more concise by using COUNT to retrieve the next byte and increment to string address: : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..up to 20 chars MYNAME 1+ \ start of MYNAME string after length byte BEGIN \ count actual chars COUNT \ get next byte..increment address..addr byte to stack 0= \ retrieved char = 0? UNTIL MYNAME - \ subtract the 2 addresses to get char count + 1 2- \ correct to actual char count MYNAME C! \ store char count at start of MYNAME ; Thanks a million Lee, I'm still working through these for comprehension! {It might be a while} 2 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 27 Share Posted May 27 4 hours ago, dhe said: 4. Launch a balloon sprite from the bottom of the screen like it's floating up? HEX \ Array of 4 character definitions for magnified balloon DATA[ 0F1F 3F7F 7F7F 7F3F 1F0F 0702 0202 0101 F8FC FEFF FFFF FFFE FCF8 F0A0 A0A0 C0C0 ]DATA \ leaves address and cell count on stack 80 SPDCHAR \ assign above char defs to sprite chars 80h..83h (128..131) 2 MAGNIFY \ magnification = 2 0A 0B0 6 80 0 SPRITE \ sprite 0: char 128/dark red/dotrow=176/dotcol=10 3 -6 0 MOTION \ sprite 0 motion 1 #MOTION \ set sprites < 1 in motion Try it with 3 MAGNIFY \ magnification = 3 There is a lot more you can do with this, so think about exactly what it is you want to happen and we can work through it. ...lee 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 27 Share Posted May 27 (edited) When I see someone interested in learning Forth I have an overwhelming urge to help them get through stuff that took me too much time. So here goes... I would make one suggestion about a "rule of thumb" as we say in English, for Forth. The rule is "Don't hide your tools". It means extract good pieces of code into a word so you can reuse it for other parts of the program. Lee made a very clever piece of code that finds the end of a zero delimited string. So let's extract it and make it a word. : $END ( addr1 -- addr1 addr2 ) DUP BEGIN COUNT 0= UNTIL ; When we have a start address and an end address on that data stack we can find the length very easily OVER - We can put these ideas together to make something like a BASIC input statement, but it only works with strings. : $INPUT ( addr1 len -- ) \ automate the adjustment to hold a length byte OVER 1+ SWAP ( -- addr1 addr' len ) EXPECT $END ( -- addr1 addr2 ) OVER - ( -- addr length) \ compute the length 2- \ correct the count SWAP C! \ store length in the first byte of the address ; And in case you don't need to reserve permanent space for a specific string let me introduce PAD. PAD is typically located some distance past the end of the dictionary, in un allocated memory. It's free to use but know that it could be overwritten by compiling new code or even another word in the system. Caveat emptor. I would add another word as well if you plan to use "byte-counted" strings which is common in forth. "dot" prints a number so here .$ print a byte counted string. : .$ COUNT TYPE ; ( this is a normal practice in forth to make a small sub-routine. So with PAD and $INPUT and .$ Lee's example becomes: : GETNAME CR ." What's your name? " PAD 32 $INPUT CR ." Hello " PAD .$ ; Edited May 28 by TheBF Wrong comment 3 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 28 Share Posted May 28 4 hours ago, TheBF said: : .$ COUNT TYPE ; ( this is a normal practice in forth to make a small sub-routine. Careful here. In fbForth and TurboForth, an almost identical word ( $. ) types the number on the top of the stack as an unsigned, hexadecimal number. ...lee 1 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 28 Share Posted May 28 1 minute ago, Lee Stewart said: Careful here. In fbForth and TurboForth, an almost identical word ( $. ) types the number on the top of the stack as an unsigned, hexadecimal number. ...lee Good point. Well we could always call it $PRINT. I find I get tired typing COUNT TYPE endlessly. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted May 28 Share Posted May 28 (edited) OK...Here, in the spoiler below, are all the above (1)..(4) requested HOW-TOs together with some helper words and a final program word to run: Spoiler DECIMAL \ Variable MYNAME with room at the beginning for a length byte. Total \ of 24 bytes allowed, with the leading word and the 22 ALLOTed bytes. 0 VARIABLE MYNAME 22 ALLOT : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..up to 20 chars MYNAME 1+ \ start of MYNAME string after length byte BEGIN \ count actual chars COUNT \ get next byte..increment address..addr & byte to stack 0= \ retrieved char = 0? UNTIL MYNAME - \ subtract the 2 addresses to get char count + 2 2- \ correct to actual char count MYNAME C! \ store char count at start of MYNAME ; : HELLO ." Hello, " \ print greeting MYNAME \ address of MYNAME COUNT \ get char count and address after it TYPE \ type MYNAME string as part of greeting ." !" \ end greeting with '!' CR \ cursor to next line ; HEX : SPRITE0 \ Array of 4 character definitions for magnified balloon DATA[ 0F1F 3F7F 7F7F 7F3F 1F0F 0702 0202 0101 F8FC FEFF FFFF FFFE FCF8 F0A0 A0A0 C0C0 ]DATA \ leaves address and count on stack 80 SPDCHAR \ assign above char defs to sprite chars 80h..83h (128..131) 2 MAGNIFY \ magnification = 2 0A 0B0 6 80 0 SPRITE \ sprite 0: char 128/dark red/dotrow=176/dotcol=10 3 -6 0 MOTION \ sprite 0 motion ; DECIMAL : ANYKEY KEY DROP \ wait for a key and drop it ; : STARTPROMPT CR CR ." ...any key to start " ANYKEY ; : STOPPROMPT CR CR CR ." ...any key to stop " ANYKEY ; \ Main program : DOSTUFF VDPMDE @ \ get current screen mode for restoration at end GRAPHICS \ set graphics mode, clearing screen and homing cursor SPRITE0 \ set up sprite 0 and display it CR CR \ skip 2 lines GETNAME \ get user's name STARTPROMPT PAGE \ clear screen and home cursor HELLO \ greet user 1 #MOTION \ set sprite 0 in motion STOPPROMPT VMODE \ restore screen mode ; CR CR ." ...type DOSTUFF <enter> to run" Of course, there are other ways to do all of this. You should have no trouble incorporating @TheBF’s solutions into the above, as well. ...lee Edited May 28 by Lee Stewart clarified first lines of code 2 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted May 28 Share Posted May 28 I remember struggling to figure out how to get keyboard input in TI Forth when I coded Core Wars. I no longer recall how I did it, but it did strike me at the time that Forth did not have such a fundamental function built-in... Any particular reason for this? Not exactly a user friendly omission I might add... https://youtu.be/ZFANT61hEF0?si=1seXzWQpz9zOR7PR 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 28 Share Posted May 28 2 hours ago, Vorticon said: I remember struggling to figure out how to get keyboard input in TI Forth when I coded Core Wars. I no longer recall how I did it, but it did strike me at the time that Forth did not have such a fundamental function built-in... Any particular reason for this? Not exactly a user friendly omission I might add... The guy who invented Forth, Chuck Moore, decided that he could never predict what he needed for any given project so he made himself a toolkit with which to build whatever he wanted. His credo is best described as radical minimalism. This is a guy who ported his multitasking Forth system to the IBM 360, before the 360 had an Operating system, in a couple of days. At the end of the week he had the machine doing things the IBM engineers didn't know it could do. So a different kind of mind. To your point FigForth is a bit obtuse in this area. There are inconsistencies in it that have been eliminated in modern Forth. Like EXPECT creating a zero delimited string. Those are 'C' style strings and Forth typically uses Pascal style byte-counted strings everywhere else. huh? ANS Forth removed EXPECT and gave us ACCEPT ( addr len -- len) which is still at the "tool" level but at least with an extra DUP, it returns the address and length of the string you typed. So the short answer to your question is because Forth is not a language but a toolkit to build the language that you need for your current project. That's hard for people used to "languages" to get their head around. By example I replicated TI BASIC's "INPUT" functionality for myself and true to Chuck's philosophy, one word does one thing. These words don't take input from files. That would make them needlessly complicated if I only need input from the keyboard. Chuck is fond of saying he doesn't write general solutions because nobody has every told him what the "general problem" is. Here are my TI BASIC style input word for strings using ACCEPT DECIMAL : $ACCEPT ( $addr -- ) CR ." ? " DUP 1+ 80 ACCEPT SWAP C! ; : $INPUT ( $addr -- ) BEEP $ACCEPT ; \ BEEP like TI-BASIC And here is one for numbers that does the HONK and loops until you satisfy it : #INPUT ( variable -- ) \ made to look/work like TI-BASIC BEEP BEGIN PAD $ACCEPT \ $ACCEPT text into temp buffer PAD PAD COUNT NUMBER? \ convert the number in PAD WHILE \ while the conversion is bad we do this CR HONK ." input error " CR DROP REPEAT SWAP ! ; \ store the number in the variable on the stack) Now the truth... I don't think I have ever used them in a program as is. I build something better for the requirement at hand with the toolkit. As my Anglican friends would say: "Thus endeth the lesson" 2 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 28 Share Posted May 28 10 hours ago, Lee Stewart said: OK...Here, in the spoiler below, are all the above (1)..(4) requested HOW-TOs together with some helper words and a final program word to run: Hide contents DECIMAL \ Variable MYNAME with room at the beginning for a length byte. Total \ of 24 bytes allowed, with the leading word and the 22 ALLOTed bytes. 0 VARIABLE MYNAME 22 ALLOT : GETNAME ." Your name? " \ prompt for name MYNAME 1+ 20 EXPECT \ start 1 byte after start of MYNAME..up to 20 chars MYNAME 1+ \ start of MYNAME string after length byte BEGIN \ count actual chars COUNT \ get next byte..increment address..addr & byte to stack 0= \ retrieved char = 0? UNTIL MYNAME - \ subtract the 2 addresses to get char count + 2 2- \ correct to actual char count MYNAME C! \ store char count at start of MYNAME ; : HELLO ." Hello, " \ print greeting MYNAME \ address of MYNAME COUNT \ get char count and address after it TYPE \ type MYNAME string as part of greeting ." !" \ end greeting with '!' CR \ cursor to next line ; HEX : SPRITE0 \ Array of 4 character definitions for magnified balloon DATA[ 0F1F 3F7F 7F7F 7F3F 1F0F 0702 0202 0101 F8FC FEFF FFFF FFFE FCF8 F0A0 A0A0 C0C0 ]DATA \ leaves address and count on stack 80 SPDCHAR \ assign above char defs to sprite chars 80h..83h (128..131) 2 MAGNIFY \ magnification = 2 0A 0B0 6 80 0 SPRITE \ sprite 0: char 128/dark red/dotrow=176/dotcol=10 3 -6 0 MOTION \ sprite 0 motion ; DECIMAL : ANYKEY KEY DROP \ wait for a key and drop it ; : STARTPROMPT CR CR ." ...any key to start " ANYKEY ; : STOPPROMPT CR CR CR ." ...any key to stop " ANYKEY ; \ Main program : DOSTUFF VDPMDE @ \ get current screen mode for restoration at end GRAPHICS \ set graphics mode, clearing screen and homing cursor SPRITE0 \ set up sprite 0 and display it CR CR \ skip 2 lines GETNAME \ get user's name STARTPROMPT PAGE \ clear screen and home cursor HELLO \ greet user 1 #MOTION \ set sprite 0 in motion STOPPROMPT VMODE \ restore screen mode ; CR CR ." ...type DOSTUFF <enter> to run" Of course, there are other ways to do all of this. You should have no trouble incorporating @TheBF’s solutions into the above, as well. ...lee I love ANYKEY. Reminds me of the help desk story about the lady who called in and said : "The computer is saying press any key to continue, but I can't find the 'any" key on the keyboard" 😂 1 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 31 Share Posted May 31 OK this took me a hell of a lot longer to port to Camel99 Forth. I had never dealt with sprites in my experiments with bit mapped mode. So I had to work on the GRAPHICS2 library, then I had to write a new sprite library to handle GRAPHICS2 mode but it was a good exercise for me. I was totally shamed by how simple it was to drop the TI-Forth version, with a few corrections into FbForth. Anyway I had little better to do this week. I wanted our Forth neophyte to notice some differences in my version versus the TI-FORTH version. ( @dhe ) My program has no variables. Crazy right? But Forth has a bit in common with functional languages where instead of storing data in variable you generate it and leave it on the data stack for somebody to use. The older version IMHO, was written by someone who came from BASIC and then wrote a kind of BASIC program, but using Forth keywords. It takes some time to get your head around programming in Forth "style" and everybody seems to do it a bit different. The program is broken up into small pieces which makes testing easier. That's important in Forth because the verdammt language is hard enough so you need to test as you go so you trust the pieces. The small sub-routine style would kill normal languages because you have to transfer data in and out of variables. Forth was made with the data stack so sub-routine overhead is lower. It's not free, but it is quite efficient. Here is what I came up with. I added some nicer cursors and a pen-up ability. Spoiler \ KIBBIT.FTH May 31 2024 ported to Camel99 Forth \ Originally written by: \ Greg Goodwin, TI Hoosier's User Group, circa 1980s \ Translated to Camel99 Forth NEEDS .S FROM DSK1.TOOLS \ needed for debugging only NEEDS CASE FROM DSK1.CASE NEEDS PLOT FROM DSK1.GRAPHICS2 NEEDS SPRITE FROM DSK1.SPRITES2 ( for use with Graphics2) NEEDS JOYST FROM DSK1.JOYST HEX \ ================ KIBBIT BEGINS HERE ===================== \ define the sprite shape data but give them a name CREATE $PENCIL ( -- addr ) 8060 , 7038 , 1C0E , 0400 , CREATE $ARROW ( -- addr ) F0E0 , E090 , 0804 , 0000 , CREATE $ERASER ( -- addr ) 0010 , 387C , 3E1E , 0C00 , CREATE $BRUSH ( -- addr ) 8080 , C060 , 6010 , 0800 , CREATE $ROLLER ( -- addr ) 007E , 7E02 , 1E10 , 1010 , DECIMAL : INIT_KIBBIT GRAPHICS2 \ set bitmap mode before anything else DELALL \ INIT the sprite memory \ Write turtle sprite char data into VDP sprite definition table \ data bytes char $PENCIL 8 138 SP.SHAPE $ERASER 8 139 SP.SHAPE $ROLLER 8 140 SP.SHAPE $ARROW 8 141 SP.SHAPE 1 15 COLOR \ colr char X Y spr# 5 138 22 22 0 SPRITE ; \ JOYST Output decoding HEX 01 CONSTANT Fire 02 CONSTANT Left 04 CONSTANT Right 08 CONSTANT Down 10 CONSTANT Up 0A CONSTANT Down/left 0C CONSTANT Down/right 12 CONSTANT Up/left 14 CONSTANT Up/right DECIMAL \ add byte to a byte in VDP memory "vdp char plus store" : VC+! ( byte Vaddr -- ) DUP>R VC@ + R> VC! ; 0 CONSTANT #1 \ the sprite name \ these words alter the sprite position by changing the fields in VDP memory : GOUP -1 #1 SP.Y VC+! ; : GODOWN 1 #1 SP.Y VC+! ; : GOLEFT -1 #1 SP.X VC+! ; : GORIGHT 1 #1 SP.X VC+! ; : MOVE_BRUSH 0 JOYST CASE Left OF GOLEFT ENDOF Right OF GORIGHT ENDOF Down OF GODOWN ENDOF Up OF GOUP ENDOF Down/left OF GODOWN GOLEFT ENDOF Down/right OF GODOWN GORIGHT ENDOF Up/left OF GOUP GOLEFT ENDOF Up/right OF GOUP GORIGHT ENDOF ENDCASE ; \ common factor : ISCURSOR ( ascii -- ) #1 SP.PAT VC! ; : USE-PENCIL PENCIL IS STYLUS 138 ISCURSOR ; : USE-ERASER ERASER IS STYLUS 139 ISCURSOR ; : USE-ROLLER BRUSH IS STYLUS 140 ISCURSOR ; : USE-ARROW PENUP IS STYLUS 141 ISCURSOR ; : CHANGE_BRUSH KEY? CASE [CHAR] D OF USE-PENCIL ENDOF \ pen down to draw [CHAR] E OF USE-ERASER ENDOF [CHAR] T OF USE-ROLLER ENDOF [CHAR] U OF USE-ARROW ENDOF \ pen up [CHAR] C OF INIT_KIBBIT ENDOF ENDCASE ; : KIBBIT INIT_KIBBIT USE-ARROW BEGIN #1 POSITION PLOT MOVE_BRUSH CHANGE_BRUSH ?TERMINAL UNTIL TEXT ; \ KIBBIT \ to start program Here' me showing that it still needs work to be practical kibbit silly demo.mp4 2 Quote Link to comment Share on other sites More sharing options...
GDMike Posted June 1 Share Posted June 1 Absolutely great 1 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.