Jump to content
IGNORED

IntyBASIC compiler v1.4.2: reloaded with new features


nanochess

Recommended Posts

13 minutes ago, First Spear said:

The number of folks that have the mental agility and Inty expertise to do this are fairly low. :) Maybe 4 of you? 5? Anyway, it would be fun to have the extra functionality from Arnauld's tracker, maybe call it MUSIC2 or MUSICA commands? :)

 

 

 

One of my goals for the new Intellivision Music Tracker v1.5 was to adapt it to work with IntyBASIC.  I think it's doable, I just haven't had a chance to play with it.  Now that I am on vacation (finally), I'll see to releasing the new tracker library, the comprehensive manual I wrote, and the glue-code library to make it work with the IntyBASIC SDK.

 

     -dZ.

  • Like 2
Link to comment
Share on other sites

12 hours ago, artrag said:

Question: is there an efficient way to do a function doing this 



YEvent:procedure	'YEvent(ys,ya)
	' input  ys,ya
	if (ya and 1) then 
		yr = #Interaction(ys*2 + ((ya/2) and 1))/256
	else
		yr = #Interaction(ys*2 + ((ya/2) and 1))and 255
	end if
end

I did this:

 

DEF FN XEvent(s,a)    = (#Interact(s*2 + ((a/2) and 1))/((a and 1)*255 + 1)) and 255

 

but it is way too slow for its purpose

 

You could implement an assembly language function and call it using USR YOURFUNC(ys,ya), R0 would get ys and R1 would get ya.

 

 

Link to comment
Share on other sites

I had nine different songs, and randomly wanted to play one in the game, i.e. my musical memory game that I posted last year.

 

While I could have done a construction like this:

 

IF k=1 THEN PLAY song1

ELSE IF k=2 THEN PLAY song2

ELSE IF k=3 THEN PLAY song3

etc

 

I thought there should be a more elegant way. Thus I defined song pointers:

 

song_pointers:

DATA VARPTR song1(0)

DATA VARPTR song2(0)

etc

 

and kind of hoped I could use PLAY song_pointers(k) but alas it did not work. This is where I believe PLAY VARPTR song_pointers(k) would belong.

 

So what I ended up doing, like described in a comment on the previous page was:

 

#ptr = song_pointers(k)

ASM MVI var_&PTR,R0

ASM CALL _play_music

 

which is exactly what I wanted to do, but it would not fly e.g. in an IntyBASIC contest where custom ASM is not possible.

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...
On 12/18/2020 at 6:34 AM, carlsson said:

Up till now, I still don't know anyone who has integrated Arnaud's tracker with IntyBASIC. I imagine me or DZ-Jay are most likely to do that, though the player uses a good amount of 16-bit variables so it could be a tight fit without CC3/JLP extension.

 

This is now a reality!  I have adapted the Intellivision Music Tracker v1.5 (based on Arnauld's tracker) to integrate with IntyBASIC.

 

By the way, the 6-channel tracker uses only eight 16-bit variables.  It does require 35 8-bit variables, but the pool of 8-bit Scratch RAM is considerably larger. :)

 

   -dZ.

Edited by DZ-Jay
  • Like 4
Link to comment
Share on other sites

  • 3 weeks later...
On 12/18/2020 at 4:16 AM, artrag said:

Question: is there an efficient way to do a function doing this 



YEvent:procedure	'YEvent(ys,ya)
	' input  ys,ya
	if (ya and 1) then 
		yr = #Interaction(ys*2 + ((ya/2) and 1))/256
	else
		yr = #Interaction(ys*2 + ((ya/2) and 1))and 255
	end if
end

I did this:

 

DEF FN XEvent(s,a)    = (#Interact(s*2 + ((a/2) and 1))/((a and 1)*255 + 1)) and 255

 

but it is way too slow for its purpose

 

On 12/18/2020 at 4:55 PM, nanochess said:

 

You could implement an assembly language function and call it using USR YOURFUNC(ys,ya), R0 would get ys and R1 would get ya.

 

 

If it always uses ys and ya and writes to yr, it seems like it'd be faster to have a function that read those directly that you just CALL.

 

Something like this would work:

 

;YEvent:procedure	'YEvent(ys,ya)
;	' input  ys,ya
;	if (ya and 1) then 
;		yr = #Interaction(ys*2 + ((ya/2) and 1))/256
;	else
;		yr = #Interaction(ys*2 + ((ya/2) and 1))and 255
;	end if
; end

YEVENT PROC
       MVI  var_YA, R0  ;  10
       MVI  var_YS, R1  ;  10
       SARC R0          ;   6  C = YA and 1
       GSWD R2          ;   6  stash it away in R2
       SARC R0          ;   6  C = (YA / 2) and 1
       RLC  R1          ;   6  R1 = (YS*2 + ((YA/2) and 1))
       ADDI #array_&INTERACTION, R1 ; 8
       MVI@ R1, R0      ;   8  R0 = #Interaction(YS*2 + ((YA/2) and 1))
       RSWD R2          ;   6  restore: C = YA and 1
       BNC  @@0         ;   7(9) If YA and 1
       SWAP R0          ;   6  true:  swap upper byte to lower
@@0:   MVO  R0, var_YR  ;  11  both:  store lower byte. (No AND 255 needed.)
       JR   R5          ;   7  return
       ENDP             ;----
                        ;  97 cycles worst-case

 

If you use USR instead, you'll want to swap the argument order so that ys ends up in R1.  R0 can't be used for memory indexing.  You will also need to put ANDI #$FF, R0 in place of MVO R0, var_YR, since there's no guarantee you'll store to 8-bit memory and slice off the upper 8 bits.  The result would only be slightly slower (16 cycles), but it'll be larger by 6 words for every call you make to YEvent.

 

If you can change how you encode #Interaction and swap the two LSBs, you can eliminate the GSWD/RSWD pair and go faster.  And if you invert the polarity for the if/else, you can save 2 more cycles in the "branch taken" case.

 

;YEvent:procedure	'YEvent(ys,ya)
;	' input  ys,ya
;	if (ya and 2) then 
;		yr = #Interaction(ys*2 + (ya and 1)) and 255
;	else
;		yr = #Interaction(ys*2 + (ya and 1)) / 256
;	end if
; end

YEVENT PROC
       MVI  var_YA, R0  ;  10
       MVI  var_YS, R1  ;  10
       SARC R0          ;   6  C = YA and 1
       RLC  R1          ;   6  R1 = (YS*2 + (YA and 1))
       ADDI #array_&INTERACTION, R1 ; 8
       MVI@ R1, R1      ;   8  R1 = #Interaction(YS*2 + ((YA/2) and 1))
       SARC R0          ;   6  C = (YA and 2) <> 0
       ADCR PC          ;   7  skip SWAP if (YA and 2) <> 0
       SWAP R0          ;   6  (YA and 2) = 0:  swap upper byte to lower
@@0:   MVO  R0, var_YR  ;  11  both:  store lower byte. (No AND 255 needed.)
       JR   R5          ;   7  return
       ENDP             ;----
                        ;  85 cycles worst-case

 

 

  • Like 1
Link to comment
Share on other sites

On 11/24/2020 at 5:06 PM, Kiwi said:

I found a small Intybasic bug that I can't map at $c100. It doesn't show up in the .cfg file.  I used to be able to map data to that segment at $c100 using older version of Intybasic. Small work around is to map at $c200.  I'm not sure if I'm alone with the issue, I'm using the latest Intybasic version.

EDIT: I may be over in segment $A000-$BFFF, so that's why it's not mapping at $C100. 

EDIT2: It been confirmed I was over that segment.  It's now all fixed.

 

Recent versions of AS1600 have a feature to help detect this problem.  Have a look in jzintv/doc/utilities/as1600.txt, and look for ERR_IF_OVERWRITTEN.  You can also use the as1600 command-line flag --err-if-overwritten (or -e for short) to turn this on.  It'll cause AS1600 to throw an error if you accidentally assemble two things to the same address.  I suspect it would have caught your section overflow.

 

------------------------------------------------------------------------------
    ERR_IF_OVERWRITTEN expr     Mark code as "not intended to be overwritten"
    FORCE_OVERWRITE expr        Force code to be overwritten anyway
------------------------------------------------------------------------------

By default, AS1600 lets you assemble new code over addresses you've already
assembled code into.  That allows for some interesting tricks; however, most
often this is really an error.

The ERR_IF_OVERWRITTEN directive controls a flag that indicates whether the
code that follows may be safely overwritten.  0 means "safe to overwrite",
while 1 means "throw an error if overwritten."

>>> Note:  ERR_IF_OVERWRITTEN defaults to 0.  You can change the default at
>>         the command line by adding the flag -e or --err-if-overwritten

For example, if I wanted to fill some ROM with a fixed pattern, and then
overwrite it with final code, I could do something like this:

        ERR_IF_OVERWRITTEN 0    ; About to write some filler data
        ORG $6000
        REPEAT  4096 / 8
        DECLE   -1, -1, -1, -1, -1, -1, -1, -1
        ENDR

        ERR_IF_OVERWRITTEN 1    ; Now overwrite it with real code
        ORG $6000
        ; The following generates no errors or warnings.
fun:    PROC
        MVII    #ISR,   R0
        MVO     R0,     $100
        SWAP    R0
        MVO     R0,     $101
        ;...
        ENDP

        ; This code, however, will trigger an error, because it's overwriting
        ; the code we just assembled at 'fun':
        ORG $6000
        DECLE   12, 34          ; ERROR - ROM overwrite error on $6000 - $6001

The FORCE_OVERWRITE directive gives you the ability to forcibly overwrite
code that was previously assembled with ERR_IF_OVERWRITTEN == 1.  Revisiting
the previous example:

        ERR_IF_OVERWRITTEN 1    ; Now overwrite it with real code
        ORG $6000
fun:    PROC
        MVII    #ISR,   R0
        MVO     R0,     $100
        SWAP    R0
        MVO     R0,     $101
        ;...
        ENDP

        ; With FORCE_OVERWRITE, this code now assembles without errors.
        FORCE_OVERWRITE 1
        ORG $6000
        DECLE   12, 34

The FORCE_OVERWRITE directive is meant for use in specialized macros that
may wish to "back-patch" code that otherwise should have ERR_IF_OVERWRITTEN
turned on.  Use it sparingly.

There is no way to query the current state of ERR_IF_OVERWRITTEN or
FORCE_OVERWRITE.  If you need to track that for some reason, wrap these in
macros.

Truth table:

    ERR_IF_OVERWRITTEN  FORCE_OVERWRITE     Result on an overwrite
            off             off             No error
            off             ON              No error
            ON              off             Report an error
            ON              ON              No error

Note that ERR_IF_OVERWRITTEN tags current code to detect _future_ attempts to
overwrite, while FORCE_OVERWRITE affects the code you're assembling right now.

For example, this still generates an error, because the first DECLE was
assembled with ERR_IF_OVERWRITTEN == 1:

        ERR_IF_OVERWRITTEN 1
        ORG     $6000
        DECLE   1234

        ERR_IF_OVERWRITTEN 0
        ORG     $6000
        DECLE   3456

Conversely, this example does _not_ generate an error:

        ERR_IF_OVERWRITTEN 0
        ORG     $6000
        DECLE   1234

        ERR_IF_OVERWRITTEN 1
        ORG     $6000
        DECLE   3456

 

There's lots of neat stuff in the as1600.txt file.  For example, you can add build dates to your program's metadata, so you know, just from looking at the .CFG file, when you built something.

 

I highly recommend every IntyBASIC programmer puts a line like this in their program:

 

 ASM  CFGVAR "build_date" = TODAY_STR_LOC("%Y-%m-%d %H:%M:%S %z")

That'll add the current date and time into the CFG file (or .ROM file metadata).  There's ways to get the current date/time as values as well, from within the assembler.  That makes it possible to expose the values to the game, in case you want it to print that information on-screen, for example.

 

I find that's a huge help when beta-testing games.  "Which version did you test?"  "Uh, I don't know!  It's this ROM.  Which version is it?"  *facepalm*

  • Like 2
Link to comment
Share on other sites

  • 1 year later...
On 12/19/2022 at 8:12 AM, bkumanchik said:

I was setting the dev system up on my Steamdeck and I'm getting this message when trying to run the emulator:

 

./jzintv: error while loading shared libraries: libreadline.so.6: cannot open shared object file: No such file or directory
 

 

thanks for any help, Brian

No need to post the same question in many different places.

 

Please start a new thread.

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