Jump to content
IGNORED

Tips for mixing assembly with XB


retrodroid
 Share

Recommended Posts

LOL RXB is 27485 lines of code in GPL and Assembly right now and grows each year.

 

Keep in mind GPL is very efficient as a language and requires less code to do same thing as assembly. 

Example IO in GPL uses the TI ROM 0 to do most of the work thus a 7 byte command in GPL would be 400 bytes in Assembly.

So if you turned the GPL into pure Assembly it would be massive.

  • Like 2
Link to comment
Share on other sites

23 minutes ago, RXB said:

LOL RXB is 27485 lines of code in GPL and Assembly right now and grows each year.

 

Keep in mind GPL is very efficient as a language and requires less code to do same thing as assembly. 

Example IO in GPL uses the TI ROM 0 to do most of the work thus a 7 byte command in GPL would be 400 bytes in Assembly.

So if you turned the GPL into pure Assembly it would be massive.

Large parts of FbForth are written in Forth. The Assembler is simply used to "compile" the tokens into the definitions and create the dictionary labels and linked list.

Where GPL tokes are bytes ITC Forth systems use 16 bit addresses, so it does take more space, however the reason that FbForth can fit 505 functions in the kernel is because it's not ALL Assembler code.  :) 

Edited by TheBF
typo
  • Like 5
  • Thanks 1
Link to comment
Share on other sites

4 hours ago, Vorticon said:

As Rasmus mentioned, there is certainly value in the batch assembly process with xas-99, but again that's an advanced usage. 

On a personal level, I prefer to use the simplest and easiest tool available that does what I need it to do. Time in my more mature age has become increasingly valuable 😁

@Graeme Cowie has some kind of set up with Notepad++ in which he can submit his source code to be compiled and loaded into WinUAE/AmigaForever (it featured prominently in his Turbo Sprint development videos.)  I would love to have a similar set up for TI development.

  • Like 1
Link to comment
Share on other sites

10 hours ago, OLD CS1 said:

@Graeme Cowie has some kind of set up with Notepad++ in which he can submit his source code to be compiled and loaded into WinUAE/AmigaForever (it featured prominently in his Turbo Sprint development videos.)  I would love to have a similar set up for TI development.

If Notepad++ has some scripting abilities (and it might based on what you said above), then it may be possible to direct a Classic 99 instance already set up with the TI Assembler cart and relevant disk folders to automatically load and compile a source file generated by Notepad++. TICodEd does something  a little similar by automatically loading your XB compiled file into Classic 99 and running it. It may even be possible to output commands in a command line window to launch xas-99 with appropriate options.

We need an NP++ guru.

PS: I just got an A500 mini and its a blast :) Will be trying to turn it into a full-fledged functional A500. How do you spell NERD again?

  • Like 2
  • Haha 1
Link to comment
Share on other sites

7 hours ago, Vorticon said:

PS: I just got an A500 mini and its a blast :) Will be trying to turn it into a full-fledged functional A500.

The mini is fun, sure, but you will never turn it into a full-fledged functional A500.  If you really think the Mini is fun, get a real A500 and have real fun.  You kids these days have it too easy with your FPGAs and USB floppy emulators.

7 hours ago, Vorticon said:

How do you spell NERD again?

Sure are a lot of 'em around here.

 

3 hours ago, jedimatt42 said:

I like to remember it as NERC + 1

What if C-A-T really spells "dog?"

  • Haha 2
Link to comment
Share on other sites

I was able to successfully assemble the "gameLoop" code from the "Assembly on the TI99/4A" thread using win994a, and got it running using E/A 3. 

Then I messed around a bit to see what quick hacks I could make. The first one was to remove the "only update one character per VSYNC" so I could see what full speed looked like. 😎

Next I made it so it would update the entire screen sequentially, left-to-right, top-to-bottom using the same colour, switching colours each time it had completed a full screen's worth.  Using that I did some manual timings and it seems we can replace all 768 chars on the screen in approx. 460ms (doing it one char at a time, mind-you).

 

Based on the good advice above, I hunted down the xdt99/xas99 assembler.  What a revelation! Now I can code AL (or XB) using the free version of IntelliJ directly on my M1 Mac, including IDE plugin.  Sweet!

 

Currently I have both my .asm source file and .obj assembler output stored directly in my classic99 "DSK2" folder, under my WINE "drive_C" folder.  This seems to work fine, I edit the  code, press Build in IntelliJ and my mini script runs the assembler. Then all I have to do is reboot classic99 and Load and Run in E/A 3. Any potential issues with this approach?

 

I'm about half-way done the "Assembly on the TI99/4A" thread. The first 10 pages or so are a wonderful resource for new AL programmers.  After that things get a bit esoteric for a newbie like myself.  


Now I'm looking for some examples of AL games that illustrate some good approaches to managing enemies of varied type/capability/number per screen. Does anyone have any good reference AL game code they could point me at, beyond the examples in the "Assembly..." thread?

 

Many thanks for the tips so far guys! It's been a lot of fun exploring this frontier and discovering the vast resources created by others along the way, sometimes decades prior. 

 

Edited by retrodroid
  • Like 5
Link to comment
Share on other sites

7 hours ago, retrodroid said:

Now I'm looking for some examples of AL games that illustrate some good approaches to managing enemies of varied type/capability/number per screen. Does anyone have any good reference AL game code they could point me at, beyond the examples in the "Assembly..." thread?

All games are different, but I would usually define a data structure for each enemy, which is just a list of equates, e.g:

enemy_type:
         equ 0
enemy_y:
         equ 2
enemy_x: 
         equ 4
enemy_vx:
         equ 6
enemy_vy:
         equ 8
enemy_status:
         equ 10
enemy_props:
         equ 12
enemy_struct_size:
         equ 14

For this data structure I would allocate 14 bytes for each enemy. If I then have a pointer to an enemy in r1, for instance, I can use indexed addressing to access each field, e.g.:

       a @enemy_vx(r1),@enemy_x(r1)

Note that I don't keep a reference to which hardware sprite each enemy if represented by. Instead I rewrite the entire sprite attribute list in VDP RAM each frame by iterating through the enemy list and generating attributes for the visible enemies. (I also generate attributes for other sprites, of course, like you main character, bullets/shots, etc.) That makes it easy to implement a sprite rotation scheme if you have more than 4 sprite on a line.

  • Like 3
Link to comment
Share on other sites

13 hours ago, Asmusr said:

All games are different, but I would usually define a data structure for each enemy, which is just a list of equates, e.g:

enemy_type:
         equ 0
enemy_y:
         equ 2
enemy_x: 
         equ 4
enemy_vx:
         equ 6
enemy_vy:
         equ 8
enemy_status:
         equ 10
enemy_props:
         equ 12
enemy_struct_size:
         equ 14

For this data structure I would allocate 14 bytes for each enemy. If I then have a pointer to an enemy in r1, for instance, I can use indexed addressing to access each field, e.g.:

       a @enemy_vx(r1),@enemy_x(r1)

Note that I don't keep a reference to which hardware sprite each enemy if represented by. Instead I rewrite the entire sprite attribute list in VDP RAM each frame by iterating through the enemy list and generating attributes for the visible enemies. (I also generate attributes for other sprites, of course, like you main character, bullets/shots, etc.) That makes it easy to implement a sprite rotation scheme if you have more than 4 sprite on a line.

Interesting. Such a different mindset than XB.  

 

13 hours ago, Asmusr said:

The source code for several of my games is available here: https://github.com/Rasmus-M?tab=repositories.

This is an amazing resource.  Would you mind if I "clone" your Tix project structure and build file, etc. for my project?

My game is sufficiently different from yours but I really like how you've organized things.

 

Edited by retrodroid
Link to comment
Share on other sites

On 12/14/2022 at 3:15 PM, retrodroid said:

Anyway, I was wondering if anyone could provide advice on the way to proceed with this approach?  I assume the TI Editor/Assembler should be used to develop the main game loop function?  Any tips or tricks in terms of what my development cycle will look like with the hybrid approach?  Any existing games with source code available that could act as references to how it is done, etc.?

 

I like things to be simple, and sometimes the 99/4A is not that when it comes to the way TI engineered the software layers (very much like a minicomputer, surprise!)

 

For a few mixed XB and assembly examples, I helped Owen twice with some of his projects.  One was a sound player, the other a map scroller.  The assembly routines gave the needed performance to give XB a little extra kick.  Both have their own threads in the forum, but the map scroller is wholly contained in this post:

 

https://forums.atariage.com/topic/171780-assembly-xb-link-project/page/8/#comment-2152895

 

On pg. 8, a little way down (still annoying that the post numbers are gone after the forum update).  Values are passed to/from XB and assembly in a very minimal way.

 

Owen used these in two XB games he was working on, both are threads in the forum.  One was something like Lemonade Stand, IIRC.  The other was Berrly Reicht (or some spelling thereof).

 

Edited by matthew180
  • Like 2
Link to comment
Share on other sites

On 12/19/2022 at 3:02 PM, matthew180 said:

 

I like things to be simple, and sometimes the 99/4A is not that when it comes to the way TI engineered the software layers (very much like a minicomputer, surprise!)

 

For a few mixed XB and assembly examples, I helped Owen twice with some of his projects.  One was a sound player, the other a map scroller.  The assembly routines gave the needed performance to give XB a little extra kick.  Both have their own threads in the forum, but the map scroller is wholly contained in this post:

 

https://forums.atariage.com/topic/171780-assembly-xb-link-project/page/8/#comment-2152895

 

On pg. 8, a little way down (still annoying that the post numbers are gone after the forum update).  Values are passed to/from XB and assembly in a very minimal way.

 

Owen used these in two XB games he was working on, both are threads in the forum.  One was something like Lemonade Stand, IIRC.  The other was Berrly Reicht (or some spelling thereof).

 

Thanks for the information.  I have to admit there is a certain attraction in the difficulty of accomplishing this (XB-assembler integration). However, for my current project I'm all-in on a pure AL implementation. It doesn't gain anything from including XB at this point, and will actually be far simpler without it. 

 

BTW thanks for putting together the "Assembly on the 994a" thread 12 years ago. lol.  I'm finding it very informative and helpful.  

 

  • Like 1
Link to comment
Share on other sites

On 12/19/2022 at 5:02 PM, matthew180 said:

For a few mixed XB and assembly examples, I helped Owen twice with some of his projects.  One was a sound player, the other a map scroller.  The assembly routines gave the needed performance to give XB a little extra kick.  Both have their own threads in the forum, but the map scroller is wholly contained in this post:

 

https://forums.atariage.com/topic/171780-assembly-xb-link-project/page/8/#comment-2152895

 

I read through this thread.  Very informative.  Side note:  you never know what post will end a thread...in this case it was an enthusiastic shout-out to the McGriddle!

Link to comment
Share on other sites

I noticed that the Magellan -> Export -> Assembly Data -> RLE Compress Maps only supports up char 127.  Can someone share why that is?

 

I wrote a little RLE byte compressor to see how my map data would benefit and it reduces my maps to anywhere from 60% of the original size to only 20% of original size, a huge savings.

Ideally, I'd like to leverage the wonderful Magellan tool fully and have it produce my RLE compressed map data, but ran into this limitation.

 

Edited by retrodroid
Link to comment
Share on other sites

31 minutes ago, TheBF said:

It seems that other's have needed such a thing. Here's one for ARM that gives some ideas.

Yes, something like this. So I don't have to look up for each line if I can use the increment + or other variants of a command. Actually I am working my way through Matthews "Assembly on the 99/4a" and need to look up some of the opcodes in the examples, but once I start coding myself, a "onepager" might be supportive to my limited mind... I used the XB Reference Card a lot, BITD and still today. Who doesn't confuse CALL POSITION with CALL LOCATE sometimes. Or is it just me?

Link to comment
Share on other sites

3 minutes ago, SteveB said:

I might find the time to compile a list in the next days, which might be a good exercise for a novice, but would need some proof-reading from an expert. 

 

No prob. I can certainly be one pair of eyes. I may be just shy of “expert”, however. :ponder:

 

...lee

  • Haha 1
Link to comment
Share on other sites

2 hours ago, SteveB said:

Yes, something like this. So I don't have to look up for each line if I can use the increment + or other variants of a command. Actually I am working my way through Matthews "Assembly on the 99/4a" and need to look up some of the opcodes in the examples, but once I start coding myself, a "onepager" might be supportive to my limited mind... I used the XB Reference Card a lot, BITD and still today. Who doesn't confuse CALL POSITION with CALL LOCATE sometimes. Or is it just me?

Pixelpenant made a video talking about this issue in XB games with CALL COINC.

So I created a new RXB command

CALL COLLIDE(#sprite,#sprite,tolerance,return-dot-row,return-dot-column)   

! does what CALL COINC & CALL POSITION in one command for sprite hitting sprite.

CALL COLLIDE(#sprite,dot-row,dot-column,tolerance,return-dot-row,return-dot-column) 

! does what CALL COINC & CALL POSITION in one command for sprite hitting a location.

 

I fix problems, not work around them.

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

  • Recently Browsing   0 members

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