freewheel Posted February 22, 2015 Share Posted February 22, 2015 Ah, 20Hz - that would explain the huge difference in scrolling smoothness. I figured there was no way Space Patrol used hardware scrolling, especially with the stationary images at the bottom. I still know of no easy way to keep anything static while scrolling, other than using precious MOBs. Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 22, 2015 Share Posted February 22, 2015 (edited) Ah, 20Hz - that would explain the huge difference in scrolling smoothness. 20Hz affects everything's smoothness. Somehow, I think the 20Hz design decision for the original EXEC saddled the system with an undeserved perception of slowness. The system was more than capable of keeping up with 60Hz updates. I figured there was no way Space Patrol used hardware scrolling, especially with the stationary images at the bottom. I still know of no easy way to keep anything static while scrolling, other than using precious MOBs. Yep, no hardware scrolling in Space Patrol. That said, you don't need to use MOBs to make stationary elements when using hardware scrolling. See River Raid and Bump & Jump for counterexamples. (Both of those examples use the same trick, as I recall, although B&J is less effective at hiding it.) Edited February 22, 2015 by intvnut Quote Link to comment Share on other sites More sharing options...
freewheel Posted February 23, 2015 Share Posted February 23, 2015 That said, you don't need to use MOBs to make stationary elements when using hardware scrolling. See River Raid and Bump & Jump for counterexamples. (Both of those examples use the same trick, as I recall, although B&J is less effective at hiding it.) Huh. I couldn't think of an example so I just haven't experimented enough. Checking our River Raid, yeah, it's pretty smooth. What are they doing? Just constantly re-drawing the stationary cards and making sure they're timing things just right to avoid jerkiness? Quote Link to comment Share on other sites More sharing options...
freewheel Posted February 23, 2015 Share Posted February 23, 2015 (edited) General IntyBASIC/ASM1600 question: Is there a limit on the number of labels that can be used in a program? Is there any reason I can't use hundreds of labels to really have data granularity (and/or just a lot of data)? I can't remember if we've discussed this before. Edited February 23, 2015 by freeweed Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 23, 2015 Share Posted February 23, 2015 Huh. I couldn't think of an example so I just haven't experimented enough. Checking our River Raid, yeah, it's pretty smooth. What are they doing? Just constantly re-drawing the stationary cards and making sure they're timing things just right to avoid jerkiness? They're shifting the graphics in GRAM across multiple cards. When the screen scrolls down by one row, they're moving the image up by one row in GRAM to compensate. You can do the same thing horizontally, but it's a bit more expensive. General IntyBASIC/ASM1600 question: Is there a limit on the number of labels that can be used in a program? Is there any reason I can't use hundreds of labels to really have data granularity (and/or just a lot of data)? I can't remember if we've discussed this before. AS1600 has no intrinsic limit here. I imagine IntyBASIC has no limit either, but I'll let nanochess answer for sure. If you do find a limit on number of labels in AS1600, let me know, and I'll fix it. I'm pretty sure there isn't any hard limit. Obviously, if you use more labels than fit in your PC's RAM, AS1600 will have a problem.... I doubt you're going quite that far... 1 Quote Link to comment Share on other sites More sharing options...
freewheel Posted February 23, 2015 Share Posted February 23, 2015 AS1600 has no intrinsic limit here. I imagine IntyBASIC has no limit either, but I'll let nanochess answer for sure. If you do find a limit on number of labels in AS1600, let me know, and I'll fix it. I'm pretty sure there isn't any hard limit. Obviously, if you use more labels than fit in your PC's RAM, AS1600 will have a problem.... I doubt you're going quite that far... Good to know I guess at the end of the day, labels just end up as addresses within the final executable code? So the cardinal number of them is irrelevant? I'm just so used to running into limits on everything that I realized I've never thought much about this. And my latest monstrosity has a LOT of labels. Quote Link to comment Share on other sites More sharing options...
+nanochess Posted February 23, 2015 Author Share Posted February 23, 2015 AS1600 has no intrinsic limit here. I imagine IntyBASIC has no limit either, but I'll let nanochess answer for sure. If you do find a limit on number of labels in AS1600, let me know, and I'll fix it. I'm pretty sure there isn't any hard limit. Obviously, if you use more labels than fit in your PC's RAM, AS1600 will have a problem.... I doubt you're going quite that far... IntyBASIC has no limit in program size or labels used 1 Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 23, 2015 Share Posted February 23, 2015 Good to know I guess at the end of the day, labels just end up as addresses within the final executable code? So the cardinal number of them is irrelevant? I'm just so used to running into limits on everything that I realized I've never thought much about this. And my latest monstrosity has a LOT of labels. For fun, I just ran a test through AS1600 that had, literally, 1 million labels. It took a little longer to assemble than I would have liked (just over a minute), but it did assemble. I'll have to profile to see where all that time went. FWIW, the test itself was 1,000,000 labels followed by a single NOP. The resulting executable is only 2 bytes large. 2 Quote Link to comment Share on other sites More sharing options...
+nanochess Posted February 23, 2015 Author Share Posted February 23, 2015 For fun, I just ran a test through AS1600 that had, literally, 1 million labels. It took a little longer to assemble than I would have liked (just over a minute), but it did assemble. I'll have to profile to see where all that time went. FWIW, the test itself was 1,000,000 labels followed by a single NOP. The resulting executable is only 2 bytes large. This reminds me of optimizing prime number generation for speed MVII #2,R0 CALL output_number MVII #3,R0 CALL output_number MVII #5,R0 CALL output_number MVII #7,R0 CALL output_number MVII #11,R0 CALL output_number MVII #13,R0 CALL output_number ... ... continue up to xxx th prime ... As you can see, no time is wasted in unnecessary calculations Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 23, 2015 Share Posted February 23, 2015 This reminds me of optimizing prime number generation for speed MVII #2,R0 CALL output_number MVII #3,R0 CALL output_number MVII #5,R0 CALL output_number MVII #7,R0 CALL output_number MVII #11,R0 CALL output_number MVII #13,R0 CALL output_number ... ... continue up to xxx th prime ... As you can see, no time is wasted in unnecessary calculations You may laugh, but I actually did something like this once. I precomputed a bitmap of all prime numbers that fit in 32 bits. I had a particular need to do quick primality testing. BTW, you can optimize the code above for size without affecting speed: . CALL output_number DECLE 2 CALL output_number DECLE 3 CALL output_number DECLE 5 CALL output_number DECLE 7 CALL output_number DECLE 11 CALL output_number DECLE 13 ... ... continue up to xxx th prime ... . ...and then just put a MVI@ R5, R0 on the other side of the call. Same total cycles, but fewer bytes. (While this example is a bit contrived, it can make sense elsewhere in Inty code.) 1 Quote Link to comment Share on other sites More sharing options...
+nanochess Posted February 23, 2015 Author Share Posted February 23, 2015 You may laugh, but I actually did something like this once. I precomputed a bitmap of all prime numbers that fit in 32 bits. I had a particular need to do quick primality testing. BTW, you can optimize the code above for size without affecting speed: . CALL output_number DECLE 2 CALL output_number DECLE 3 CALL output_number DECLE 5 CALL output_number DECLE 7 CALL output_number DECLE 11 CALL output_number DECLE 13 ... ... continue up to xxx th prime ... . ...and then just put a MVI@ R5, R0 on the other side of the call. Same total cycles, but fewer bytes. (While this example is a bit contrived, it can make sense elsewhere in Inty code.) Oh my! And even then I learnt something In fact this could be useful in my future coding! Thanks! Quote Link to comment Share on other sites More sharing options...
First Spear Posted March 6, 2015 Share Posted March 6, 2015 What would be a smart way to mimic the behavior of the INPUT statment used in other flavors of BASIC? For example, to do something like this: Input at 20 Color 7 , "Value 0?" , #myVar to allow numeric input on the screen into #myVar and potentially halt program execution until input is complete? Thanks. Quote Link to comment Share on other sites More sharing options...
freewheel Posted March 6, 2015 Share Posted March 6, 2015 Keep in mind that INPUT handles the .. well, input for you. The keyboard. In IntyBASIC you have to handle it yourself. So the answer is, CONT(1/2). PRINT AT 20,"Value?" loop: c=CONT if c = 0 THEN GOTO loop ELSE myVar=c Or similar. Obviously you'll want to do a lot of processing on myVar depending on what you're aiming for. And you'll want a lot of logic to avoid specious input (say the direction disc, etc). Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted March 6, 2015 Share Posted March 6, 2015 What would be a smart way to mimic the behavior of the INPUT statment used in other flavors of BASIC?The smartest way I can think of is for IntyBASIC to support the statement natively. That said, the way I do this in P-Machinery is to use a simple state machine. Nothing fancy: you just loop while you wait for the "enter" key sequence, storing input in a buffer. When the "enter" sequence is accepted, you exit the loop. At that point, the contents of the buffer are your final input. Of course, since P-Machinery is event-driven, it doesn't really "loop," it just continues processing normally, and triggers an event when "enter" sequence is accepted. At that point, a call-back handler is executed. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted March 6, 2015 Share Posted March 6, 2015 Thanks. My unstated issue is that I want to input 4 digit numbers for #myvar, and I have 8 actual variables to fill. I started down the path you suggested but if I want to enter "45" and I first accept a 4 and then a 5 I will end up storing a 9. Thanks. Keep in mind that INPUT handles the .. well, input for you. The keyboard. In IntyBASIC you have to handle it yourself. So the answer is, CONT(1/2). PRINT AT 20,"Value?" loop: c=CONT if c = 0 THEN GOTO loop ELSE myVar=c Or similar. Obviously you'll want to do a lot of processing on myVar depending on what you're aiming for. And you'll want a lot of logic to avoid specious input (say the direction disc, etc). Quote Link to comment Share on other sites More sharing options...
intvnut Posted March 6, 2015 Share Posted March 6, 2015 (edited) Thanks. My unstated issue is that I want to input 4 digit numbers for #myvar, and I have 8 actual variables to fill. I started down the path you suggested but if I want to enter "45" and I first accept a 4 and then a 5 I will end up storing a 9. I'm a subroutine freak, so I'd probably write something like this. Note I haven't tested it and so the syntax may be off. But, hopefully you get the idea. WaitNewKey Procedure wnk: IF CONT.KEY <> 12 THEN GOTO wnk wk: IF CONT.KEY = 12 THEN GOTO wk FOR Debounce = 1 TO 100 IF CONT.KEY = 12 THEN GOTO wk NEXT RETURN End GetDigit Procedure GOSUB WaitNewKey Digit = CONT.KEY RETURN End ' AtPos Position to display number at during entry ' #Value Number entered. Initialize to 0 or desired initial value before calling GetNumber4 Procedure gn4: PRINT AT AtPos, <.4> #Value GOSUB GetDigit IF Digit == 11 THEN RETURN ' Return entered value IF Digit == 10 THEN #Value = 0 : GOTO gn4 ' Clear entered value #Value = ( ( #Value % 100 ) * 10 + Digit ) GOTO gn4 End Edited March 6, 2015 by intvnut 2 Quote Link to comment Share on other sites More sharing options...
freewheel Posted March 6, 2015 Share Posted March 6, 2015 Thanks. My unstated issue is that I want to input 4 digit numbers for #myvar, and I have 8 actual variables to fill. I started down the path you suggested but if I want to enter "45" and I first accept a 4 and then a 5 I will end up storing a 9. That's just a math problem then. Multiply the first digit by 10 and add to the second. Do it on the fly or use temp variables, depending on how you handle things. Quote Link to comment Share on other sites More sharing options...
intvnut Posted March 7, 2015 Share Posted March 7, 2015 Thanks. My unstated issue is that I want to input 4 digit numbers for #myvar, and I have 8 actual variables to fill. I started down the path you suggested but if I want to enter "45" and I first accept a 4 and then a 5 I will end up storing a 9. Ok, so after a couple margaritas, I decided to polish up those routines I wrote earlier and make them actually work. This short demo actually works. You can enter 8 values, and they get populated in the array #Parm(). Feel free to use this in any program. I release this snippet to the public domain if it was even copyrightable to begin with. . ' Number Input Demo DIM #Parm( WAIT CLS FOR I = 0 to 7 PRINT AT Prompt(I), "Input ", <1> I+1, "? " AtPos = Prompt(I) + 10 #Value = 0 GOSUB GetNumber4 #Parm(I) = #Value NEXT I FOR I = 1 to 30 WAIT NEXT I CLS FOR I = 0 to 7 PRINT AT Prompt(I) COLOR 6, "Value ", <1>I+1, " = ", <.4> #Parm(I) NEXT I Done: GOTO Done Prompt: DATA 43, 63, 83, 103, 123, 143, 163, 183 WaitNewKey: Procedure wnk: IF CONT.KEY <> 12 THEN WAIT : GOTO wnk wk: IF CONT.KEY = 12 THEN WAIT : GOTO wk RETURN End GetDigit: Procedure GOSUB WaitNewKey Digit = CONT.KEY RETURN End ' AtPos Position to display number at during entry ' #Value Number entered. Init to 0 or desired initial value before calling GetNumber4: Procedure gn4: PRINT AT AtPos, <.4> #Value GOSUB GetDigit IF Digit = 11 THEN RETURN ' Return entered value IF Digit = 10 THEN #Value = 0 : GOTO gn4 ' Clear entered value #Value = ( ( #Value % 1000 ) * 10 + Digit ) GOTO gn4 End numin.bas 2 Quote Link to comment Share on other sites More sharing options...
intvnut Posted March 7, 2015 Share Posted March 7, 2015 Ok, so after a couple margaritas, I decided to polish up those routines I wrote earlier and make them actually work. This short demo actually works. You can enter 8 values, and they get populated in the array #Parm(). Feel free to use this in any program. I release this snippet to the public domain if it was even copyrightable to begin with. . And yes, I realize GetDigit is a bit superfluous. I should have nuked it. I initially thought more might need to go in there, but it wasn't really necessary. Here's a more concise but functionally equivalent version. . ' Number Input Demo ' J. Zbiciak, Mar 2015 DIM #Parm( WAIT CLS FOR I = 0 to 7 PRINT AT Prompt(I), "Input ", <1> I+1, "? " AtPos = Prompt(I) + 10 #Value = 0 GOSUB GetNum #Parm(I) = #Value NEXT I FOR I = 1 to 30 WAIT NEXT I CLS FOR I = 0 to 7 PRINT AT Prompt(I) COLOR 6, "Value ", <1>I+1, " = ", <.4> #Parm(I) NEXT I Done: GOTO Done Prompt: DATA 43, 63, 83, 103, 123, 143, 163, 183 GetKey: Procedure wnk: IF CONT.KEY <> 12 THEN WAIT : GOTO wnk wk: IF CONT.KEY = 12 THEN WAIT : GOTO wk RETURN End ' AtPos Position to display number at during entry ' #Value Number entered. Init to 0 or desired initial value before calling GetNum: Procedure gn4: PRINT AT AtPos, <.4> #Value GOSUB GetKey Digit = CONT.KEY IF Digit = 11 THEN RETURN ' Return entered value IF Digit = 10 THEN #Value = 0 : GOTO gn4 ' Clear entered value #Value = ( ( #Value % 1000 ) * 10 + Digit ) GOTO gn4 End numin.bas 2 Quote Link to comment Share on other sites More sharing options...
First Spear Posted March 7, 2015 Share Posted March 7, 2015 So awesome. I wish there was more than one "like" button for posts. Thank you! And yes, I realize GetDigit is a bit superfluous. I should have nuked it. I initially thought more might need to go in there, but it wasn't really necessary. Here's a more concise but functionally equivalent version. . ' Number Input Demo ' J. Zbiciak, Mar 2015 [snip] Quote Link to comment Share on other sites More sharing options...
freewheel Posted March 11, 2015 Share Posted March 11, 2015 Pretty sure this was asked/answered before, but I forget: Where do the variable limits come from in IntyBASIC? A simple program seems to be able to use 209 8-bit vars (I assume from scratchpad) and 51 16-bit vars. Shouldn't the latter have a lot more room? This ends up giving a person ~300 bytes of RAM to work with, doesn't the INTV have something like 3x that available (I mean after GRAM is taken out of the entire memory equation)? What parts am I forgetting/missing? I'm excluding the use that happens when you add in MUSIC, VOICE, etc. I know those modules carve out some RAM usage which reduces things even further. Quote Link to comment Share on other sites More sharing options...
intvnut Posted March 11, 2015 Share Posted March 11, 2015 (edited) Pretty sure this was asked/answered before, but I forget: Where do the variable limits come from in IntyBASIC? A simple program seems to be able to use 209 8-bit vars (I assume from scratchpad) and 51 16-bit vars. Shouldn't the latter have a lot more room? This ends up giving a person ~300 bytes of RAM to work with, doesn't the INTV have something like 3x that available (I mean after GRAM is taken out of the entire memory equation)? What parts am I forgetting/missing? I'm excluding the use that happens when you add in MUSIC, VOICE, etc. I know those modules carve out some RAM usage which reduces things even further. The Intellivision has 240 bytes of 8-bit RAM at $100 - $1EF, and 112 words of 16-bit RAM at $2F0 - $35F. That's it, if you exclude GRAM. The 209 and 51 are what's left after IntyBASIC takes its share for internal variables, stack, etc. You can see what it's allocating into both spaces by looking at the assembler output. In particular, the listing file has a list of symbols and what addresses they got allocated to. You can see what symbols got allocated in the range $2F0 - $35F, for example, to see what got allocated over there. Or, you could read intybasic_prologue.asm and intybasic_epilogue.asm. EDIT: Ok, I tried assembling a simple "hello" program with IntyBASIC 1.02. It consisted solely of PRINT AT 0, "HELLO", followed by "x: GOTO x". IntyBASIC reported: . 8 used 8-bit variables of 212 available 0 used 16-bit variables of 71 available . Off the bat, I'm not sure what 8 variables I used, but there's apparently 204 more 8-bit variables and 71 16-bit variables available to me. So, what did IntyBASIC use in RAM? I assembled and asked the assembler to output a symbol list to hello.sym. Here's the portion that falls in $100 - $1EF. These are all in 8-bit memory: . 00000100 ISRVEC 00000100 SCRATCH 00000102 _int 00000103 _ntsc 00000104 _rand 00000105 _gram_target 00000106 _gram_total 00000107 _gram2_target 00000108 _gram2_total 00000109 _mode_select 0000010A _border_color 0000010B _border_mask 0000010C _SCRATCH . The SCRATCH and _SCRATCH labels aren't actually variables. These keep track of where the allocation pointer is in 8-bit memory. So, it looks like the first 12 locations out of 240 are taken, which should leave 228 locations ($10C to $1EF) available. Not sure why fewer are available. For 16-bit memory, here's what's allocated between $2F0 and $35F: . 000002F0 STACK 000002F0 SYSTEM 00000308 _SYSTEM 00000323 _scroll_buffer 00000337 _music_table 00000338 _music_start 00000339 _music_p 0000033A _frame 0000033B _read 0000033C _gram_bitmap 0000033D _gram2_bitmap 0000033E _screen 0000033F _color 00000340 _mobs 00000358 _col0 00000359 _col1 0000035A _col2 0000035B _col3 0000035C _col4 0000035D _col5 0000035E _col6 0000035F _col7 . Here, the SYSTEM and _SYSTEM labels are what IntyBASIC uses to keep track of what 16-bit space it's using. It looks like the stack takes the first 24 words of 16-bit RAM ($2F0 - $307), The rest is apparently at the top of 16-bit RAM: SCROLL buffer from $323 to $336 Music stuff from $337 to $339 Current frame number at $33A Current READ pointer at $33B GRAM loading variables at $33C to $33D Current PRINT AT and COLOR variables. (_screen and _color, respectively) MOB shadow at $340 - $357 MOB collision tables at $358 - $35F If I counted this correctly, that's an additional 61 words over the 24 words of stack, for a total of 85 words used by IntyBASIC. That should leave only 27 words available for 16 bit variables, not 71. And yet IntyBASIC reports 71? nanochess, can you help us out here? Are these numbers corrected in IntyBASIC 1.0.3? Edited March 11, 2015 by intvnut 2 Quote Link to comment Share on other sites More sharing options...
freewheel Posted March 11, 2015 Share Posted March 11, 2015 (edited) Hm. It also helps that I'm clearly reading the wrong docs. I'm seeing hints of a total of (roughly) 1.5KB of RAM available. Take out 512 bytes for GRAM, and that still should leave an awful lot to use. The Scratchpad RAM adds up, but for whatever reason I thought there should be a lot more of the 16-bit system RAM available. For example, here's what the always-reliable Wikipedia has to say: 1456 bytes of RAM: 240 × 8-bit Scratchpad Memory 352 × 16-bit (704 bytes) System Memory 512 × 8-bit Graphics RAM Edited March 11, 2015 by freeweed Quote Link to comment Share on other sites More sharing options...
carlsson Posted March 11, 2015 Share Posted March 11, 2015 What happens if you try to assign say 30, 50 or 70 variables of 16-bit length each? Does the compiler give up, does the assembler complain, does the executable crash? Does the compiler temporarily swap around 16-bit variables into the 8-bit storage area if there is empty space? Quote Link to comment Share on other sites More sharing options...
catsfolly Posted March 11, 2015 Share Posted March 11, 2015 Hm. It also helps that I'm clearly reading the wrong docs. I'm seeing hints of a total of (roughly) 1.5KB of RAM available. Take out 512 bytes for GRAM, and that still should leave an awful lot to use. The Scratchpad RAM adds up, but for whatever reason I thought there should be a lot more of the 16-bit system RAM available. For example, here's what the always-reliable Wikipedia has to say: 1456 bytes of RAM: 240 × 8-bit Scratchpad Memory 352 × 16-bit (704 bytes) System Memory 512 × 8-bit Graphics RAM That 352 words of 16 bit System Memory includes the 240 words of Backtab (the 20 by 12 grid of characters making up the Intellivision display) and the 112 remaining words that Joe talks about. 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.