Jump to content

Photo

SAMS usage in Assembly


102 replies to this topic

#76 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Thu Sep 4, 2014 10:19 PM

Rich have you got any docs on those programs? I know of their existence but no nothing of the programs themselves.

Sure here you go but this is not everything he has done. Just most of it.

Attached Files

  • Attached File  RAG.zip   504.73KB   16 downloads


#77 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Thu Sep 4, 2014 10:42 PM

Found some more files not included with those sent already.

 

Attached Files

  • Attached File  RAG.zip   504.73KB   18 downloads


#78 Willsy OFFLINE  

Willsy

    River Patroller

  • 3,088 posts
  • Location:Uzbekistan (no, really!)

Posted Fri Sep 5, 2014 4:46 AM

That has to be one hell of a lot faster then having to fetch values after the XOP. 8 Registers are loaded and ready to execute before I even do the call.

 

Yeah, but you had to load those registers before-hand right? So it seems you're doing the work pre-call rather than post-call. No problem with that at all. Just making the point that the work still has to be done somewhere! ;)



#79 Stuart OFFLINE  

Stuart

    Dragonstomper

  • 808 posts
  • Location:Southampton, UK

Posted Fri Sep 5, 2014 5:05 AM

I would have to disagree with that Stuart.

In RXB I use a command called CALL EXECUTE(cpu-address)

And it is a just a BLWP @cpu-address

 

So what I do is the CPU Workspace is where all the values are loaded before I call that routine. Thus all registers are pre-loaded and ready to go.

 

That has to be one hell of a lot faster then having to fetch values after the XOP. 8 Registers are loaded and ready to execute before I even do the call.

I was talking about the specific case of passing "a parameter" - just *one* parameter. XOP @>1234,R1 where the parameter >1234 is passed in the instruction itself uses one less instruction than having to MOV that parameter somewhere then calling BLWP which then retrieves it. It you want to pass *lots* of parameters, then there is of course no benefit at all.



#80 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Fri Sep 5, 2014 5:14 AM

 

Yeah, but you had to load those registers before-hand right? So it seems you're doing the work pre-call rather than post-call. No problem with that at all. Just making the point that the work still has to be done somewhere! ;)

 

I do after all load all 8 Registers with one move of data, now I suppose you could do the same thing with a CALL LINK but then that would take one hell of a lot more code to do then preloading them.

 

If was just more effective to move 16 bytes with a single RXB CALL MOVES then to keep doing CALL LINKS for them or a single one at a time CALL LINK version.

 

P.S. Never mind just read the second message....


Edited by RXB, Fri Sep 5, 2014 5:14 AM.


#81 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,393 posts

Posted Tue Jun 27, 2017 1:05 PM

As I recently acquired a SAMS card, I'm now thinking I'll change my CRPG to make use of it. I actually don't need a great deal of memory to complete it, most of the game content is still disk-based, but I can utilize some memory-intensive approaches to make the performance better in places.

 

The problem is, I need to actually break my program up into some code segments; just data in extra memory isn't going to be enough. But what platform to do this? I've used A99 to do my compiling into a tagged object format before, but should I be trying to use CSEG and CEND? And I suppose E/A #5 is right out, you'll have to use a custom loader.. I don't mind doing that, I just want to make sure I can compile the segments so they all have the same absolute addressing.

 

I suppose, worst case scenario, I can group together all the shared code and then create different source sets for the different "states" the program is in, compile those, then read in the 8K segments in a custom loader...

 

Has anyone actually used Art Green's assembler and linker for SAMS programming?


  • RXB likes this

#82 Asmusr ONLINE  

Asmusr

    River Patroller

  • 2,946 posts
  • Location:Denmark

Posted Tue Jun 27, 2017 1:39 PM

How much program code do you have, since it's not possible to use SAMS for data only?



#83 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,393 posts

Posted Tue Jun 27, 2017 1:49 PM

At present, around 29k. Some of that is static data.

 

I'm reading up on the linker that Art Green did, with root and overlay segments, I may be able to use that... I was just hoping someone had already made a cross-assembler version of it.



#84 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Tue Jun 27, 2017 8:44 PM

As I recently acquired a SAMS card, I'm now thinking I'll change my CRPG to make use of it. I actually don't need a great deal of memory to complete it, most of the game content is still disk-based, but I can utilize some memory-intensive approaches to make the performance better in places.

 

The problem is, I need to actually break my program up into some code segments; just data in extra memory isn't going to be enough. But what platform to do this? I've used A99 to do my compiling into a tagged object format before, but should I be trying to use CSEG and CEND? And I suppose E/A #5 is right out, you'll have to use a custom loader.. I don't mind doing that, I just want to make sure I can compile the segments so they all have the same absolute addressing.

 

I suppose, worst case scenario, I can group together all the shared code and then create different source sets for the different "states" the program is in, compile those, then read in the 8K segments in a custom loader...

 

Has anyone actually used Art Green's assembler and linker for SAMS programming?

Yea I played around with the RAG GPL Assembler and Linker for about a year. I had a hard time with the oddball syntax he used.

 

I think if you are used to C then it would be a natural fit.



#85 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Tue Jun 27, 2017 8:45 PM

How much program code do you have, since it's not possible to use SAMS for data only?

Why do you say this?



#86 Asmusr ONLINE  

Asmusr

    River Patroller

  • 2,946 posts
  • Location:Denmark

Posted Wed Jun 28, 2017 12:02 AM

Why do you say this?

 

My point is that if he could limit his program to 24K, for instance, then he could use the lower memory area to swap in 2 pages (8K) of data that are stored in SAMS. This is much easier to work with than paged programs, especially if he wants to use a cross compiler. A loader is still require to get the data from disk into SAMS, but that should be relatively easy.



#87 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Wed Jun 28, 2017 12:33 AM

 

My point is that if he could limit his program to 24K, for instance, then he could use the lower memory area to swap in 2 pages (8K) of data that are stored in SAMS. This is much easier to work with than paged programs, especially if he wants to use a cross compiler. A loader is still require to get the data from disk into SAMS, but that should be relatively easy.

LOL you do know this is built into RXB since version 2001?

 

My game IN THE DARK used 336K of SAMS memory.

 

http://atariage.com/...me-in-the-dark/

 

And this game uses XB and Assembly combined. Matter of fact the Assembly is loaded in the UPPER 24K at >B000 to >B200


Edited by RXB, Wed Jun 28, 2017 12:48 AM.


#88 Willsy OFFLINE  

Willsy

    River Patroller

  • 3,088 posts
  • Location:Uzbekistan (no, really!)

Posted Wed Jun 28, 2017 4:04 AM

 
My point is that if he could limit his program to 24K, for instance, then he could use the lower memory area to swap in 2 pages (8K) of data that are stored in SAMS. This is much easier to work with than paged programs, especially if he wants to use a cross compiler. A loader is still require to get the data from disk into SAMS, but that should be relatively easy.


If possible it may be possible to architect the game software such that the 29k or so of data is always accessed at the same 4k address window. Then you're only mapping in 4k of game data at any time, so the rest is free for code. The last 4k of the 8k cpu space would be an ideal place to map it in.

#89 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,393 posts

Posted Wed Jun 28, 2017 10:09 AM

Even though my present codebase is not that large, I still needed a Superspace cartridge to get the RAM I needed. (29k of code/data, and 8k of empty RAM required) So the AMS does benefit, and it also gives me the option to expand and add features.

 

The problem with SAMS development is it's something most 99'ers are not accustomed to, which is module/segment/overlay programming.

 

For example, you have a root module, which ALWAYS exists in memory. So common functions and global variables go there, along with main program control. Then you have to identify your self-contained modules and how much space they need. If need be, you duplicate code functions and data, another practice that we aren't used to, given that memory is usually precious.

 

What Art Green was trying to accomplish was to make it so that you did not have to bake any memory management into your code; instead the linker will add the necessary header data to your program segments and the loader will load them into the respective pages and add control code to them as well so that your program just invisibly switches to the different modules. That would mean you would always need his loaders to load the programs, but a small price to pay. Unfortunately, his AMS assembler and linker appear to be a bit of a mess to figure out. :P So much so that I'd almost rather roll my own. I also don't like compiling on the actual TI (even in emulation) because a cross-assembler works WAY faster.

 

So what I'm going to work on now is to re-architect my source code so that it has four modules including a root module. The other modules are distinct states in the game that cannot overlap each other, so I effectively have three "state" versions of the program. I can compile and create memory image files of all three, and then use a hex editor to copy out the compiled contents to create module files that can be loaded via a custom loader into the AMS memory pages.



#90 apersson850 OFFLINE  

apersson850

    Dragonstomper

  • 524 posts

Posted Thu Jun 29, 2017 9:41 AM

I recognize that issue.

My TI 99/4A has 64 K internal RAM, which is segmented in 8 K banks. Bank switching is via CRU bits. As 64 K is the entire address range of the TMS 9900, this implies that this memory can overlay everything.

When I implemented a RAM disk, with a DSR on my I/O card, I wanted to use all available memory for the RAM disk. That includes console RAM at >4000->5FFF. But since enabling that memory disables the console's capability to access the DSR in the PEB, it took some extra code to fix that. Switching away the memory the current code is running in is the electronic version of suicide.

 

Due to that there are (were) only three consoles I know about with my memory structure, I did of course also have to write my own loader software. I decided not to make my own assembler (which would have been necessary to add directives for bank switching), but instead split it up. If I wanted to assemble code that should be loaded at a "forbidden" place, i.e. where other computers didn't have RAM, I assembled with the .ABSOLUTE and .ORG directives. Then, when running the loader, I had to separately specify which CRU bit to turn on and which file to load with that bit on. To make it easy to use in daily life, when maybe several code segments should be loaded in various memory locations, I made the loader so that I can specify any number of CRU addresses and code files. The loader will then load them all in a sequence. My loader can also save the sequence data in a file, and retrieve and run that file on another occasion. I even automated it in such a way, that when I start the DSRLOADER (I gave it that name, since the first application was to load DSR files in RAM on my own PEB cards), it looks for the file *SYSTEM.LOADER. If it exists, it will run the load sequence stored in that file.

 

Doing it like this made it possible to just turn the 99/4A on, and provided the right diskette was in the first drive, it booted not only the operating system, but also installed the clock and RAM-disk DSR files, set the system date, installed the fourth and fifth drives and copied the system files I mostly benefited from having on the RAM disk without any manual intervention.

 

This has absolutely nothing to do with the SAMS card, but since it's about ways to use more memory than initially thought for this computer, I wrote it anyway. Just disregard if you didn't find anything useful to build on.


Edited by apersson850, Thu Jun 29, 2017 9:47 AM.


#91 Willsy OFFLINE  

Willsy

    River Patroller

  • 3,088 posts
  • Location:Uzbekistan (no, really!)

Posted Fri Jun 30, 2017 9:09 AM

With a "bank stack" you can call code in any bank from any bank. You can either put the bank push and pop routines in pad, or place identical routines at identical addresses in each bank.

http://turboforth.ne...urces/sams.html

Edited by Willsy, Fri Jun 30, 2017 9:10 AM.


#92 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,393 posts

Posted Mon Nov 13, 2017 11:11 PM

An update on this, I do have a working model now. :)

 

I set up batch files to build each of my modules. The "root" module exists in the first 12K of the upper memory, and the latter 12K is swapped out for four different modules.

 

First I wrote an E/A 5 loader program that loads all the program data. I blank the screen and do 12K segment loads of memory images for this. On Classic99 it runs pretty fast, I expect it to probably take a minute or three on the actual TI. (Even WITH the dip switches sent at maximum speed the Corcomp DSDD controller is damn slow...) All memory swaps are handled at the application level; I'm not doing linking commands to mask them.

 

I build a module (which includes 'root' module code as well) using A99 which then creates a 24k tagged object file. I then load this in Classic99 but just let it sit and dump the memory through the debugger. I can then copy and paste the code out from the top 24K into their respective memory image files for loading. Turnaround time isn't QUITE as fast as it would be, I'm considering writing my own cross-assembler in C# to auto-generate the hex code directly for the image files, but I'm happy if I can make progress on the game and not the infrastructure to support the coding of it.

 

Right now I'm working on the "start" module which has the title screen and musical opening, character/game creation, configuration settings management and other things of that nature. Which is actually good; it will help me establish some things like how disk paths will be set up.



#93 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,393 posts

Posted Mon Nov 26, 2018 6:34 AM

Hey all,

 

So I have a new issue. Classic99 now has support for the new 32MB SAMS card that is coming out. But now I have code that breaks in Classic99 and works on my actual hardware SAMS card.

 

Can someone tell me how to write this code so that it works on both systems? What's REALLY strange is I have this exact code in my game loader and it still works fine for both. Maybe the fact the loader is located in low memory helps... as written, this code seems to swap out the page where the code lives.

 

UPDATE: I figured out the problem. Currently Classic99 is hard-coded to use the 32MB version of the card AND it also sets the page for the >A000 block to page 0, instead of page 10 which is what hardware expects. It's a hack in the code at present and probably won't be around long.

       LI   R12,>1E00                  * Set CRU for AMS
       LI   R0,>4000
       CLR  R1
       LI   R2,16
START1 SBO  0                          * Turn on AMS card page mapping
       MOV  R1,*R0+                    * Copy page assignments (0-15)
       AI   R1,>0100                   * Add 1 to each page value
       DEC  R2
       JNE  START1                     * Are we at end of loop?
       SBZ  0                          * Turn off memory page mode
       LI   R12,>1E00                  * Set CRU for AMS
       SBO  1                          * Turn on mapping mode


#94 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Mon Nov 26, 2018 2:15 PM

 

Hey all,

 

So I have a new issue. Classic99 now has support for the new 32MB SAMS card that is coming out. But now I have code that breaks in Classic99 and works on my actual hardware SAMS card.

 

Can someone tell me how to write this code so that it works on both systems? What's REALLY strange is I have this exact code in my game loader and it still works fine for both. Maybe the fact the loader is located in low memory helps... as written, this code seems to swap out the page where the code lives.

 

UPDATE: I figured out the problem. Currently Classic99 is hard-coded to use the 32MB version of the card AND it also sets the page for the >A000 block to page 0, instead of page 10 which is what hardware expects. It's a hack in the code at present and probably won't be around long.

       LI   R12,>1E00                  * Set CRU for AMS
       LI   R0,>4000
       CLR  R1
       LI   R2,16
START1 SBO  0                          * Turn on AMS card page mapping
       MOV  R1,*R0+                    * Copy page assignments (0-15)
       AI   R1,>0100                   * Add 1 to each page value
       DEC  R2
       JNE  START1                     * Are we at end of loop?
       SBZ  0                          * Turn off memory page mode
       LI   R12,>1E00                  * Set CRU for AMS
       SBO  1                          * Turn on mapping mode

I see the problem easy!

 

You should not be able to add a value to the SAMS REGISTERS in DSR space.

 

I have always READ or WRITTEN values, never tried to add or minus from SAMS REGISTERS IN DSR SPACE, as that will crash or at times crash.

(I assume this is a TIMING ISSUE or HARDWARE FAILURE)

 

Thus I have always READ SAMS REGISTERS, modified value and WRITTEN SAMS REGISTERS.

 

Also I NEVER mess with SAMS REGISTERS for pages 0=>0000, 1=>1000, 4=>4000,5=>5000,6=>6000, 7=>7000,8=>8000, 9=>9000 as you are asking for a crash!

(On purpose!)

 

NOTE: In your code after you load >0000 into Register 0 which is at >4000 you load >0400 into Register 4 which is DSR for SAMS??? 

How does the hardware handle that  request?


Edited by RXB, Mon Nov 26, 2018 2:26 PM.


#95 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Mon Nov 26, 2018 2:34 PM

I see the problem easy!

 

You should not be able to add a value to the SAMS REGISTERS in DSR space.

 

I have always READ or WRITTEN values, never tried to add or minus from SAMS REGISTERS IN DSR SPACE, as that will crash or at times crash.

(I assume this is a TIMING ISSUE or HARDWARE FAILURE)

 

Thus I have always READ SAMS REGISTERS, modified value and WRITTEN SAMS REGISTERS.

 

Also I NEVER mess with SAMS REGISTERS for pages 0=>0000, 1=>1000, 4=>4000,5=>5000,6=>6000, 7=>7000,8=>8000, 9=>9000 as you are asking for a crash!

(On purpose!)

 

NOTE: In your code after you load >0000 into Register 0 which is at >4000 you load >0400 into Register 4 which is DSR for SAMS??? 

How does the hardware handle that  request?

 

As Paul Schippnick told me stay away ever writing to anything but Registers 2, 3, A, B, C, D, E, and F in AMS (SAMS) or you will regret results.



#96 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,393 posts

Posted Mon Nov 26, 2018 4:16 PM

I see the problem easy!

 

You should not be able to add a value to the SAMS REGISTERS in DSR space.

 

I have always READ or WRITTEN values, never tried to add or minus from SAMS REGISTERS IN DSR SPACE, as that will crash or at times crash.

(I assume this is a TIMING ISSUE or HARDWARE FAILURE)

 

Thus I have always READ SAMS REGISTERS, modified value and WRITTEN SAMS REGISTERS.

 

Also I NEVER mess with SAMS REGISTERS for pages 0=>0000, 1=>1000, 4=>4000,5=>5000,6=>6000, 7=>7000,8=>8000, 9=>9000 as you are asking for a crash!

(On purpose!)

 

NOTE: In your code after you load >0000 into Register 0 which is at >4000 you load >0400 into Register 4 which is DSR for SAMS??? 

How does the hardware handle that  request?

 

I'm not adding values to the existing registers, that would definitely be a bad idea.

 

This initialization code is on the TI-Tech pages and also in Art Green's documentation. It's necessary to set up the hardware for paging to work; without it, my programs don't page. I've tried it just doing an SBO 1 without any register settings and subsequent attempts to access pages fail.

 

On Classic99, however, you don't need to do this, it will work without it. The only hitch of late is that the current build is set to use the 32mb version of AMS and it sets register >4014 to 0 instead of A. Could I code to do that? Sure. But then it will completely break on hardware if my loaded code is in that page.



#97 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Mon Nov 26, 2018 5:18 PM

 

I'm not adding values to the existing registers, that would definitely be a bad idea.

 

This initialization code is on the TI-Tech pages and also in Art Green's documentation. It's necessary to set up the hardware for paging to work; without it, my programs don't page. I've tried it just doing an SBO 1 without any register settings and subsequent attempts to access pages fail.

 

On Classic99, however, you don't need to do this, it will work without it. The only hitch of late is that the current build is set to use the 32mb version of AMS and it sets register >4014 to 0 instead of A. Could I code to do that? Sure. But then it will completely break on hardware if my loaded code is in that page.

Hmm how do you use the 32 Meg?

 

Normal Registers on SAMS 1 Meg only have values from 4K page 0 to 255 (>00 to >FF) so how the hell do you get above that?

 

Now what was discussed years ago was first byte would be the page from 0 to 255 and second byte was bank 0 to 255

 

So 256 pages times 256 banks would be 65535 divided by 1024 is 64 Meg. Is the 32 Meg version using this concept?

 

i.e.  Page >4014 set to >0A07 would be Page 10 and Bank 7


Edited by RXB, Mon Nov 26, 2018 5:21 PM.


#98 BeeryMiller OFFLINE  

BeeryMiller

    Dragonstomper

  • 733 posts
  • Location:Campbellsburg, KY

Posted Mon Nov 26, 2018 5:35 PM

Jim (or anyone else that can confirm),

 

I got the 1MB SuperAMS 2016 1 Megabyte edition card from Jim at the Chicago show.  It was supposed to have 1 MB ram and is marked 1 Megabyte / 4 Megabyte.  With the discussion of the 32 MB mapping maybe being different, is the memory mapping of this device the same as used for the AMS system by Asgard?  

 

My 99/5C looks like it will be shipping in the next week or so, and I want to make sure I understand the memory mapping correctly.  Since it has 9938 capability, I am going to look at what I can accomplish with the TIPI with the 99/5C to get at least 80 column ANSI capability working with Mass Transfer.

 

Beery



#99 adamantyr OFFLINE  

adamantyr

    Stargunner

  • 1,393 posts

Posted Mon Nov 26, 2018 5:46 PM

Hmm how do you use the 32 Meg?

 

Normal Registers on SAMS 1 Meg only have values from 4K page 0 to 255 (>00 to >FF) so how the hell do you get above that?

 

Now what was discussed years ago was first byte would be the page from 0 to 255 and second byte was bank 0 to 255

 

So 256 pages times 256 banks would be 65535 divided by 1024 is 64 Meg. Is the 32 Meg version using this concept?

 

i.e.  Page >4014 set to >0A07 would be Page 10 and Bank 7

 

Yes, the LSB controls the bank. My code I had some places where I replicated the page # in both bytes, and this caused some problems with the latest Classic99 version until I cleaned it up.

 

I didn't initially the notice the problem with the >A000 block because my game loader doesn't live there; it gets loaded into low memory. So fortunately my development work isn't blocked.

 

I was testing sprite FX and I wanted to see how it looked on the actual TI, so I wrote a test program that required using the AMS in order to ensure the code was as close as possible to the real game. That's how I found the problem. (The sprite FX looks awesome btw.)


  • RXB likes this

#100 RXB OFFLINE  

RXB

    River Patroller

  • 3,420 posts
  • Location:Vancouver, Washington, USA

Posted Mon Nov 26, 2018 6:41 PM

Yea as I use GPL so I can switch any bank in SAMS with no issues at all, thus I can swap out entire 32K and not a single problem.

 

New routines in RXB allows CALL SAMS(address,page) ! Address is 2,3, A, B, C, D, E, F and page can be 0 to 255

 

Example is CALL SAMS(A,124) ! would be address >A000 page 124 (>007C)

 

I guess I an add into RXB 32 Meg version of CALL SAMS(A,124,2) ! would be address >A000 page 124 and bank 2

 

CALL SAMS(A,124) ! would still work as it defaults to what ever bank was previously loaded.

 

How ever if you use it to call multiple banks and multiple pages that is going to require all values used.

 

CALL SAMS(2,78,5,3,79,0) ! This would load address >2000 with page 78 in bank 5 then address >3000 with page 79 in bank 0

 

With a simple CALL LOAD(-31888,0,0,0,0) XB thinks there is no 32K for XB to use and runs from VDP only, thus entire 32K could be for Assembly and XB runs from VDP.

 

I should add RXB allows this and XB would crash, turns out CALL LINK in normal XB thinks no 32K so no CALL LINK allowed, RXB just crashes if no 32K is there as it checks >2000 to see if it works.


Edited by RXB, Mon Nov 26, 2018 6:46 PM.





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users