Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

What should I do when my program begins in the 24K block of high expansion memory ( AORG >A000 ) and then it's length extends beyond the 24K limit at >FFD7?  [ref: E/A manual, Section19.1 Memory Allocation, p.305]

 

Specifically, how do I utilize the lower block of 8K memory from >2000 - >3FFF?

 

I've noticed when I assemble code exceeding 24K there's a failure in the assembler. Why?

 

I'm using xas99 with the following batch file:

 

:: ///// Assemble an EA5 Program Image File /////
 

xas99.py -R -i progname.a99 -o progname-5
if %errorlevel% neq 0 exit /b 

 

This batch file works properly until the program exceeds 24K. I suppose I need to use multiple assembler directives in my program, maybe on on some of my data tables, to move them down to the >2000 - >3FFF range?

 

May I do this without crashing the "utilities and the REF/DEF table," as the E/A manual states?

 

When I load my program using E/A5 I don't ever see any activity in this lower block range...

 

Is this because I'm running the E/A cart vs and E/A disk? Confusing....help please!

 

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, Airshack said:

What should I do when my program begins in the 24K block of high expansion memory ( AORG >A000 ) and then it's length extends beyond the 24K limit at >FFD7?  [ref: E/A manual, Section19.1 Memory Allocation, p.305]

 

Specifically, how do I utilize the lower block of 8K memory from >2000 - >3FFF?

I don't know what other people do, but I create separate assemblies for each memory space. When you're all done you can link the program images manually. ;)

 

  • Thanks 1
Link to comment
Share on other sites

2 hours ago, Airshack said:

What should I do when my program begins in the 24K block of high expansion memory ( AORG >A000 ) and then it's length extends beyond the 24K limit at >FFD7?  [ref: E/A manual, Section19.1 Memory Allocation, p.305]

 

Specifically, how do I utilize the lower block of 8K memory from >2000 - >3FFF?

 

I've noticed when I assemble code exceeding 24K there's a failure in the assembler. Why?

 

I'm using xas99 with the following batch file:

 

:: ///// Assemble an EA5 Program Image File /////
 

xas99.py -R -i progname.a99 -o progname-5
if %errorlevel% neq 0 exit /b 

 

This batch file works properly until the program exceeds 24K. I suppose I need to use multiple assembler directives in my program, maybe on on some of my data tables, to move them down to the >2000 - >3FFF range?

 

May I do this without crashing the "utilities and the REF/DEF table," as the E/A manual states?

 

When I load my program using E/A5 I don't ever see any activity in this lower block range...

 

Is this because I'm running the E/A cart vs and E/A disk? Confusing....help please!

 

Unless your code is relocatable (using RORG), the linking loader will not relocate any of your program to the lower expansion RAM and will do as you observed. If you want to put a piece of your program in lower RAM, the E/A utilities end at >267B and the REF/DEF table ends at >3F38 before your REF/DEFs are added (growing down from >3F38). That is 6332 bytes. If you make your program relocatable, The linking loader will start loading your relocatable program at >A000 and continue at >267C (or close).

 

...lee

  • Like 2
Link to comment
Share on other sites

2 hours ago, Tursi said:

I don't know what other people do, but I create separate assemblies for each memory space. When you're all done you can link the program images manually. ;)

 

I’d like to turn my EA5 files into a .bin for FinalGROM when finished. Assuming this method requires multiple files? I’d also have to learn to manually link files which means more learning of course ;)

Link to comment
Share on other sites

2 hours ago, Lee Stewart said:

If you make your program relocatable, The linking loader will start loading your relocatable program at >A000 and continue at >267C (or close).

This sounds promising and the easiest way to claim around 6k of that low expansion memory. Unfortunately, I seem to remember the AORG directive was necessary in order to get xdt’s xas99 assembler to work. I believe this was covered earlier in this thread. I need to check.

Link to comment
Share on other sites

But the linking loader can't do that with one large block of program, can it?

I know that if you load several files, each (say) 4 K long, and each with RORG directive, then the loader will stuff them into 24 K RAM until it gets full. The next file will end up in the 8 K RAM.

But if you create one big program, say 28 K long, then you're toast, aren't you?

I've never needed it, but I don't think entering multiple RORG directives in the same file will create separate relocatable blocks. But perhaps it will.

 

When using the UCSD p-system's assembler and linker, you can do that. You can easily create multiple program modules inside one assembly file, where each module is relocatable separately. This also implies that if you want to reach a label that's in another such module, you have to DEF it where it is and REF it where it's used. Just like you have to do across separate files with the E/A assembler/loader.

  • Thanks 1
Link to comment
Share on other sites

11 hours ago, Tursi said:

I create separate assemblies for each memory space. When you're all done you can link the program images manually. ;)

Looks like I’ll need to figure this out. May I correctly assume this solution will create multiple files which will then prevent the creation of a single binary file?

Link to comment
Share on other sites

1 hour ago, Airshack said:

Looks like I’ll need to figure this out. May I correctly assume this solution will create multiple files which I will then be unable to make a single binary file out of?

I only use E/A, it automatically creates multiple files if the object code is larger than 8K.

 

edit: From a single .bin, you would probably want to use trampoline code to move the smaller part of the program down to LOWMEM.

Edited by HOME AUTOMATION
  • Thanks 1
Link to comment
Share on other sites

Or do as I did once, when I developed assembly support for Extended BASIC, for computers with 32 K memory expansion only. It could run from cassette as well as from disk. You did OLD CS1, which loaded the Extended BASIC program. Inside, there were some CALL LOAD statements, which poked a minimal loader into RAM. Then CALL LINK that loader, which loaded the next memory image file on the cassette. That was the real support subprogram.

By this I mean that you can include a memory image loader in your own program, which reads any number of memory image files you need.

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

I've got an assembly code writing technical question.

When should I use an "EVEN" instruction in my code?

I understand using it after placing something like, TEXT "1" for example, and placing EVEN on the next instruction., but what other consequences require an EVEN that you can think of?

Would this?

ST BSS 1

Or this,

FINE DATA 1

 

Thank you

Edited by GDMike
Link to comment
Share on other sites

HEX01   BYTE >01

             EVEN

 

or better to include all your BYTE/TEXT labels as a group whenever possible.

 

HEX01 BYTE >01

STR1   TEXT 'Hello World!"

HEX02 BYTE >02

HEX03 BYTE >04

STR2   TEXT 'See you another day.'

           EVEN

 

By grouping all possible odd length strings and bytes together, the use of EVEN results in at most only a single byte of extra space used if there was an odd length to all the statements.

 

Beery  

 

 

  • Like 3
Link to comment
Share on other sites

35 minutes ago, GDMike said:

Would this?

ST BSS 1

Yes, it reserves one byte.

35 minutes ago, GDMike said:

Or this,

FINE DATA 1

No, because DATA always reserves 2 bytes even though the value 1 could be stored in one byte.

 

I'm not actually sure under which circumstance the assembler automatically aligns to an even address. I think Win99Asm is doing it differently from the E/A assembler.

  • Like 1
Link to comment
Share on other sites

It aligns for DATA and instructions.

 

With EVEN, you could e.g. ensure that a line with BYTE or TEXT starts at a word address when the previous line was BYTE or TEXT or BSS.

 

Also, the E/A manual mentions that a label is assigned the current location counter, so for instance, in

 

   DATA 0
   TEXT 'Example'
LABEL
   LI R0,1
   ...

 

the LABEL does not point to the operation LI in the following line but to the byte after the text.

Edited by mizapf
I just don't get it without space lines.
  • Like 1
Link to comment
Share on other sites

54 minutes ago, mizapf said:

It aligns for DATA and instructions.

 

With EVEN, you could e.g. ensure that a line with BYTE or TEXT starts at a word address when the previous line was BYTE or TEXT or BSS.

 

Also, the E/A manual mentions that a label is assigned the current location counter, so for instance, in

 


   DATA 0
   TEXT 'Example'
LABEL
   LI R0,1
   ...

 

the LABEL does not point to the operation LI in the following line but to the byte after the text.

Say what? You were just waiting for me to walk into this. Lol now this doesn't make sense to me...

Edited by GDMike
Link to comment
Share on other sites

27 minutes ago, GDMike said:

Say what? You were just waiting for me to walk into this. Lol now this doesn't make sense to me...

So even if the instruction LI R0,1 starts at >2000 the LABEL still has the value >1FFF. That's exactly why you need to use EVEN after the text and before the label. Otherwise if you branch to LABEL you will execute the last 'e' of 'Example', whatever instruction that might correspond to. 

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

1 hour ago, mizapf said:

It aligns for DATA and instructions.

 

With EVEN, you could e.g. ensure that a line with BYTE or TEXT starts at a word address when the previous line was BYTE or TEXT or BSS.

 

Also, the E/A manual mentions that a label is assigned the current location counter, so for instance, in

 


   DATA 0
   TEXT 'Example'
LABEL
   LI R0,1
   ...

 

I see

Link to comment
Share on other sites

12 minutes ago, Asmusr said:

So even if the instruction LI R0,1 starts at >2000 the LABEL still has the value >1FFF. That's exactly why you need to use EVEN after the text and before the label. Otherwise if you branch to LABEL you will execute the last 'e' of 'Example', whatever instruction that might correspond to. 

Will the Program Counter on real hardware allow execution of code on an odd boundary?  I did not think it would allow that.

 

I know back when Geneve support was first added to MESS, I found one or two instructions that did not 'autocorrect' for an even boundary that then threw the emulated 9995 into executing code on an odd boundary.  On the real hardware, the very same code did not allow that to happen.

 

Beery

 

  • Like 1
Link to comment
Share on other sites

4 minutes ago, BeeryMiller said:

Will the Program Counter on real hardware allow execution of code on an odd boundary?  I did not think it would allow that.

 

I know back when Geneve support was first added to MESS, I found one or two instructions that did not 'autocorrect' for an even boundary that then threw the emulated 9995 into executing code on an odd boundary.  On the real hardware, the very same code did not allow that to happen.

 

Beery

 

No, if you branch to >1FFF it will branch to >1FFE, which is where the 'e' is.

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

12 minutes ago, BeeryMiller said:

Will the Program Counter on real hardware allow execution of code on an odd boundary?  I did not think it would allow that.

 

I know back when Geneve support was first added to MESS, I found one or two instructions that did not 'autocorrect' for an even boundary that then threw the emulated 9995 into executing code on an odd boundary.  On the real hardware, the very same code did not allow that to happen.

 

Beery

 

The TMS9995 databook says the PC is 15 bits, word address. (page 5) So you cannot branch or jmp to an odd address-the LSbit of branch should just be dropped. JMP is in units of words as well.

Even though it has an 8-bit bus, it is still the 16-bit microprocessor inside.

  • Thanks 1
Link to comment
Share on other sites

@BeeryMiller I remember this was indeed an issue ... but long ago, maybe 10 years or more.

 

I tried it with this code. The code is meaningless, also the CLR instructions.

       TEXT 'Example'
LABEL1
       CLR  R0
       LI   R1,LABEL1

       TEXT 'Another'
LABEL2 CLR  R0
       LI   R1,LABEL2

       TEXT 'LastOne'
LABEL3 TEXT 'here'
       CLR  R0
       LI   R1,LABEL3
       MOV  *R1+,R2
       MOV  *R1+,R3
       
       END 

 

This is the memory dump after loading:

 

a000  4578 616d 706c 6500 04c0 0201 a007 416e   Example.......An
a010  6f74 6865 7200 04c0 0201 a016 4c61 7374   other.......Last
a020  4f6e 6568 6572 6500 04c0 0201 a023 c0b1   Onehere......#..
a030  c0f1 0000 0000 0000 0000 0000 0000 0000   ................

 

So we can see that LABEL1 is indeed on an odd address (a007), where LABEL2 is on an even address (where it matters when the label is in the same line as the instruction and when it is not!). In the third example, I falsely assume that LABEL3 is on an even address, because I use MOV (not MOVB) which will deliver an unexpected result: R2 will contain 'eh' (from (LastOn)eh(ere)) and R3 will contain 'er' (not 'he' and 're').

 

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