gar0u Posted May 13, 2021 Share Posted May 13, 2021 I'd like to think I have a good handle on flow control, but this code has me stumped: DO WAIT c = CONT1 LOOP WHILE c DO WAIT c = CONT1 LOOP WHILE c = 0 The first DO loop is waiting for input from controller 1, which is assigned to the variable 'c', and I assume 'c' is initialized to 0, so the condition is false until it gets any input from the controller, which is interpreted as > 0 and casts to true. But what is the purpose of the second DO loop? Thanks for the help. I'm trying to not skip over anything that doesn't make sense. (I also think I have a neat idea for a game, so I'm working my way through both of Oscar's books very diligently while planning out my game on paper. Looking forward to doing some test implementations of things...) Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 13, 2021 Share Posted May 13, 2021 4 hours ago, gar0u said: I'd like to think I have a good handle on flow control, but this code has me stumped: DO WAIT c = CONT1 LOOP WHILE c DO WAIT c = CONT1 LOOP WHILE c = 0 The first DO loop is waiting for input from controller 1, which is assigned to the variable 'c', and I assume 'c' is initialized to 0, so the condition is false until it gets any input from the controller, which is interpreted as > 0 and casts to true. But what is the purpose of the second DO loop? Thanks for the help. I'm trying to not skip over anything that doesn't make sense. (I also think I have a neat idea for a game, so I'm working my way through both of Oscar's books very diligently while planning out my game on paper. Looking forward to doing some test implementations of things...) I believe you have it backwards. The first loop will wait until the controller is fully idle, looping while any input signal is different from zero. The second one will then loop while the controller is idle, waiting for a fresh new input. The end effect is to guarantee that a fresh new input signal is received. This is useful for game transitions, where you want to guarantee that only new input is processed, and ignore any input that was left pressed from before. For example, if you have a screen that says "press any key to continue," you want to make sure that the first key pressed arrives after the message is displayed. Otherwise, you risk skipping that phase completely, if the player left his thumb on the disc on the previous screen. dZ. Quote Link to comment Share on other sites More sharing options...
Zendocon Posted May 13, 2021 Share Posted May 13, 2021 I had asked about CONT1 and CONT2 while proofreading Advanced Game Programming For Intellivision. I know that when there is no input on one of the controllers, all the bits are raised at the memory address associated with that controller. It turns out CONT1 is a mnemonic for "PEEK($1FF) XOR $FF" and CONT2 is a mnemonic for "PEEK($1FE) XOR $FF". Another thing to know, which I pointed out in Appendix E, is that an expression evaluates to TRUE if it is any value other than 0. What that means is, "LOOP WHILE c" will keep code execution in that first loop until c=0, which will be the case when there is no input from Controller 1, as @DZ-Jay pointed out. The second loop waits until there is input from Controller 1. The last line could also be written as "LOOP UNTIL c". I have something similar, also in Appendix E, which is a DEF (definition) for "getInput" which waits for a keypress from either keypad: DEF FN getInput = \ DO: WAIT: \ Input = CONT.KEY: \ LOOP WHILE Input = 12: \ DO: WAIT: \ LOOP UNTIL CONT.KEY = 12 ' Keypad value saved to Input To use this, you would just type "getInput" as a line of code. Obviously, I'm using the variable "Input" instead of "c", so you would modify the code accordingly. I hope this helps. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 13, 2021 Share Posted May 13, 2021 (edited) 56 minutes ago, Zendocon said: It turns out CONT1 is a mnemonic for "PEEK($1FF) XOR $FF" and CONT2 is a mnemonic for "PEEK($1FE) XOR $FF". Another thing to know, which I pointed out in Appendix E, is that an expression evaluates to TRUE if it is any value other than 0. Hi, @Zendocon, I do not know if it is in the books (although I suspect it is in the first one), but that information is described in the IntyBASIC User Manual, which should be the first stop for anybody using IntyBASIC. dZ. Edited May 13, 2021 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
gar0u Posted May 13, 2021 Author Share Posted May 13, 2021 Thank you both for the responses. That makes sense that the first loop is waiting for the controller input to "settle down", then the second loop reads the requested input. I'll check out the IntyBASIC User Manual. Quote Link to comment Share on other sites More sharing options...
Zendocon Posted May 13, 2021 Share Posted May 13, 2021 4 hours ago, DZ-Jay said: Hi, @Zendocon, I do not know if it is in the books (although I suspect it is in the first one), but that information is described in the IntyBASIC User Manual, which should be the first stop for anybody using IntyBASIC. dZ. I didn't even bother with the IntyBASIC user manual. I got started with IntyBASIC after the first book was released. The only thing I did prior was tweak the music in the Music sample program. That's also why my CONST.BAS file in all my projects has all of my own constants defined, duplicating what is in the standard one for IntyBASIC. In my released games so far, I was using PEEK($1ff) and PEEK($1fe) when I needed something on the fly. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 14, 2021 Share Posted May 14, 2021 8 hours ago, Zendocon said: I didn't even bother with the IntyBASIC user manual. I got started with IntyBASIC after the first book was released. The only thing I did prior was tweak the music in the Music sample program. That's also why my CONST.BAS file in all my projects has all of my own constants defined, duplicating what is in the standard one for IntyBASIC. In my released games so far, I was using PEEK($1ff) and PEEK($1fe) when I needed something on the fly. Well then, maybe you should take a peek at the manual. There is a lot of good information in there about how the language works and its limitations. -dZ. Quote Link to comment Share on other sites More sharing options...
carlsson Posted May 14, 2021 Share Posted May 14, 2021 Just about everything in the manual.txt file is reprinted in the first book anyway. Quote Link to comment Share on other sites More sharing options...
Kiwi Posted May 14, 2021 Share Posted May 14, 2021 The manual text is a good reference in case you forget what stuff does like I do all the time. Like the PLAY MUSIC commands or correct myself if I accidentally using C syntax like <> != for not. 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 14, 2021 Share Posted May 14, 2021 (edited) 4 hours ago, carlsson said: Just about everything in the manual.txt file is reprinted in the first book anyway. Well, there you go! The manual includes these helpful nuggets: CONT Contains AND'ed $01fe and $01ff complemented content (from both controllers) ... CONT1 Contains complemented content of address $01ff (left controller) ... CONT2 Contains complemented content of address $01fe (right controller) ... WHILE expr:[statement]:WEND WHILE expr [statement] WEND Looping statement that keeps looping as long as the expression evaluates to non-zero. ... DO:[statement]:LOOP UNTIL expr DO [statement] LOOP UNTIL expr Looping statements that keep looping WHILE expression evaluates to non-zero, or UNTIL expression evaluates to non-zero. There are quite more technical details revealing the nuances of the language implementation, such as: A=A=B If A and B are the same the result is $ffff (-1) else zero ... o Comparisons now return $ffff for true results, useful with NOT Edited May 14, 2021 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 14, 2021 Share Posted May 14, 2021 One thing to note is that comparisons against zero are generally more efficient, if just slightly so, especially in DO/WHILE. This is because comparing against zero is a native CPU operation, while comparing against constants require loading the values into CPU registers first. Also, complex logical expressions with multiple terms are less efficient than nesting them one at a time. This is because something like the following: IF (A=B) AND (C=D) THEN Requires each term to be evaluated and then assigned a temporary logical value of zero (false) or true (-1) before performing the AND operation. In essence, the evaluated result of each term is normalized to a logical value in order to evaluate the greater expression. This is in contrast to writing the same like this: IF (A=B) THEN IF (C=D) THEN ... Which does not need to normalize or store any interim results: each term is evaluated and the results are directly applied to either process the inner block, or skip it. -dZ. Quote Link to comment Share on other sites More sharing options...
Zendocon Posted May 14, 2021 Share Posted May 14, 2021 53 minutes ago, DZ-Jay said: One thing to note is that comparisons against zero are generally more efficient, if just slightly so, especially in DO/WHILE. This is because comparing against zero is a native CPU operation, while comparing against constants require loading the values into CPU registers first. Funny you bring that up. I actually mentioned that in Appendix E of the Advanced book, where I shared a snippet of code from X-Ray, including a line at the end of a DO block with an expression that either does or doesn't evaluate to 0 in lieu of TRUE or FALSE. Quote Link to comment Share on other sites More sharing options...
Peripheral Posted May 14, 2021 Share Posted May 14, 2021 4 hours ago, DZ-Jay said: IF (A=B) AND (C=D) THEN Requires each term to be evaluated and then assigned a temporary logical value of zero (false) or true (-1) before performing the AND operation. In essence, the evaluated result of each term is normalized to a logical value in order to evaluate the greater expression. -dZ. As a casual user of IntyBasic, and coming from a C/C++ background, I've been bitten more than once by writing IF (A AND B) ... which can be false even when both A and B are non-zero. Proper ways to check that both conditions are true are either IF (A <> 0 AND B <> 0), or use nesting: IF (A) THEN IF (B) THEN One of my wish list items for IntyBasic is introduction of true logical and/or operators, like C's && and ||, complete with short circuit evaluation for performance reasons. @nanochess, are you listening? 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 14, 2021 Share Posted May 14, 2021 1 hour ago, Peripheral said: As a casual user of IntyBasic, and coming from a C/C++ background, I've been bitten more than once by writing IF (A AND B) ... which can be false even when both A and B are non-zero. Proper ways to check that both conditions are true are either IF (A <> 0 AND B <> 0), or use nesting: IF (A) THEN IF (B) THEN One of my wish list items for IntyBasic is introduction of true logical and/or operators, like C's && and ||, complete with short circuit evaluation for performance reasons. @nanochess, are you listening? Well, there are no "boolean" variables in IntyBASIC. If you define "A" and "B" as integers in C, you will get the same effect: a bitwise operation. But your point is very valid: programmers should keep in mind that in IntyBASIC logical "truth" is represented by any non-zero value in most circumstances. It is only given a precise value of "-1" when assigning the result of a logical expression to a variable, or when using such result as part of a greater expression, as I mentioned in my prior examples. -dZ. 1 Quote Link to comment Share on other sites More sharing options...
Zendocon Posted May 14, 2021 Share Posted May 14, 2021 Reminds me of writing a rudimentary text editor for a class project. ASCII codes 10 and 13 are both often recognized as newline characters, so at first glance to freshmen, this line if (keycode = 10 || 13) { // Newline } ought to execute the "Newline" block. But "10 || 13" bitwise results in 15, so that block is never executed, because none of the characters in the file used ASCII code 15. Quote Link to comment Share on other sites More sharing options...
carlsson Posted May 14, 2021 Share Posted May 14, 2021 Is there any programming language that allows the later example? I know some have constructs like keycode in [10, 13] but that is a slightly different syntax. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 14, 2021 Share Posted May 14, 2021 1 hour ago, carlsson said: Is there any programming language that allows the later example? I know some have constructs like keycode in [10, 13] but that is a slightly different syntax. I think languages that have distinct operators for bitwise and logical operations. VB.Net or C#? I don't know. But even then, what does it even mean to say "(10 || 13)"? It is either a bitwise operation or a logical expression; and in either case, the results would be functionally equivalent. I do not know of any language that allows you to compare compare one term with all elements within a set using purely logical operators. The closest thing I can think of is the "in set" operator, like some functional languages (and Pascal) have. Still that's an explicit operation in a set. I think that @Zendocon's point was that a naive or inexperienced programmer may commit such a mistake, not knowing really knowing how logical expressions work in practice. I would agree with that, but then again, that just suggests they should read the manual. dZ. 1 Quote Link to comment Share on other sites More sharing options...
Peripheral Posted May 14, 2021 Share Posted May 14, 2021 4 hours ago, DZ-Jay said: Well, there are no "boolean" variables in IntyBASIC. If you define "A" and "B" as integers in C, you will get the same effect: a bitwise operation. -dZ. It depends on what you choose to replace "AND" with. You're assuming "&". I'm looking for an "&&" operator, which clearly does not give the same effect as IntyBasic AND. 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.