Jump to content
IGNORED

IntyBASIC compiler v1.0 crunchy&tasty :)


nanochess

Recommended Posts

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 by intvnut
Link to comment
Share on other sites

 

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?

Link to comment
Share on other sites

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 by freeweed
Link to comment
Share on other sites

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...

  • Like 1
Link to comment
Share on other sites

 

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.

Link to comment
Share on other sites

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 8)

  • Like 1
Link to comment
Share on other sites

 

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. :D

  • Like 2
Link to comment
Share on other sites

 

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. :D

 

This reminds me of optimizing prime number generation for speed :grin:

   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 :P

Link to comment
Share on other sites

 

This reminds me of optimizing prime number generation for speed :grin:

   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 :P

 

 

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.)

  • Like 1
Link to comment
Share on other sites

 

 

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!

Link to comment
Share on other sites

  • 2 weeks later...

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.

Link to comment
Share on other sites

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).

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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).

Link to comment
Share on other sites

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 by intvnut
  • Like 2
Link to comment
Share on other sites

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.

 

Link to comment
Share on other sites

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

  • Like 2
Link to comment
Share on other sites

 

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

  • Like 2
Link to comment
Share on other sites

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]

post-31694-0-16710100-1425756307_thumb.jpg

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by intvnut
  • Like 2
Link to comment
Share on other sites

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 by freeweed
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

 

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.

  • Like 1
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...