Jump to content

Photo

Lots of Assembler Questions

TMS9900 Operands Editor/Assembler

73 replies to this topic

#1 kl99 OFFLINE  

kl99

    Dragonstomper

  • 844 posts
  • Location:Vienna, Austria

Posted Sat Jan 20, 2018 3:49 PM

Hi, can the experienced programmers confirm if the following statements are true and I understood the topics correct?

The background is that I am working on a tool TIcode99 and would like to get it reading in 99xx(x) source code files correct.

 

Special operand types [CruBit <cnt>, Xop <xop>, ShiftCount <scnt>]

 

- If an opcode requires a numeric input for an operand, the sourcecode can define the number as decimal or hexadecimal.

- If an opcode requires a numeric input for an operand, the sourcecode can always define a symbol (EQU opcode) and refer the symbol name instead of a direct numeric input

- If an opcode requires a numeric input for an operand, the sourcecode can refer a Workspace Register instead (like 'SLA R5,R0'). However not the value of the Workspace Register is used but the number of the Workspace Register

- for these operand types I can not use '1+2' as operand.

 

Immediate operand type <iop>

 

- If I define a Symbol, I can refer the symbol as immediate operand. Here I can also use a symbol reference like below to define an immediate operand.

-SYMB1
SYMB1+2
SYMB1*256
SYMB1+SYMB2

 All of these examples don't work for the operand types CruBit <cnt>, Xop <xop>, ShiftCount <scnt>.

 

- Below instruction is not supported on the TI-99 Editor Assembler, but probably on the TI-990 Assembler (SDSMAC).

 LI   R1,MF1+(>F*4)

I assume it can be translated to?

LI   R1,MF1+>FFFF

Questions about the Immediate Operand type:

 

1. What does this instruction mean?

CI   R0,@ENDDAT
...
ENDDAT EQU $

It fails for me in the EA, never the less the 99/8 source code uses such code in DEBUGG.

 

Other example:

PAR02   CI   R8,@INTEG$*256
...
INTEG$ EQU  >AE

2. How can a String be useful as immediate Value?

'E'
'I'-'0'
-'0'
'--'
'-'*256

I don't understand the usecase when to use a String like shown as Immediate operand. How are these "translated" into a numeric value?

 

Symbol operand type <symbol>

 

This operand type is a bit unclear to me. Afaik this i used by opcodes DEF, REF, SREF, LOAD, DXOP, END and DFOP.

Should this solely allow the definition/reference of a symbol?

Or should I be able to use something like "SYMB1+2" or other 'expressions'?

 

Workspace operand type <wa>

XPTL   EQU  6
SRL  XPTL,8

Since this works, it seems I can use a Symbol instead of a direct reference of one of the Workspace Register. Is it translated to Shift R6 by 8 to the right?

However I can not use "XPTL+2" for that operand.

 

Expression operand type <exp>

 

It is quite clear that wherever the syntax definitions says here should be an <exp> as operand type it allows an expression to be used. However it seems that the Immediate operand type <iop> and the General Address operand types <gas>,<gad> are heavily using expressions as well.

 

Is the assumption correct, that every expression has to result in some number (address) during assembling time?

 

General operand type <gas>, <gad>

 

I see sometimes an operand looking like indexed memory addressing, however the @ sign is not there.

WRTADD   EQU      >402
...
         MOVB      R4,WRTADD(R9)

Any explanations on why this is missing the @ sign?

 

 

Many thanks for your help in advance.

 



#2 Asmusr ONLINE  

Asmusr

    River Patroller

  • 2,892 posts
  • Location:Denmark

Posted Sat Jan 20, 2018 4:35 PM

1. What does this instruction mean?

 

CI   R0,@ENDDAT

 

It is not allowed on the TMS9900. CI requires an immediate operand instead of a memory address.

 

CI R0,5

 

or

 

SIZE EQU 5

CI R0,SIZE



#3 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Sat Jan 20, 2018 5:00 PM

Or (I think)


LI  R2,@ENDDAT
CI  R0,R2


Edited by Opry99er, Sat Jan 20, 2018 5:01 PM.


#4 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,383 posts
  • Location:Germany

Posted Sat Jan 20, 2018 5:06 PM

@kl99: You refer to this here...

 

CLOSE2 JMP  DV1RET                                                      ATA
READ2  XOP  3,5         FIND MY BLOCK                                   ATA
       MOV  @>E008,R0
       CI   R0,@ENDDAT
       JHE  EOF2
       MOVB  *R0+,R4     GET NEXT LINE LENGTH
       SRL  R4,8        make it a word
       MOV  R4,@4(R1)   RETURN LENGTH

 

I could not find the code in the ROMs of the 99/8; this is additional software. Either this is an error, or the assembler they used can do some magic things...



#5 jens-eike OFFLINE  

jens-eike

    Star Raider

  • 82 posts

Posted Sat Jan 20, 2018 5:07 PM

Or (I think)

 

LI  R2,@ENDDAT
CI  R0,R2

Wouldn't that compare R0 to 2 (immediate value), C R0,R2 compares two registers. The assembler option "R" does an operation like "R2 EQU 2"



#6 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Sat Jan 20, 2018 5:10 PM

Hmm... you may be correct. I thought CI could be used for the values contained within two different registers.

#7 marc.hull OFFLINE  

marc.hull

    Stargunner

  • 1,297 posts
  • Location:Oklahoma CIty.

Posted Sat Jan 20, 2018 5:52 PM

Your question is more related to assembler syntax than 9900 code. In the traditional sense...

Immediate opcodes require registers and numeric values. Doesn't matter if the value is dec, hex orbin provided it is marked as such.

Shit instructions require numeric values. If the value is zero the the contents of r0 are used.

Cru instructions always involve r12 as a target with a numeric value as an offset.

All of your immediate examples could be valid provided there was an assembler available to resolve labels and insert values based on addresses but not contents.

I suspect the 99/8 code was not created with the ea cart.

#8 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Sat Jan 20, 2018 5:53 PM

Hmm... you may be correct. I thought CI could be used for the values contained within two different registers.

 

Immediate operands can only be values (or expressions, I think) that are known at assembly time.  They also must be absolute, i.e., they cannot refer to relocatable values.  Actually, I believe the value can be relocatable as in

       RORG
HOLD   BSS  >20
  ...
START  LI   R1,HOLD

...lee

 

[Edited]



#9 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Sat Jan 20, 2018 6:01 PM

- Below instruction is not supported on the TI-99 Editor Assembler, but probably on the TI-990 Assembler (SDSMAC).

 LI   R1,MF1+(>F*4)

I assume it can be translated to?

LI   R1,MF1+>FFFF

 

The first expresion (where it is allowed) would evaluate to

MF1+>3C

not

MF1+>FFFF

...lee



#10 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,383 posts
  • Location:Germany

Posted Sat Jan 20, 2018 6:05 PM

Shit instructions require numeric values.

 

I know that times may be hard, but, well, this is pretty harsh, isn't it? ;)



#11 Stuart ONLINE  

Stuart

    Dragonstomper

  • 792 posts
  • Location:Southampton, UK

Posted Sat Jan 20, 2018 6:12 PM

Shit instructions require numeric values. If the value is zero the the contents of r0 are used.
 

If the value is zero then I believe the shi(f)t count is 16.



#12 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Sat Jan 20, 2018 6:21 PM

If the value is zero then I believe the shi(f)t count is 16.

 

...only if R0 contains 0.  Otherwise, the LSn (least significant nybble) of R0 is used.

 

...lee



#13 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Sat Jan 20, 2018 6:38 PM

2. How can a String be useful as immediate Value?

'E'
'I'-'0'
-'0'
'--'
'-'*256

I don't understand the usecase when to use a String like shown as Immediate operand. How are these "translated" into a numeric value?

 

I cannot say I understand all of those examples, but one may wish to load the ASCII value of a character without needing to remember the code by loading the byte or text.  Same with two such bytes.  Multiplying a single byte by 256 shifts the ASCII value of the byte to the MSB.

 

...lee



#14 marc.hull OFFLINE  

marc.hull

    Stargunner

  • 1,297 posts
  • Location:Oklahoma CIty.

Posted Sat Jan 20, 2018 6:40 PM

Ah. "F"

Sorry.

And Lee is correct. R0 has magic powers like r12.

I believe the op's questions are a result of trying to justify 99/8 source code using the ti99 ea assembler rules. I wonder what assembler encoded the 99/8 ?

#15 Stuart ONLINE  

Stuart

    Dragonstomper

  • 792 posts
  • Location:Southampton, UK

Posted Sat Jan 20, 2018 6:42 PM

Hi, can the experienced programmers confirm if the following statements are true and I understood the topics correct?

The background is that I am working on a tool TIcode99 and would like to get it reading in 99xx(x) source code files correct.

 

Special operand types [CruBit <cnt>, Xop <xop>, ShiftCount <scnt>]

 

- If an opcode requires a numeric input for an operand, the sourcecode can define the number as decimal or hexadecimal.

>>> Depends on the assembler. No reason it couldn't be binary or octal if the assembler supports it.

 

- If an opcode requires a numeric input for an operand, the sourcecode can always define a symbol (EQU opcode) and refer the symbol name instead of a direct numeric input

>>> Correct.

 

- If an opcode requires a numeric input for an operand, the sourcecode can refer a Workspace Register instead (like 'SLA R5,R0'). However not the value of the Workspace Register is used but the number of the Workspace Register

>>> The register values R0 to R15 are normally EQU'd as values 0 to 15 (that's one of the assembly options in EA IIRC; EA works fine specifying a register as just the register value). So "SLA R5,R0" would be assembled as "SLA R5,0". (As an aside, the register value doesn't need to be R(anything); if you had a program where the X position of something was stored in R2 and the Y position in R3, you could define symbols XPOS EQU 2 and YPOS EQU 3 and use instructions like "SLA XPOS,2" and "SLA YPOS,4".)

 

- for these operand types I can not use '1+2' as operand.

>>> No reason why not if the assembler supports it. It simply calculates the expression before assembling the instruction.

 

Immediate operand type <iop>

 

- If I define a Symbol, I can refer the symbol as immediate operand. Here I can also use a symbol reference like below to define an immediate operand.

>>> Yep. Although I think EA requires the first example below to be "0-SYMB1". SDSMAC (I think) is happy with just "-SYMB1".

-SYMB1
SYMB1+2
SYMB1*256
SYMB1+SYMB2

 All of these examples don't work for the operand types CruBit <cnt>, Xop <xop>, ShiftCount <scnt>.

>>> No reason why not if the assembler supports it. It simply calculates the expression before assembling the instruction.

 

- Below instruction is not supported on the TI-99 Editor Assembler, but probably on the TI-990 Assembler (SDSMAC).

>>> IIRC EA doesn't support the parantheses? So would have to write as >F*4+MF1? Certainly wouldn't be >FFFF - it would be the arithmetic product >F*4.

 LI   R1,MF1+(>F*4)

I assume it can be translated to?

LI   R1,MF1+>FFFF

Questions about the Immediate Operand type:

 

1. What does this instruction mean?

>>> If this was code destined for SDSMAC, I think it is less 'fussy' over the use of "@" - you can tell from the instruction whether it should be an immediate operand. I comment on this a bit further down.

CI   R0,@ENDDAT
...
ENDDAT EQU $

It fails for me in the EA, never the less the 99/8 source code uses such code in DEBUGG.

 

Other example:

PAR02   CI   R8,@INTEG$*256
...
INTEG$ EQU  >AE

2. How can a String be useful as immediate Value?

>>> Uses the ASCII value of the character. So for example you have a keyboard scanning routine that places the ASCII value of the key pressed in the LSB of R2. The instruction CI R2,'A' will test if the 'A' key was pressed. If the key value is stored in the MSB of R2, then use CI R2,'A'*256 - multiplying by 256 puts the ASCII value of "A" in the MSB of the word. (Haven't seen a string value with two characters before - presumably 'AB' puts the ASCII value for 'A' in the MSB and the ASCII value for 'B' in the LSB.)

'E'
'I'-'0'
-'0'
'--'
'-'*256

I don't understand the usecase when to use a String like shown as Immediate operand. How are these "translated" into a numeric value?

 

Symbol operand type <symbol>

 

This operand type is a bit unclear to me. Afaik this i used by opcodes DEF, REF, SREF, LOAD, DXOP, END and DFOP.

Should this solely allow the definition/reference of a symbol?

Or should I be able to use something like "SYMB1+2" or other 'expressions'?

 

Workspace operand type <wa>

XPTL   EQU  6
SRL  XPTL,8

Since this works, it seems I can use a Symbol instead of a direct reference of one of the Workspace Register. Is it translated to Shift R6 by 8 to the right?

>>> Yep, commented on this above.

 

However I can not use "XPTL+2" for that operand.

>>> No reason why not if the assembler supports it. "XPTL+2" would resolve to R8.

 

Expression operand type <exp>

 

It is quite clear that wherever the syntax definitions says here should be an <exp> as operand type it allows an expression to be used. However it seems that the Immediate operand type <iop> and the General Address operand types <gas>,<gad> are heavily using expressions as well.

 

Is the assumption correct, that every expression has to result in some number (address) during assembling time?

>>> Yep.

 

General operand type <gas>, <gad>

 

I see sometimes an operand looking like indexed memory addressing, however the @ sign is not there.

WRTADD   EQU      >402
...
         MOVB      R4,WRTADD(R9)

Any explanations on why this is missing the @ sign?

>>> As I commented above, SDSMAC (I think) is less 'fussy' over the need for the @, as it can be inferred from the instruction. In the source for the disk version of TI Invaders which I assume was assembled by SDSMAC, there are a few instructions like MOVB @H00,HERE, and it presumably assembled OK.

 

Many thanks for your help in advance.

 

 

I've tried to put some answers in-line above, prefixed with >>>.



#16 Stuart ONLINE  

Stuart

    Dragonstomper

  • 792 posts
  • Location:Southampton, UK

Posted Sat Jan 20, 2018 6:50 PM

 

...only if R0 contains 0.  Otherwise, the LSn (least significant nybble) of R0 is used.

 

...lee

 

Lee and Marc,

 

I've learned something new tonight! That's actually a handy little feature.

 

Stuart.



#17 InsaneMultitasker OFFLINE  

InsaneMultitasker

    River Patroller

  • 2,237 posts

Posted Sat Jan 20, 2018 11:40 PM

Shit instructions require numeric values. If the value is zero the the contents of r0 are used.

... and the only value passed is 2.



#18 kl99 OFFLINE  

kl99

    Dragonstomper

  • Topic Starter
  • 844 posts
  • Location:Vienna, Austria

Posted Sun Jan 21, 2018 3:29 AM

All your replies and discussions are so much appreciated. Thank you guys!

 

Questions about the Immediate Operand type:

 

1. What does this instruction mean?

CI   R0,@ENDDAT
...
ENDDAT EQU $

It fails for me in the EA, never the less the 99/8 source code uses such code in DEBUGG.

 

Other example:

PAR02   CI   R8,@INTEG$*256
...
INTEG$ EQU  >AE

 

I did some research on one question and found an easy answer to it:

The manual on the 990 assembler shows a note on Immediate Addressing:
 

3.2.8. Immediate Addressing

...

NOTE

An @ sign may precede an immediate operand, but has no effect.

 

(2270509-9701 990/9900 Assembly Language Reference Manual)

 

So I can allow and simply ignore it in TIcode99. Stuart was correct with his assumption!

 

 

 

General operand type <gas>, <gad>

 

I see sometimes an operand looking like indexed memory addressing, however the @ sign is not there.

WRTADD   EQU      >402
...
         MOVB      R4,WRTADD(R9)

Any explanations on why this is missing the @ sign?

 

Again, the manual on the 990 assembler shows a note on Symbolic Memory Addressing:
 

3.2.4. Symbolic Memory Addressing

...

NOTE

Symbols previously defined as having relocatable values or values greater than 15 need not have @. The at (@) sign is used to distinguish a register from an undefined memory storage label.

 

(2270509-9701 990/9900 Assembly Language Reference Manual)

 

So I can allow this syntax and simply ignore a missing symbol preFix in TIcode99 under the same circumstances. Stuart was again correct with his assumption!



#19 F.G. Kaal OFFLINE  

F.G. Kaal

    Space Invader

  • 38 posts

Posted Sun Jan 21, 2018 6:43 AM

A little remark about all your examples whith expressions  that "does work" or "does not" work also depends on what you are trying to do and also what Lee mentioned a few times: It depends on the assembler you use ... and what posibilities it has.

 

When I was creating my XA99 cross assembler I stumbled on a paragraph of the Model 990/12 Computer Assembly Language Programmer's guide which I copied below.

 

What this paragraph is trying to tell you is what makes sence and what not in an expression and if the result is absolute or relative.

 

For example:

 

Reloc. Symbol + Constant value is i.e. an offset in a table (1)

Reloc. Symbol - Reloc. Symbol is the size of i.e. some table (1-1=0)

Reloc. Symbol + Reloc. Symbol is what ? (1+1=2)

 

 

Expressions

Some information I found about expressions in the "Model 990/12 Computer Assembly Language Programmer's guide" paragrapgh "2.10 Expressions" page 2-19 and which is not mentioned in the Editor/Assembler manual is the following:
    if in an expression
       NA = sum of relocatable symbols added
       NS = sum of relocatable symbols subtracted
    then if
       NA - NS == 0 : Expression is absolute
       NA - NS == 1 : Expression is relative
       other is illigal

Fred



#20 marc.hull OFFLINE  

marc.hull

    Stargunner

  • 1,297 posts
  • Location:Oklahoma CIty.

Posted Sun Jan 21, 2018 6:18 PM

Way to go Lee. Good insight.

#21 marc.hull OFFLINE  

marc.hull

    Stargunner

  • 1,297 posts
  • Location:Oklahoma CIty.

Posted Sun Jan 21, 2018 7:10 PM

... and the only value passed is 2.


I can appreciate shitty jokes in fact I've made a few. None that short and pointed though. Nice Timbo.

#22 Opry99er OFFLINE  

Opry99er

    Quadrunner

  • 9,797 posts
  • Location:Hustisford, WI

Posted Sun Jan 21, 2018 7:10 PM

Lol!!

#23 marc.hull OFFLINE  

marc.hull

    Stargunner

  • 1,297 posts
  • Location:Oklahoma CIty.

Posted Sun Jan 21, 2018 7:30 PM

Lol!!

😒

#24 apersson850 OFFLINE  

apersson850

    Dragonstomper

  • 510 posts

Posted Tue Jan 23, 2018 4:37 AM

DEF, REF, LOAD etc. aren't opcodes. They don't produce instructions the CPU can execute. They are assembly directives, controling how the assembler program works when generating tagged object code. The DEF directive, for example, defines a label for external reference. It generates object code tagged in such a way, that the appropriate loader, which understands the tag correctly, will create an entry in the REF/DEF table, where external definitions are stored. Definitions stored there can then be referenced by another program, which contains the REF directive.

This is useful for example when two or more assembly programs are loaded after each other, and those loaded later need access to some points in the programs loaded previously. Or when the operating system needs access to some label you defined, in order to start executing your assembly program from BASIC, for example.



#25 RXB OFFLINE  

RXB

    River Patroller

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

Posted Tue Jan 23, 2018 5:12 AM

Just so you know the Ryte Data GPL Assembler has different set of output commands then Editor Assembler output commands.

 

Example EA OPTIONS: LRSC    (List, Registers, Symbols, Compressed)

 

Example Ryte Data GPL Assembler OPTIONS: LSFPFC (List, Symbols 16=F, Passes 16=F, Compressed)

 

Symbol Note: 16 symbol tables means it gives you at least two versions 1 alpha listing and 2 address listing.

 

Pass Note: 16 means it will load the entire source up to 16 times to resolve references and list those changes each pass.

(The most I have ever gotten the Ryte Data GPL Assembler to do was 9 passes to resolve references that called other references.)


Edited by RXB, Tue Jan 23, 2018 5:12 AM.






Also tagged with one or more of these keywords: TMS9900, Operands, Editor/Assembler

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users