Jump to content

Photo

Assembly on the 99/4A


597 replies to this topic

#551 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,438 posts
  • Location:Denmark

Posted Sat Aug 12, 2017 2:14 AM

Sure, but the ISR is the one thing to be aware of that might interfere with your program, by trashing your variables in scratch pad or changing the VDP address. I always turn off the ISR. 



#552 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 326 posts
  • Location:The Great White North

Posted Sat Aug 12, 2017 10:07 PM

 

Well, on the TI-99/4A, I've always used the stack growing in the other direction. To follow your example ...

 

A push is then done with

MOV @DATA,,*SP+

 

and a pop with

DECT SP

MOV *SP,@DATA
   
;)

 

 

A convention in my experience is to have stacks grow downwards from high RAM and memory usage to grow upwards.

Not written in stone somewhere, just something I have seen.

 

BF



#553 sometimes99er OFFLINE  

sometimes99er

    River Patroller

  • 3,924 posts
  • Location:Denmark

Posted Sun Aug 13, 2017 12:47 AM

... my experience is to have stacks grow downwards ...

 

Yes.

 

For my practical use of a stack simply saving and retrieving return addresses. I originally only looked at saving a few bytes and not at CPU cycles used.

 

Growing downwards would need 4 bytes in-line to PUSH and 4 bytes to POP and return. 8 bytes in total. PUSH would consist of 2 lines of instructions, namely DECT and MOV. POP would have MOV and RT.

 

Growing upwards would need 2 bytes in-line to PUSH (1 line is nice and clean) and 6 bytes to POP and return. Also 8 bytes in total. I replaced the in-line POP with a branch which is 4 bytes *). PUSH would consist of 1 line, namely MOV. POP would have 1 line (nice and clean), namely B. The general code to branch to consists of 6 bytes or 3 lines of instructions, namely DECT, MOV and RT.

 

Growing down would use 8 bytes per routine.

 

Growing up would use 6 bytes per routine and one generel chunk of 6 bytes.

 

There's a break-even at 3 routines. 

 

8X = 6X + 6

 

2X = 6

 

X = 3

 

*) Could be optimized and cut to 2 bytes using jump in a very few cases.

 

For fun I now took a look at CPU cycles used according to Classic99.

 

Growing down would use 78 cycles per routine. Growing up without branching use the same cycle count.

 

Growing up with branching would use 130 cycles per routine.

 

Did I get it all right? Hope so.  :)



#554 apersson850 OFFLINE  

apersson850

    Moonsweeper

  • 421 posts

Posted Sun Aug 13, 2017 3:08 AM

If you use it for saving return addresses only, it doesn't matter much.

But if the stack is used for other things too, then it's sometimes handy to have the stack pointer actually pointing at the top of stack all the time, not pointing to the next free space above top of stack. With the TMS 9900 you can easily address top of stack in any case, but if you let the stack grow downwards, as I indicated, then top of stack is accessed by *SP. If you let it grow upwards, and want to use autoincrement, then you have to refer to top of stack as @-2(SP). Doable, but slower and consumes more space.

 

When allocating a frame on the stack, i.e. a larger piece of data, then it's also easy to refer to the items in that record by indexing from the stack pointer with positive indexes. You can do the opposite, but at least to me, I find it easier to think in positive terms.

You push by AI -ITEMSIZE,SP

When you transferred the data to the stack, you reach the top element by *SP and items further down by @OFFSET(SP).

You have use for such data on the stack when traversing graphs, for example.



#555 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 326 posts
  • Location:The Great White North

Posted Sun Aug 13, 2017 9:19 AM

This is the way most Forths are implemented for both stacks for all the reasons you state.

 

In CAMEL99 I tried a common optimization and CACHE the top of stack value in a register.

This changes where you have to push and pop but on balance it speeds up a Forth system by about 10%.

Simple Math operations become:

 

A  *SP+,R4   

versus

A  *SP+,*SP

 

Fetching the contents of a variable is:

 

MOV *R4,R4

 

I like it. :)



#556 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Mon Sep 4, 2017 7:21 PM

Just read about the Workspace Pointer being initially set to >83E0 at boot up or Reset by a Level 0 interrupt, as per the ROM Monitor . This seems well placed since the range >83E0 to >83FF is 32-bytes of the 256-byte most efficient 16-bit CPU addressable "scratchpad" RAM.

Why would a non-context-switching 99/4 programmer wish move the WP elsewhere?

If you routinely do so please explain to where and why?

Gratitude Always. -james

Edited by Airshack, Mon Sep 4, 2017 7:23 PM.


#557 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,355 posts
  • Location:Silver Run, Maryland

Posted Mon Sep 4, 2017 7:49 PM

If you never use GPLLNK (WSP = >83E0) or allow the console ISR to run (WSP = >83C0 and switches to/from GPL WS), you are probably safe using the GPL WS.

 

...lee



#558 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 326 posts
  • Location:The Great White North

Posted Mon Sep 4, 2017 7:50 PM

Well... the TI system is using the workspace at 83E0 and it kind of assumes it owns them.

 

So if you want a full register set for your program, it's available.

And if you don't change you have to save at least some of the registers in order to use them.

 

Also it's simpler to let TI-99 keep it's workspace when you call some of the system calls like KSCAN and such.

 

So the good news is there is a nice space at >8300 that is waiting for your program to use as a workspace.

Take it and have 16 registers to yourself.

 

B



#559 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Mon Sep 4, 2017 8:29 PM

 
So the good news is there is a nice space at >8300 that is waiting for your program to use as a workspace.
Take it and have 16 registers to yourself.
 
B


So you're saying just use BLWP >8300 for your own registers and leave the >83E0 -- >83FF area alone for the Service Routines with LIMI 2.

Otherwise, with LIMI 0... use BLWP >8300 and feel free to use >83E0 -- >8300 for anything else, with no worries?


Sent from my iPhone using Tapatalk Pro

#560 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 326 posts
  • Location:The Great White North

Posted Mon Sep 4, 2017 8:43 PM

Actually just LWPI >8300

That way you wont't pollute R13, R14 and R15 in the Other workspace.

 

And that only guarantees you 8300 to 830F (16 words of memory for registers)

 

Consult the Editor Assembler manual for the usage of the memory at 8300 to 83FF


Edited by TheBF, Mon Sep 4, 2017 8:46 PM.


#561 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,355 posts
  • Location:Silver Run, Maryland

Posted Mon Sep 4, 2017 9:01 PM

And that only guarantees you 8300 to 830F (16 words of memory for registers)

 

Typo there—8300 to 831F.

 

...lee



#562 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Mon Sep 4, 2017 9:14 PM

Actually just LWPI >8300

That way you wont't pollute R13, R14 and R15 in the Other workspace.
 
And that only guarantees you 8300 to 830F (16 words of memory for registers)
 
Consult the Editor Assembler manual for the usage of the memory at 8300 to 83FF


LWPI >8300 is indeed what I meant.

I've been reading E/A which seems heavy on facts and especially light on technique.

I suppose tonight's question is more of a technique question. Where does everyone put their registers, and why?

Seems >8300 is commonly used since it's in the scratchpad.

#563 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,355 posts
  • Location:Silver Run, Maryland

Posted Mon Sep 4, 2017 9:18 PM

So you're saying just use BLWP >8300 for your own registers and leave the >83E0 -- >83FF area alone for the Service Routines with LIMI 2.

 

>83C0 – >83FF if you use LIMI 2 anywhere in your program.

 

Otherwise, with LIMI 0... use BLWP >8300 and feel free to use >83E0 -- >8300 for anything else, with no worries?

 

Again, as long as you never use LIMI 2.  If you do use LIMI 2, you will need to have backed up that WS as it was before you used it so you can restore it before issuing LIMI 2.  There are a few values needed by the ISR when it changes from the ISR WS to the GPL WS.  I would need to review the ISR routine and the routine(s) it calls, but I think, at times, the ISR also uses values in the GPL WS without BLWP/LWPIing to it

 

...lee



#564 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,355 posts
  • Location:Silver Run, Maryland

Posted Mon Sep 4, 2017 10:13 PM

Here is how fbForth 2.0 uses Scratchpad RAM (from Chapter 4 of the fbForth 2.0 manual):

 

Attached File  CPU_RAM_Pad.png   84.87KB   6 downloads

 

As you can see, >8300 – >831F is the fbForth workspace.  The ISR and GPL workspaces are left alone for the most part because the normal state is LIMI 2 in fbForth. The Default Data Stack at >83A0 – >83BF is used by the Floating Point Library for its workspace because the FPL does not use any GPL or XML calls that would use that space.

 

...lee



#565 apersson850 OFFLINE  

apersson850

    Moonsweeper

  • 421 posts

Posted Tue Sep 5, 2017 3:30 AM

So it depends entirely in which context your program exists. Most efficient programs are a mix of high level and assembly. Thus your assembly programs have to respect the environment they were called from. An assembly procedure called from Pascal can't use more than R0-R7 in the calling workspace, which is at 83C0, without saving what it changes.
It's only programs that don't intend to return to anything but a reboot that can roam everywhere in memory.

#566 TheBF OFFLINE  

TheBF

    Moonsweeper

  • 326 posts
  • Location:The Great White North

Posted Tue Sep 5, 2017 4:23 AM

 

Typo there—8300 to 831F.

 

...lee

 

Yup,



#567 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Tue Sep 5, 2017 8:11 AM

So it depends entirely in which context your program exists. Most efficient programs are a mix of high level and assembly. Thus your assembly programs have to respect the environment they were called from. An assembly procedure called from Pascal can't use more than R0-R7 in the calling workspace


I'm thinking as a beginner in Assembly the Pure-Assembly route introduces less complexity.

#568 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Tue Sep 5, 2017 8:32 AM

 
>83C0 – >83FF if you use LIMI 2 anywhere in your program.
 
 
Again, as long as you never use LIMI 2.  If you do use LIMI 2, you will need to have backed up that WS as it was before you used it so you can restore it before issuing LIMI 2.  


Got it! Thx:)

#569 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Tue Sep 5, 2017 8:53 AM

aa4be024af5de03b9aca74c3ff54072d.jpg

Bob Webb's collection of User Group newsletter Assembly Lessons is especially enjoyable to read. His humor and artwork combine well with an ability to clarify some challenging topics.

Today's questions come from Bob's tutorial on the Memory Map.

From what I've gathered the 8k area from >6000 to >7FFF is for Command Module memory: GROM and ROM, or in the case of Mini-Memory GROM/ROM and "middle memory" RAM.

Q1: This Command Module ROM is either TI's proprietary GROM (auto-incrementing for faster sequential reads) or regular ROM, or both. Correct?

Q2: Is it safe to assume using GROM was less about speed and more about controlling developers?

Q3: If one wishes to write Assembly code for a cartridge ROM, you're limited to 8k?

Q4: How does the console v2.2 ROM lock out GROM-less cartridges?

Q5: Are the modern carts sold by Greg on Arcadeshopper unable to run on the v2.2 machine?

Thanks guys! Many pieces to this TI 99/4A puzzle!

-j

#570 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,355 posts
  • Location:Silver Run, Maryland

Posted Tue Sep 5, 2017 11:21 AM

One place to always check is Thierry Nouspikel’s TI-99/4A Tech Pages.
 
That said, re questions 1 and 3, cartridge ROM space is indeed in the CPU address space at >6000 – >7FFF. You can write programs larger than 8 KiB for this space by using bank-switching techniques—fbForth 2.0 uses 32 KiB (4 8-KiB banks).
 
GROM space, however, is not in CPU address space. GROMs are memory-mapped devices with their own address space accessed through 4 CPU address windows for each GROM base. For GROM base >9800, these window addresses are
 
>9800: read data (GROM base)
>9802: read address+1
>9C00: write data
>9C02: write address
 
Others here will elaborate this topic much better than I can.
 
Re question 2, though proprietary control was part of it, I think it was more about space. You can write a GPL program in a good bit less space than the same program would occupy in Assembly Language.
 
...lee


#571 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,438 posts
  • Location:Denmark

Posted Tue Sep 5, 2017 11:31 AM

Q3: No, because modern cartridges have many 8K pages.

Q4: By not showing them in the menu.

Q5: Yes, ROM only cartridges are unable to run on a v2.2 machine, except if you do tricks.



#572 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Tue Sep 5, 2017 3:11 PM

One place to always check is Thierry Nouspikel’s TI-99/4A Tech Pages.
 
...lee


Thank you for this link! This kind of material helps break up the monotony of reading through the E/A manual.

-j

#573 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 530 posts
  • Location:Phoenix, AZ

Posted Tue Sep 5, 2017 3:18 PM

Q3: No, because modern cartridges have many 8K pages.
Q4: By not showing them in the menu.
Q5: Yes, ROM only cartridges are unable to run on a v2.2 machine, except if you do tricks.


Q4: So it must look for the GROM in the cartridge address space at RESET?

#574 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,438 posts
  • Location:Denmark

Posted Tue Sep 5, 2017 3:49 PM

Q4: So it must look for the GROM in the cartridge address space at RESET?

 

No, a v2.2 machine doesn't look in the cartridge space at all, but it looks for GROMs in the GROM space. 



#575 matthew180 OFFLINE  

matthew180

    River Patroller

  • Topic Starter
  • 2,388 posts
  • Location:Castaic, California

Posted Wed Sep 6, 2017 10:20 PM

Answering rather late, sorry.
 
I always put my workspace at >8300.  No particular reason other than I have always done it that way and it is out of the way of using the rest of the scratch pad RAM for variable storage.  IMO you should *always* use a workspace in the 16-bit scratch pad RAM, otherwise you pay a hefty performance penalty.  As others have mentioned, if you are going to use console routines (ROM or GROM) or allow the console ISR to run, then you will need to know and respect the use of scratch pad based on those services.  Also, if you are interfacing with XB then I think there are additional constraints.
 
 

Q1: This Command Module ROM is either TI's proprietary GROM (auto-incrementing for faster sequential reads) or regular ROM, or both. Correct?


A command module can contain both ROM and GROM.
 

Q2: Is it safe to assume using GROM was less about speed and more about controlling developers?


That would be a good assumption. Secondary assumptions might be cost, component size, or number of pins.
 

Q3: If one wishes to write Assembly code for a cartridge ROM, you're limited to 8k?


Without bank-switching, yes, you are limited to 8K. With bank-switching you are limited to 8K at *any single time*. Basically bank-switching gives you an 8K window into the larger memory space.
 

Q4: How does the console v2.2 ROM lock out GROM-less cartridges?


I'm not totally up on my console differences, but as others have said I think carts that do not have GROM do not show up on the menu. Also, I think the QI console removed some of the physical connections to the cartridge port, so ROM is not physically possible. I might be wrong about that though, so check the facts.
 

Q5: Are the modern carts sold by Greg on Arcadeshopper unable to run on the v2.2 machine?


No idea.  Greg?






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users