Jump to content
IGNORED

Supernotes


GDMike

Recommended Posts

1 hour ago, Asmusr said:

If you want to copy 2K of data to VDP RAM >1000.

li r0,>1000
li r1,address in CPU RAM
li r2,>800                       ; 2K
bl @vmbw                         ; Or blwp, depending on which version of the VDP functions you use

 

And if you want to play inter-actively with VMBW and VMBR to get a quick feel for them, they are in all of the TI-99 Forth systems.

(I called mine VWRITE and VREAD but I renamed them for the demo code)

 

So to do what @ASMUSR shows in Assembler you would do with the statements in the spoiler in Camel99 Forth.

 

The three parameters that go into registers R0,R1,R2  in ALC come from the data stack in Forth.

To see your results use DUMP and VDUMP or even simpler use the Classic99 debugger to examine memory. 

 

Example for Camel99 Forth but it's similar for whatever system you use.

VMBR example is reading VDP -> PAD which is free memory past the end of Forth)

Spoiler
NEEDS DUMP  FROM DSK1.TOOLS 

: VMBW ( src Vdst len -- )  VWRITE ; 
: VMBR ( Vsrc dst len -- )  VREAD ; 

HEX
A000 1000 400 VMBW

1000 PAD 400 VMBR

 

image.png.9f0ab3f384cda4ff80496d5a6d97fd69.png

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

Maybe I'm confusing myself. Im thinking i cannot access CPU ram directly and so I thought VDPWA has to be pointed to prior to using VDPWR in order to get to CPURAM data. 

Well,. I'm confused because I've never used this VDPWA before..so ok.  Im ok with the way I've been doing it then with VMBW...ok

Link to comment
Share on other sites

23 minutes ago, GDMike said:

Maybe I'm confusing myself. Im thinking i cannot access CPU ram directly and so I thought VDPWA has to be pointed to prior to using VDPWR in order to get to CPURAM data. 

Well,. I'm confused because I've never used this VDPWA before..so ok.  Im ok with the way I've been doing it then with VMBW...ok

I think I see what's going on. 

You are confusing VDP port addresses like VDPWA with code routines.

 

Just for a quick review:

  1. The CPU can only "get at" the VDP memory through a few magic addresses in the CPU RAM space called "ports"
    1. Ports are "windows" in the CPU RAM that connect to a piece of hardware.
       
  2. The addresses of those ports are >8800, >8802, >8C00 and >8C02 
     
  3. You can use those addresses as numbers but a common practice is to "name" those numbers using EQU
    1. If you use EQU the program doesn't change, but we can remember the names easier than the HEX numbers
       

Common names used for these ports are what you already know:

8800 -> VDPRD               \ vdp ram read data port
8802 -> VDPSTS              \ vdp status port
8C00 -> VDPWD               \ vdp ram write data port
8C02 -> VDPWA               \ vdp ram read/write address port 

 

You NEVER need these addresses if you use CODE routines that someone else has written like VMBW, VMBR, VSBW and VSBR. 

The addresses are baked into those code routines. 

 

Does that help?

  • Like 2
Link to comment
Share on other sites

Yes. That's what I was confused about.

Thx. And so when Lee said just use vmbw, etc.. because he knows I'm in the EA routines.

I saw Lee was using that in something he put together for me and so I was questioning myself that maybe I'm not moving data to and from CPUram correct.

And then I remembered seeing these VDPRD, VDPWD in the book, but I've never used them 

Even though I was moving data previously just fine with VMBW etc..

So I thought I'd ask about their use.

 

 

  • Like 3
Link to comment
Share on other sites

Well, I suppose we'll wrap up SNP and call it done and next i will start dipping back into forth again, I think...as I'm still trying to decide. And if I choose forth, then I need to choose the flavor, helping me will depend on wether or not my access to>6000->7FFF will be something I need. But it's probably not because I've already chosen to use TIPI and SAMs, so really, what advantage would I get from>6000->7FFF when SAMS is here.

 

So next is flavor?? I've already been dipping in TF and a bit of FB and CF, so what's the benefits from each. Well, I know how SAMs works in TF and I'm comfortable with it, along with a bunch other stuff, like sounds.

So I'm ok with sticking to it.

 

 

Edited by GDMike
  • Like 1
Link to comment
Share on other sites

1 hour ago, GDMike said:

Well, I suppose we'll wrap up SNP and call it done and next i will start dipping back into forth again, I think...as I'm still trying to decide. And if I choose forth, then I need to choose the flavor, helping me will depend on wether or not my access to>6000->7FFF will be something I need. But it's probably not because I've already chosen to use TIPI and SAMs, so really, what advantage would I get from>6000->7FFF when SAMS is here.

 

So next is flavor?? I've already been dipping in TF and a bit of FB and CF, so what's the benefits from each. Well, I know how SAMs works in TF and I'm comfortable with it, along with a bunch other stuff, like sounds.

So I'm ok with sticking to it.

 

 

TF is fine system. If I get some ambition I might be able to migrate some of the size reductions I found for SAMS colon definitions back into Mark's code.

I just need to change a bit of the assembler code to use TF stack usage I think.

That would let you cram more stuff into your program

 

And truth be told if there is something you find in one system that TF doesn't have, somebody around here could port it over probably.

For example I ported the cooperative multi-tasker to FbForth. Would not take much more effort to move it to TF is you wanted to expand your mind in that direction. :) 

 

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

On 9/11/2022 at 10:38 AM, GDMike said:

Download available here for those wanting to try it out.

 

SNP 74.88 kB · 5 downloads

When I tried to run your latest version, all I got was this...

 

image.thumb.jpeg.ce7d3741a71699a08aa108bbaeaee26f.jpeg

 

...after about an hour of debugging, I identified the offending code:

 

image.thumb.jpeg.01dc3a93e7b79aca1363491107613e39.jpeg 


...and bypassed.

 

image.thumb.jpeg.28ce3ff05d6b4171e8d0752ed80e8a45.jpeg

 

Now-I-find that the joke is on me!


I'd taken my F18A, to the kitchen, to have it cleaned. Apparently, the dish-washer, placed it in the utensils' draw!

Not 'til brunch, was it returned.:roll:

 

image.thumb.png.7b572c6748ba8752703fd376e1f12e3d.png

 

...Good help is priceless!;)

 

image.thumb.jpeg.00a2cb4137ff3ba8ec935da7a54cd010.jpeg

;-)

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

7 hours ago, TheBF said:

TF is fine system. If I get some ambition I might be able to migrate some of the size reductions I found for SAMS colon definitions back into Mark's code.

I just need to change a bit of the assembler code to use TF stack usage I think.

That would let you cram more stuff into your program

 

And truth be told if there is something you find in one system that TF doesn't have, somebody around here could port it over probably.

For example I ported the cooperative multi-tasker to FbForth. Would not take much more effort to move it to TF is you wanted to expand your mind in that direction. :) 

 

Right. With you, Lee and Mark, I think anything is possible. :)

 

 

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

  • 1 month later...

I may have mentioned this before but I wanted to see if I can get further than I have in the past with This item.

Currently, in SNP, I have a statement that runs at assembly time.

As this:

AORG >3000

COPY "dsk#.mems" (code+resolved references+data).

 

This places code directly into my unmapped lower ram.

Then at runtime and early in the process, I push that 2000 bytes of code into a high SAMs page.

 

But because I can only do this once at assemble time AND < 4K so I was looking for another way to do this BUT I need to pass, let's say, another 64K of code into SAMs banks.

 

I can only think of writing multiple DEFS of the early routine that I currently have and just calling them one after another at run time, in which one runs and pushes code to a bank then exits and continuing to run through a stack of similar processes.

I haven't done this yet, but was thinking this might be (if it even works) the only other way. Has anyone tried pushing raw code that can be executed after page change like this?

I do have my original code of 2K working the way I explained in the beginning and it's very effective.

But I'm thinking about coding on a larger scale.

Note: I'm in my phone as usual and can't easily place my code that I currently have.

If I need to, then Id have to make that a special thing. But I can later if needed. 

I also thought about (on real hardware), running multiple programs that just push code into SAMs banks one after another because as Long as the PEB stays powered then that RAM remains until I can load my actual program that can access that multipe bank code. 

Just a thought..

 

 

 

Edited by GDMike
Link to comment
Share on other sites

Not sure I understand you completely, but it sounds like you want to make a system to have a bunch of callable code in multiple SAMS pages.

Not an assembler expert but I don't think REF DEF is the way to go.

 

I think you need a system to organize the code for your program's usage rather than the assembler.

Something like the way TI lets us link to code in different cards might work but using numbered sub-routines for simplicity.

Think of each SAMS page as "card" that appears at >3000.

 

Something like:

  1. All CODE pages will map into >3000
  2. All code pages have a table of addresses at the top that you treat like an array of entry points for sub-routines
  3. The sub-routines can be accessed by number from 0 to 20. (numbers are simpler that using text names to search through) 
  4. Write a group of useful subroutines and DOCUMENT the input and output register arguments. (it would be easier with a stack) :) 
  5. Assemble all the sub-routines that fit in 4K and put the labels in the table (group them by function type?) 
    1. document the number used to call each sub-routine for that 4K page.
    2. assign and document a SAMS page number for this block of sub-routines
    3. Do this for as many 4K code pages as you need. 

 

* code page example

	AORG >3000

SUBTAB	DATA SUB0,SUB2,SUB4,SUB6,
	DATA SUB8,SUB10,SUB12,SUB14,  
	DATA  0000,0000,0000,0000,
	DATA  0000,0000,0000,0000,
	DATA  0000,0000,0000,0000,


SUB0	CODE...
	...
      RT 

SUB2	CODE...
	...
	...
	...
	RT

SUB4	CODE...
	...
      RT 


ETC...

 

At startup your program must map in a SAMS page to >3000 then load a code file to >3000.

Do this for as many code pages as you have.

 

To call a program you need 2 parameters: ( SAMS_page_number, subroutine#)

SUBTAB	EQU >3000

	LI R0,>10      SAMS page #
	BL @MAP
	LI R1, 4       subroutine numbers are even 0 2 4 6 8 
	BL @SUBTAB(R1) call the routine at table entry 4 

 

Apologies if the syntax is wrong but it shows the concept.

  • Like 3
Link to comment
Share on other sites

That's all good, I guess my question is more of a problem for me.

How to assemble code And push that code to SAMs pages.

Because the mapper can't run during assembly.

And even if I assemble my code separately, let's say, well. I've still got a problem getting the mapper running and then moving the code.

 

While Forth, on the other hand can do that, since the assembler runs or can run after the mapper is set .

I could (lol)...write  code better and i won't need to push other code. OR do everything in forth. 

I was just looking for another way to read the source and moving what I'd like over to SAMs.

I don't have Any code anyway, but I was pondering this after finding a way to move 4K and testing it successfully.

Thx

 

 

Link to comment
Share on other sites

21 minutes ago, GDMike said:

That's all good, I guess my question is more of a problem for me.

How to assemble code And push that code to SAMs pages.

Because the mapper can't run during assembly.

And even if I assemble my code separately, let's say, well. I've still got a problem getting the mapper running and then moving the code.

 

While Forth, on the other hand can do that, since the assembler runs or can run after the mapper is set .

I could (lol)...write  code better and i won't need to push other code. OR do everything in forth. 

I was just looking for another way to read the source and moving what I'd like over to SAMs.

I don't have Any code anyway, but I was pondering this after finding a way to move 4K and testing it successfully.

Thx

 

 

Yes, your program needs a MAP routine which is not difficult and it needs a way to load binary files into memory.

The simplest way to load binary files is with file function 5 which I think you are using now to save files. (?) 

And you need a program to convert the "code page" object files to binary files that can be loaded with function 5.

I think there is a SAVE utility on the E/A disks that could do this.  

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

Another way to go...

 

Write a small stub program, to load and run your code...

It could...

 

Switch pages, call the @LOADER(load some of your code), switch pages, reset the load vector, call the @LOADER(load more code), repeat, repeat, switch pages, execute your entry address.

 

This way you can use RELOCATABLE code, and trick the loader into resolving the relative addresses, should you find it necessary to load your code to a different address range.

 

...You would have to keep track of available space, or save/restore the first and last available addresses.

 

..did I already mention this?:ponder:

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

If you would store code segments in SAMS, you reasonably store them in 4K banks. When loading, you have to have a loader that loads the appropriate code in the intended bank.

To run them later, you only need to select the bank and branch to the code.

One can do this very fixed, with memory image files (which per definition are absolute) to store in different memory segments, or very flexible, with relocatable code that can be stored in such segments or anywhere else, to be tested. A table of labels to call and bank numbers to switch to, and that's flexible too.

  • Like 1
Link to comment
Share on other sites

12 minutes ago, apersson850 said:

If you would store code segments in SAMS, you reasonably store them in 4K banks. When loading, you have to have a loader that loads the appropriate code in the intended bank.

To run them later, you only need to select the bank and branch to the code.

One can do this very fixed, with memory image files (which per definition are absolute) to store in different memory segments, or very flexible, with relocatable code that can be stored in such segments or anywhere else, to be tested. A table of labels to call and bank numbers to switch to, and that's flexible too.

Right. This I've managed to do, but it was a one-time shot and only at assembly time and I only had 2K of the 4K( but that doesn't matter as. Long as I'm under 4K).

 

I know that there's a "LOADER" call in the Editor Assembler book. I just don't know how to use that. (Nothing abnormal there), but I did TRY that option once, but my code pushed ended up as ASCII (the way it looked to the assembler) even after I assembled.  it was assembled and on disk.

So that didn't pan out for me.

 

As a test now:

Currently  I'm writing a program that lets me move 200 bytes consecutively as "AB" into the EVEN SAMs "pages" and "CD" into the ODD SAMs pages  starting with "pages"  >1000 and ending at >D000 mapped as >3000 in classic99.

Then the program goes back and reads each and displays it to the screen. This is a test to show that my mapper is working by keying thru the "pages".

I've got to get that settled first.

This is because I'm not sure what's in the pages by just using the classic 99 debugger.

I know this is a long way off from what I'm eventually trying to achieve, but it's my starting point.

So I think from what I'm hearing, is that it's probably best to compile standalone code with the assembler, and build a "LOADER".. because at the time a loader is called by my program the mapper is already running and mapping where the file data goes would be simple.

Of course I'd definitely know which bank it's going to by my control.

I guess I'd have to revisit the "LOADER" again and figure that out as my solution.

Thx so much.

 

 

 

 

 

 

Link to comment
Share on other sites

1 hour ago, HOME AUTOMATION said:

Another way to go...

 

Write a small stub program, to load and run your code...

It could...

 

Switch pages, call the @LOADER(load some of your code), switch pages, reset the load vector, call the @LOADER(load more code), repeat, repeat, switch pages, execute your entry address.

 

This way you can use RELOCATABLE code, and trick the loader into resolving the relative addresses, should you find it necessary to load your code to a different address range.

 

...You would have to keep track of available space, or save/restore the first and last available addresses.

 

..did I already mention this?:ponder:

Yes hahaha.. you did..I just couldn't figure out the loader.  Hahaha.. I knew I had tried this a year ago I think. . anyway, the loader, the way I had it, was reading ASCII assembled code..I couldn't get the loader to read binary code File...

 

  • Thanks 1
Link to comment
Share on other sites

36 minutes ago, GDMike said:

Right. This I've managed to do, but it was a one-time shot and only at assembly time and I only had 2K of the 4K( but that doesn't matter as. Long as I'm under 4K).

 

I know that there's a "LOADER" call in the Editor Assembler book. I just don't know how to use that. (Nothing abnormal there), but I did TRY that option once, but my code pushed ended up as ASCII (the way it looked to the assembler) even after I assembled.  it was assembled and on disk.

So that didn't pan out for me.

I think what you got from the assembler is OBJECT file format, Display Fixed 128 format. 

You can convert that to binary with the SAVE utility which is the way to go because you can load 4K of binary in less than 1/2 a second.

So even if you had 10 pages of SAMS code it would load up very quickly. 

So after you have assembled all your code pages, you need to convert them all. It's a little cumbersome.

I think with my LINKER I could make a utility in Forth to batch link them and save them as binary in script. 🙂

 

  • Thanks 1
Link to comment
Share on other sites

42 minutes ago, TheBF said:

I think what you got from the assembler is OBJECT file format, Display Fixed 128 format. 

You can convert that to binary with the SAVE utility which is the way to go because you can load 4K of binary in less than 1/2 a second.

So even if you had 10 pages of SAMS code it would load up very quickly. 

So after you have assembled all your code pages, you need to convert them all. It's a little cumbersome.

I think with my LINKER I could make a utility in Forth to batch link them and save them as binary in script. 🙂

 

It was display fixed 80 but ASCII and I guess the loader inside the EA software converts it?? I'm guessing here... because both files, the source AND the object code are Still readable through the ea editor. Just my guess on things..

Also I noticed that when I use clasic99 and check sam's memory, I'm not seeing the data i put in banks. But my test of my program verified that the data is definitely in the banks. I'm using the latest version of classic 99.

That's what prompted me to write this verifier routine..

Thx

Link to comment
Share on other sites

Standard object code is in readable ASCII. That's the way it's supposed to be.

Compressed object code is partially ASCII, partially binary code. Thus the loader has less to translate before loading, and less file space is needed.

The standard LOADER, which is a part of the utilities loaded by the Editor/Assembler module, is designed to load relocatable code first in 24 K RAM, then in 8 K RAM. To load code into specific SAMS pages, it's probably best to assemble it as absolute code instead. That way you don't have to mess with the memory pointers the LOADER manages to place relocatable code correctly. To load such a file the sequence would be

 

  1. Set up a PAB with the proper filename in OPEN mode.
  2. Set the PAB pointer.
  3. Select the desired SAMS page.
  4. Call LOADER.
  5. Close the file.

 

Then repeat for all files.

This would work for testing. You can then create a program which saves these code segments in their memory banks as image files, and finally write your own image file loader, to quickly put them in SAMS memory. You only need to implement the image file transfer (a simple DSRLNK call with the right PAB parameters) in assembly. Creating the files can then be done from BASIC, with that as support.

 

Piece of cake, really.

Edited by apersson850
  • Like 1
Link to comment
Share on other sites

10 minutes ago, GDMike said:

It was display fixed 80 but ASCII and I guess the loader inside the EA software converts it?? I'm guessing here... because both files, the source AND the object code are Still readable through the ea editor. Just my guess on things..

Also I noticed that when I use clasic99 and check sam's memory, I'm not seeing the data i put in banks. But my test of my program verified that the data is definitely in the banks. I'm using the latest version of classic 99.

That's what prompted me to write this verifier routine..

Thx

Yes the loader "links" the object code and loads it at the same time.

 

To see SAMS memory in Classic above 64K (FFFF) you need to use an extended address with extra digits. (4 HEX digits can only go to 65,535 bytes) 

A way to think about it is, there are 16, 64k segments in a 1M card.

 

To see the 1st page above 64K press the AMS button and enter: 10000.  That's page >10 

To see the next 4K page enter:  11000 (page >11)

To see the 3rd page               :  12000 (page >12) 

etc.

 

  • Like 1
Link to comment
Share on other sites

8 minutes ago, TheBF said:

Yes the loader "links" the object code and loads it at the same time.

 

To see SAMS memory in Classic above 64K (FFFF) you need to use an extended address with extra digits. (4 HEX digits can only go to 65,535 bytes) 

A way to think about it is, there are 16, 64k segments in a 1M card.

 

To see the 1st page above 64K press the AMS button and enter: 10000.  That's page >10 

To see the next 4K page enter:  11000 (page >11)

To see the 3rd page               :  12000 (page >12) 

etc.

 

Oh? I was looking for SAMs >1100, >1200 for the 2 pages I placed data in. When I looked at>3000 SAMs I saw that blank out as I was pushing data...I'll have to try that larger address of >10000

And>11000 then and see. Ty.

Well, my son wants me to go to the store and get our Thanksgiving stuff. So I guess I'm done here today.

 looks like I've got a direction and it's looking like it's going towards a loader + PAB setup, reader loader.

But that has to wait until I figure a method of compiling absolute code into a format that will work.

 

Link to comment
Share on other sites

Exactly. The object code is a more or less direct representation of the binary code to load in memory.

 

Absolute code is exactly that. Each byte is represented "as-is", and just converted from readable text to binary representation. This conversion is different depending on if the object is standard type (all readable text) or compressed (where the data content is already converted).

The code also has tags. There is one tag for each word, describing what it contains. If the code is absolute, the tag always says "load this word as it is", since in absolute code all addresses are already resolved. Absolute code only works if it's loaded in one specific place in memory.

 

Relocateable code can be placed anywhere in memory at load-time. The format is the same, but there are tags both for "load this word as it is" and "load this word as a relocatable address". Some addresses doesn't need relocation, as they are relative. All JMP instructions are like that. But if your code contains branch instructions (B or BL) or accesses data with direct memory addresses (MOV @ADDRESS,R1), then the loader needs to figure out what to replace the ADDRESS word with. When you write the assembly program, you can define a label (ADDRESS DATA 1234) and refer to that data with the name ADDRESS. The assembler will generate code which keeps track of how far from the beginning of your program ADDRESS is located. If it's 50 words from the beginning of the program, it will assemble references to ADDRESS as 50 and tag that value as relocateable. When the loader then is running, it keeps track of where it started to load the program in memory. If that is at address 10000, then the relocatable address 50 will be replaced by 10050, and this value will be loaded in memory. At another time your program is perhaps loaded at 12400, in which case the address resolves to 12450.

Yet another tag can be a definitiion (DEF) of an external label. When the loader encounters such a tag, it will take the name of the label and the current loading address (i.e. where this label actually ended up in memory this time) and place this data in the REF/DEF table.

In that table it sits handy if you load yet another file with the loader, where there is an external reference tag to that same label. The loader will then locate the definitiion i the REF/DEF table and replace the reference to the external label with the address from the table.

The ability to do this is why it's called a linking loader. It can link different code segments together, where one segment REFerences a DEFinition in the other. The only requirement is that the DEFinition is loaded first.

 

  • Like 3
Link to comment
Share on other sites

On 11/14/2022 at 6:54 AM, GDMike said:

I may have mentioned this before but I wanted to see if I can get further than I have in the past with this item. Currently, in SNP, I have a statement that runs at assembly time as this:

AORG >3000

COPY "dsk#.mems" (code+resolved references+data).

 

This places code directly into my unmapped lower ram. Then at runtime and early in the process, I push that 2000 bytes of code into a high SAMs page. But because I can only do this once at assemble time AND < 4K so I was looking for another way to do this BUT I need to pass, let's say, another 64K of code into SAMs banks.

 

           <snip>

 

One way to achieve your goal involves using @ralphb’s xas99 assembler. You can put all of your code for each SAMS page into one file just as I do for fbForth cartridge banks. The code for each page needs to be self-contained and use unique labels within the library file, but, because we are assembling this library independent of the rest of the program code, we do not need to worry about label collisions outside of the library. Any external references to code in other parts of memory should be in EQUates. The following code includes five sample SAMS page stubs (banks 0 – 4), with the overlay number and SAMS page to use at the very end of each page (>3FFC – >3FFF). AORGing these values to >3FFC ensures each overlay will occupy exactly >4KiB and that we know exactly where that overlay number and SAMS page are located.

 

Source code:

Spoiler
***********************************************
* Program: LIB3000
*
* Test of multiple program overlay blocks all
* running from low RAM at >3000->3FFF 
*

* EQUates for references external to this 4KiB block of RAM
*
KSCAN  EQU  >2108

* Start of 4KiB RAM blocks all destined for >3000->3FFF
*
***********************************************
* OVERLAY 000:
*
       BANK 0, >3000
OVLY00 MOV  R0,R0       ; first instruction
       
       RT

       AORG >3FFC       ; last 2 words in this 4KiB RAM block
OVERLAY_00              ; xas99 labels are not limited to 6 chars
       DATA >0000       ; overlay number
SM00F0 DATA >F000       ; SAMS page to store this RAM block

***********************************************
* OVERLAY 001:
*
       BANK 1
OVLY01 MOV  R0,R0       ; first instruction
       
       RT

       AORG >3FFC       ; last 2 words in this 4KiB RAM block
OVERLAY_01              ; xas99 labels are not limited to 6 chars
       DATA >0001       ; overlay number
SM00EF DATA >EF00       ; SAMS page to store this RAM block


***********************************************
* OVERLAY 002:
*
       BANK 2
OVLY02 MOV  R0,R0       ; first instruction
       
       RT

       AORG >3FFC       ; last 2 words in this 4KiB RAM block
OVERLAY_02              ; xas99 labels are not limited to 6 chars
       DATA >0000       ; overlay number
SM00EE DATA >EE02       ; SAMS page to store this RAM block

***********************************************
* OVERLAY 003:
*
       BANK 3
OVLY03 MOV  R0,R0       ; first instruction
       
       RT

       AORG >3FFC       ; last 2 words in this 4KiB RAM block
OVERLAY_03              ; xas99 labels are not limited to 6 chars
       DATA >0003       ; overlay number
SM00ED DATA >ED00       ; SAMS page to store this RAM block

***********************************************
* OVERLAY 004:
*
       BANK 4
OVLY04 MOV  R0,R0       ; first instruction
       
       RT

       AORG >3FFC       ; last 2 words in this 4KiB RAM block
OVERLAY_04              ; xas99 labels are not limited to 6 chars
       DATA >0004       ; overlay number
SM00EC DATA >EC00       ; SAMS page to store this RAM block

       END

 

 

Assembler listing:

Spoiler
XAS99 CROSS-ASSEMBLER   VERSION 3.4.0
     **** ****     > lib3000.a99
0001               ***********************************************
0002               * Program: LIB3000
0003               *
0004               * Test of multiple program overlay blocks all
0005               * running from low RAM at >3000->3FFF
0006               *
0007               
0008               * EQUates for references external to this 4KiB block of RAM
0009               *
0010      2108     KSCAN  EQU  >2108
0011               
0012               * Start of 4KiB RAM blocks all destined for >3000->3FFF
0013               *
0014               ***********************************************
0015               * OVERLAY 000:
0016               *
0017                      BANK 0, >3000
0018 3000 C000  18 OVLY00 MOV  R0,R0       ; first instruction
0019               
0020 3002 045B  20        RT
0021               
0022                      AORG >3FFC       ; last 2 words in this 4KiB RAM block
0023               OVERLAY_00              ; xas99 labels are not limited to 6 chars
0024 3FFC 0000            DATA >0000       ; overlay number
0025 3FFE F000     SM00F0 DATA >F000       ; SAMS page to store this RAM block
0026               
0027               ***********************************************
0028               * OVERLAY 001:
0029               *
0030                      BANK 1
0031 3000 C000  18 OVLY01 MOV  R0,R0       ; first instruction
0032               
0033 3002 045B  20        RT
0034               
0035                      AORG >3FFC       ; last 2 words in this 4KiB RAM block
0036               OVERLAY_01              ; xas99 labels are not limited to 6 chars
0037 3FFC 0001            DATA >0001       ; overlay number
0038 3FFE EF00     SM00EF DATA >EF00       ; SAMS page to store this RAM block
0039               
0040               
0041               ***********************************************
0042               * OVERLAY 002:
0043               *
0044                      BANK 2
0045 3000 C000  18 OVLY02 MOV  R0,R0       ; first instruction
0046               
0047 3002 045B  20        RT
0048               
0049                      AORG >3FFC       ; last 2 words in this 4KiB RAM block
0050               OVERLAY_02              ; xas99 labels are not limited to 6 chars
0051 3FFC 0000            DATA >0000       ; overlay number
0052 3FFE EE02     SM00EE DATA >EE02       ; SAMS page to store this RAM block
0053               
0054               ***********************************************
0055               * OVERLAY 003:
0056               *
0057                      BANK 3
0058 3000 C000  18 OVLY03 MOV  R0,R0       ; first instruction
0059               
0060 3002 045B  20        RT
0061               
0062                      AORG >3FFC       ; last 2 words in this 4KiB RAM block
0063               OVERLAY_03              ; xas99 labels are not limited to 6 chars
0064 3FFC 0003            DATA >0003       ; overlay number
0065 3FFE ED00     SM00ED DATA >ED00       ; SAMS page to store this RAM block
0066               
0067               ***********************************************
0068               * OVERLAY 004:
0069               *
0070                      BANK 4
0071 3000 C000  18 OVLY04 MOV  R0,R0       ; first instruction
0072               
0073 3002 045B  20        RT
0074               
0075                      AORG >3FFC       ; last 2 words in this 4KiB RAM block
0076               OVERLAY_04              ; xas99 labels are not limited to 6 chars
0077 3FFC 0004            DATA >0004       ; overlay number
0078 3FFE EC00     SM00EC DATA >EC00       ; SAMS page to store this RAM block
0079               
0080                      END

 

 

The command line that produced the above assembly:

xas99.py lib3000.a99 -b -R -L lib3000.lst

 

In addition to the assembly listing, this produces a 4KiB binary file for each overlay (SAMS page) with “_bn.bin” appended, where ‘n’ is the overlay number (starting with “_b0.bin”). These can be

  1. Individually loaded to the proper SAMS page with DSR opcode 5 (LOAD) or
  2. The binaries can all be added to a composite binary file by using TI99Dir to convert that composite binary file to a TI-Files file with IF128 format and each 4KiB overlay can be loaded by one of the following methods:
    1. Reading 32 128-byte records at a time with DSR level 3 READ or
    2. Reading 16 sectors at once with DSR level 2, subprogram >014.

The command line to create the composite binary file from the above single binaries is

copy /Y /B lib3000_b?.bin /B lib3000.bin

 

A small routine would need to be written to handle the above process, which would include

  1. Loading the next 4KiB overlay to a VRAM file buffer
  2. Reading overlay  and SAMS page numbers from end of VRAM buffer 
  3. Mapping the next SAMS page to >3000
  4. Copying that 4KiB chunk to >3000
  5. Record necessary overlay and SAMS page pointers for later overlay verification and SAMS mapping
  6. If not EOF, repeat at (1)

The space for the above routine in the main program can be reclaimed when the routine finishes because it only needs to be run once at program startup.

 

Hope the above gives you some ideas about what is possible.

 

...lee

Edited by Lee Stewart
ADDITION & CORRECTION
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

I never knew xas99 assembler did that!. I've used the assembler i thnk, twice., but that's basically because, 1, my code was short and 2, I was on real hardware most of the time. But if I want to get more serious with SAMs I was going to have to start thinking forward a bit and feeling what is out there. I never knew it could do that. Hmmm ..of course it'll take me 3 months to decipher lol. What you sent here lee. Thx

Edited by GDMike
  • 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...