Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

Okay, next great ASM9900 mystery!

 

I am struggling to get CB to work as expected. When I debug my code, I have the following setup:

 

R3 6800

R4 8800

 

...but when I try to do a CB as follows, it doesn't work.

 

    CLR R3
    CLR R4
    MOVB *R1, R3
    MOVB *R2, R4
    ; Debugger shows R3/R4 values as posted above
    CB R3,R4
    JGT @DOSOMETHINGELSE
    ; R3 MSB is <= R2 MSB
    Dostuff...

 

...instead it always goes to @DOSOMETHINGELSE.

 

If I switch it up and use this code instead, avoiding the "CB", it works just fine:

 

       CLR R3
       CLR R4
       MOVB *R1, @LBR3
       MOVB *R2, @LBR4
       C    R3,R4
       JGT ;DOSOMETINGELSE
       ; R3 <= R4
       Dostuff...

 

Infuriating! 

Link to comment
Share on other sites

1 hour ago, mizapf said:

But 0x0068 < 0x0088, while 0x6800 > 0x8800 (arithmetically). This is because 0x8800 is less than 0 in two's complement.

*Sigh*.   I feel like I dealt with this exact issue about a month ago.

 

So I can't use Byte-wise comparison for this type of function. That's fine, it's cost me enough hours.

 

Link to comment
Share on other sites

 

3 hours ago, retrodroid said:

*Sigh*.   I feel like I dealt with this exact issue about a month ago.

 

So I can't use Byte-wise comparison for this type of function. That's fine, it's cost me enough hours.

 

Yes you can. You just need to use an unsigned jump instruction. 

 

I tested it with JLE for example and it works.

Apologies for the RPN Assembler. It's just easier to test. :)

CMPB,  is of course CB in regular assembler. (CB is a HEX number in Forth) ;) 

 

Edit: Oops.  I have the true/ false logic reverse here. Just swap CLR and SETO 

 

CODE TESTJLE ( n1 n2 -- ?) \ n2 is in R4 in Camel Forth
    *SP+ R1 MOV,  \ pop n1 to R1
      R1 R4 CMPB,
        1 $ JLE,
         R4 SETO,
            NEXT,  \ return to Forth

1 $:     R4 CLR,
            NEXT, \ to Forth 
ENDCODE

image.thumb.png.70d6e7c5f5ccf13484f1768034ee3490.png

Link to comment
Share on other sites

4 hours ago, retrodroid said:

*Sigh*.   I feel like I dealt with this exact issue about a month ago.

So I can't use Byte-wise comparison for this type of function. That's fine, it's cost me enough hours.

I don't understand the problem. You are comparing two bytes, In your example:

R3 6800       (I assume these two are in hex.)

R4 8800

CB R3,R4

JGT something else

Here R3 is arithmetically greater than R4 because R4 is negative. But logically R3 is lower than R4.

So JGT would jump, but JH would not jump.

 

You can try this test program. After you run it, >3000 is >FFFF and >3002 is >0000.

So R3 is greater than R4 or it would have reset >3000 to zero. But R3 is not higher than R4, so it reset >3002 to zero.

               DEF CBYTES
    
CBYTES    SETO @>3000
               SETO @>3002
               LI R3,>6800
               LI R4,>8800
    
               CB R3,R4
               JGT GT
               CLR @>3000  will be 0 if not greater than
    
GT           CB R3,R4
               JH BACK
               CLR @>3002   will be 0 if not high
    
BACK        B *R11
    
                END
   

 

Link to comment
Share on other sites

Thanks guys. I basically forgot about the signed operand issue, and that combined with my unfamiliarity with the signed jump instructions led me astray. I ran into this exact issue a few weeks ago and finally figured it out on my own, but it didn't stick, obviously. 

 

Maybe this time it will... 😬

 

Here's an interesting and informative chat I had about the topic with ChatGPT:

 

Quote

---------
What are the unsigned jump instructions in ASM9900 assembler?

 

The ASM9900 assembler is a symbolic assembler for the Texas Instruments TMS9900 microprocessor. The unsigned jump instructions in ASM9900 assembler are:

JLT - Jump if Less Than
JLE - Jump if Less Than or Equal
JEQ - Jump if Equal
JHE - Jump if Higher or Equal
JGT - Jump if Greater Than
JNE - Jump if Not Equal
JNC - Jump if No Carry
JOC - Jump if Overflow Clear
JNO - Jump if No Overflow
JIN - Jump Indirect

 

These instructions are used to transfer control to a different part of the program based on the result of a previous operation. Each instruction is followed by an address that specifies the location in memory to which control is transferred.

Note that these instructions are "unsigned" in the sense that they are used to perform comparisons and jumps based on unsigned integer values. In ASM9900 assembler, there are separate signed jump instructions that can be used to perform comparisons and jumps based on signed integer values.

 

---------
What are the signed jump instructions?

 

The signed jump instructions in ASM9900 assembler are used to perform comparisons and jumps based on signed integer values. The signed jump instructions in ASM9900 assembler are:

JL - Jump if Less Than
JLEU - Jump if Less Than or Equal Unsigned
JH - Jump if High
JLE - Jump if Less Than or Equal
JGT - Jump if Greater Than
JNEU - Jump if Not Equal Unsigned
JC - Jump if Carry Set
JO - Jump if Overflow Set
JNO - Jump if No Overflow
JID - Jump if Indirect Data

 

Like the unsigned jump instructions, each signed jump instruction is followed by an address that specifies the location in memory to which control is transferred. However, the comparison and jump are based on the signed value of the operands rather than the unsigned value.

It's important to note that the JLEU instruction is a signed jump instruction, but it compares and jumps based on the unsigned value of the operands, rather than the signed value. This can be useful in certain situations where unsigned values are being used, but a signed comparison is still required.

 

---------
Why do some jump instructions like "JGT" appear in both your signed, and unsigned jump instruction lists?

 

You are correct that some jump instructions, such as JGT, appear in both the signed and unsigned jump instruction lists in ASM9900 assembler. This is because these jump instructions can be used with either signed or unsigned operands, depending on the context in which they are used.

For example, the JGT instruction can be used to perform a jump if the result of a comparison is greater than zero, whether the operands are signed or unsigned. In the case of signed operands, JGT performs a jump if the result of the comparison is greater than zero and the operands have the same sign. In the case of unsigned operands, JGT performs a jump if the result of the comparison is greater than zero and the operands are treated as unsigned values.

Similarly, the JNE instruction can also be used with either signed or unsigned operands, and it performs a jump if the result of a comparison is not equal to zero, whether the operands are signed or unsigned.

 

In ASM9900 assembler, whether a jump instruction is signed or unsigned depends on the type of comparison being performed, which in turn depends on the type of operands being compared. This is why some jump instructions, such as JGT, appear in both the signed and unsigned jump instruction lists.

 

---------
What determines if an operand is signed or not?

 

In ASM9900 assembler, the sign of an operand is determined by the most significant bit (MSB) of the operand. If the MSB is set (i.e., equal to 1), then the operand is considered to be negative and is treated as a signed value. If the MSB is clear (i.e., equal to 0), then the operand is considered to be non-negative (i.e., positive or zero) and is treated as an unsigned value.

For example, the decimal value -1 would be represented in two's complement notation as 0xFFFF, where the most significant bit is set. This would be interpreted as a signed value when used as an operand in ASM9900 assembler. On the other hand, the decimal value 1 would be represented in binary as 00000001, where the most significant bit is clear, and would be interpreted as an unsigned value when used as an operand.

 

It's worth noting that some instructions in ASM9900 assembler can be used with either signed or unsigned operands, while others are specifically designed for signed or unsigned operands. For example, the addition and subtraction instructions can be used with either signed or unsigned operands, while the shift instructions are designed for unsigned operands only. It's important to use the correct instruction for the type of operand being used in order to ensure correct behavior of the program.

 

...so here's the bit I tripped on:

 

... the JGT instruction can be used to perform a jump if the result of a comparison is greater than zero, whether the operands are signed or unsigned. In the case of signed operands, JGT performs a jump if the result of the comparison is greater than zero and the operands have the same sign. In the case of unsigned operands, JGT performs a jump if the result of the comparison is greater than zero and the operands are treated as unsigned values.

 

 

 

Edited by retrodroid
Link to comment
Share on other sites

Everyone knows one or another guy who claims to be extremely well informed, explaining the world to their environment as desired or not, with elaborate explanations, sounding like an expert beyond any doubt ... but should you happen to know a bit more, you notice that this person keeps telling rubbish to people due to "harmful half-knowledge" (not sure about the suitable translation of what we call in German "gefährliches Halbwissen"), spreading rumors and conspiracy theories. This results from picking up information from everywhere without really understanding it.

 

I'm afraid ChatGPT will greatly assume this role.

 

[Edit: Just to be clear, I am not referring to anyone here. I don't even know who could match.]

  • Like 1
Link to comment
Share on other sites

I think the best way to train people on this problem is turn it into Decimal first.

In TI99/4A memory >0000 to >FFFF it looks to the novice like 0 to 65535 but THAT IS WRONG.

 

Memory of the 9900 is -32768 (>8000) to 0 (>0000) to 32767 (>7FFF)

 

So think of 0 (>0000) as center of memory and it has negative on left and positive on right.

  • Like 1
Link to comment
Share on other sites

That's a neat way of looking at it.. but I don't think you should tell anyone the other way is wrong.

 

8000   Scratchpad RAM and memory-mapped devices

A000

C000   24K RAM

E000

0000   ROM

2000   8K RAM

4000   DSR

6000   Cartridge ROM

 

Edit: Context is important.  I shouldn't have poked the bear

Edited by PeteE
Link to comment
Share on other sites

16 minutes ago, PeteE said:

That's a neat way of looking at it.. but I don't think you should tell anyone the other way is wrong.

 

8000   Scratchpad RAM and memory-mapped devices

A000

C000   24K RAM

E000

0000   ROM

2000   8K RAM

4000   DSR

6000   Cartridge ROM

I work with XB and GPL and Assembly.

Unless you are working with Floating point you can NEVER see above 32767 and I would like you show me how without Floating Point in XB.

I am just showing that CALL LOAD(32768,0) will crash every time with "NUMERIC OVERFLOW"

See even in the CALL LOAD(32768,0) is a Floating Point value but still crashes.

 

When you start to learn next level from XB to say GPL or Assembly you need to understand this.

I have been asked by people over the years about this over and over and over again...

 

Link to comment
Share on other sites

Well I've gotten my routine working now using JL/JH instead of JLT/JGT so that's nice. Much more elegant syntax this way and saves a few instructions.

 

The first time I fell down this well I was actually trying to use signed integers (-1/0/1) and finally figured out how to make that work. This time, I wasn't thinking *at all* about signs since my values were just bytes in my mind, which is probably why it never occurred to me that the signing was the issue. Anyway, I've learned a bit along the way so I guess that's the main thing. It's a bit tricky, especially when you only encounter it a few times, weeks apart.  I'm getting older, and apparently a bit dense. 🤷‍♂️

 

Regarding ChatGPT, I find it remarkable that it knows anything at all about ASM9900, and its explanation of how signed operands are stored was on the money. Based on where we are at already with social media and misinformation and the largish segment of the population either unwilling or unable to discern actual truths from stated fictions, I find little to be hopeful about once everyone is relying on AI generated "knowledge". When virtually everything to see in a digital format can be convincingly faked, there is no "real" anymore, other than what you can observe that isn't on a screen.
 

  • Like 1
Link to comment
Share on other sites

RXB: "I think the best way to train people on this problem is turn it into Decimal first.

In TI99/4A memory >0000 to >FFFF it looks to the novice like 0 to 65535 but THAT IS WRONG.

Memory of the 9900 is -32768 (>8000) to 0 (>0000) to 32767 (>7FFF)

So think of 0 (>0000) as center of memory and it has negative on left and positive on right.

Unless you are working with Floating point you can NEVER see above 32767 and I would like you show me how without Floating Point in XB.

When you start to learn next level from XB to say GPL or Assembly you need to understand this."

 

This is half correct. In assembly numbers are -32768 to 32767, but they are also 0 to 65535. So at the same time, >FFFE is both -2 and 65534. You can use whichever way works best for your application and that is what needs to be understood. (As Retrodroid now does)

XB chooses to use the former approach, but at least for addresses they could just as easily done it the other way, and that would make CALL LOAD easier to figure out.

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

Thanks and if you do a CALL LOAD(65534,0) you get a crash but not a CALL LOAD(-2,0)

Yes the same, but one will never work, hence why I train people in XB to think of a line with negative to 0 and positive on a single line.

 

-32768...  -3        -2        -1        0         1          2          3       ...32767

>7FFF...   >FFFD  >FFFE  >FFFF  >0000  >0001  >0002  >0003  >7FFF 

 

This below will never work in a CALL LOAD hence why I do not use it in my documents.

 

0          1          2          3         ... 65535

>0000  >0001  >0002  >0003  ...>FFFF

 

I fully understand what you are saying but this will confuse people quickly if used.

Link to comment
Share on other sites

The negative addresses as used in Extended Basic are, in my view, artifacts that come from the lack of unsigned types in TI BASIC and Extended Basic. Also, because these BASICs only have a float type for numbers, which is typically signed, TI decided to use the two's complement interpretation of 16-bit numbers. However, I guess you won't find anyone outside of the TI realm who would agree that negative addresses are a good idea.

  • Thanks 1
Link to comment
Share on other sites

7 hours ago, mizapf said:

Yes, we'll be increasingly busy with cleaning up the rubbish that ChatGPT leaves behind. The statement about JGT is nonsense.

I am sure you are right at this point in time. This is AI in 2023. 

 

For perspective this was a car in 1923. :) 

Car of the Week: 1923 Ford Model T touring - Old Cars Weekly

 

Link to comment
Share on other sites

People are working on a functional AI since the 70ies, somewhat similar to fusion power. There has not really been a breakthrough in the recent years - instead, many people redefined "AI" to include machine learning and big data analysis, and now there is "intelligence" behind every corner. Myself, I was also involved in the research some time ago when I wrote my dissertation about mobile/intelligent agents ... in 2002.

 

Neither ML nor BD is related to ideas that resemble "intelligent behaviour". I don't think that ChatGPT is an example of artificial intelligence (in the original sense).

  • Like 1
Link to comment
Share on other sites

1 minute ago, mizapf said:

People are working on a functional AI since the 70ies, somewhat similar to fusion power. There has not really been a breakthrough in the recent years - instead, many people redefined "AI" to include machine learning and big data analysis, and now there is "intelligence" behind every corner. Myself, I was also involved in the research some time ago when I wrote my dissertation about mobile/intelligent agents ... in 2002.

 

Neither ML nor BD is related to ideas that resemble "intelligent behaviour". I don't think that ChatGPT is an example of artificial intelligence (in the original sense).

I get your point.  AI was nothing for 50+ years. I watched it too.

There seems to be a step change however in the last 5 years.   Alpha Go for example, discovered things about Go that people didn't notice before, after 1000 years. (time?) 

Once can argue that it is not "intelligence" but it is moving in that direction.

There seems to be a difference in the ability of Neural Networks at the scale they are being implemented.

I'm an observer only and you have professional insight but it seems to be moving in a direction that could create "intelligence". 

And... maybe human intelligence is a long way off but how about dog level or something in that range?

Link to comment
Share on other sites

10 hours ago, retrodroid said:

Here's an interesting and informative chat I had about the topic with ChatGPT:

 

Sorry, but most of that is gobbledygook. See  the spoiler below:

 

Spoiler

The ASM9900 assembler is a symbolic assembler for the Texas Instruments TMS9900 microprocessor.

 

The unsigned jump instructions in ASM9900 assembler are:

 

{ JLT  - Jump if Less Than }                        ««--------SIGNED

JLE    - Jump if Less Than Low or Equal

{ JEQ - Jump if Equal }                               ««--------sign not considered

JHE   - Jump if High or Equal

{ JGT - Jump if Greater Than }                   ««--------SIGNED

{ JNE - Jump if Not Equal }                         ««--------sign not considered

{ JNC - Jump if No Carry }                         ««--------sign not considered

{ JOC - Jump if Overflow Clear on Carry }  ««--------sign not considered

{ JNO - Jump if No Overflow }                    ««--------sign not considered

JIN    - Jump Indirect                                ««--------no such instruction!!

 

The signed jump instructions in ASM9900 assembler are used to perform comparisons and jumps based on signed integer values. The signed jump instructions in ASM9900 assembler are:

 

{ JL    - Jump if Less Than Low }                     ««--------UNSIGNED

JLEU  - Jump if Less Than or Equal Unsigned ««--------no such instruction!!

{ JH   - Jump if High }                                    ««--------UNSIGNED

{ JLE  - Jump if Less Than Low or Equal }       ««--------UNSIGNED

JGT   - Jump if Greater Than

JNEU - Jump if Not Equal Unsigned               ««--------no such instruction!!

JC     - Jump if Carry Set                               ««--------no such instruction!!

JO     - Jump if Overflow Set                         ««--------no such instruction!!

{ JNO - Jump if No Overflow }                       ««--------sign not considered

JID    - Jump if Indirect Data                         ««--------no such instruction!!

 

Strictly speaking, there are only two conditional jump instructions that depend on comparisons that treat numbers as signed:  JGT and JLT. These are the only instructions that test the “Arithmetic Greater Than” status bit.

 

Also strictly speaking, there are only four conditional jump instructions that depend on comparisons that treat numbers as unsigned: JH, JHE, JL, and JLE. These are the only instructions that test the “Logical Greater Than” status bit.

 

None of the other conditional jump instructions depend on comparisons that consider a number as signed/unsigned.

 

...lee

  • Like 3
Link to comment
Share on other sites

6 minutes ago, Lee Stewart said:

 

Sorry, but most of that is gobbledygook. See  the spoiler below:

 

  Hide contents

The ASM9900 assembler is a symbolic assembler for the Texas Instruments TMS9900 microprocessor.

 

The unsigned jump instructions in ASM9900 assembler are:

 

{ JLT  - Jump if Less Than }                        ««--------SIGNED

JLE    - Jump if Less Than Low or Equal

{ JEQ - Jump if Equal }                               ««--------sign not considered

JHE   - Jump if High or Equal

{ JGT - Jump if Greater Than }                   ««--------SIGNED

{ JNE - Jump if Not Equal }                         ««--------sign not considered

{ JNC - Jump if No Carry }                         ««--------sign not considered

{ JOC - Jump if Overflow Clear on Carry }  ««--------sign not considered

{ JNO - Jump if No Overflow }                    ««--------sign not considered

JIN    - Jump Indirect                                ««--------no such instruction!!

 

The signed jump instructions in ASM9900 assembler are used to perform comparisons and jumps based on signed integer values. The signed jump instructions in ASM9900 assembler are:

 

{ JL    - Jump if Less Than Low }                     ««--------UNSIGNED

JLEU  - Jump if Less Than or Equal Unsigned ««--------no such instruction!!

{ JH   - Jump if High }                                    ««--------UNSIGNED

{ JLE  - Jump if Less Than Low or Equal }       ««--------UNSIGNED

JGT   - Jump if Greater Than

JNEU - Jump if Not Equal Unsigned               ««--------no such instruction!!

JC     - Jump if Carry Set                               ««--------no such instruction!!

JO     - Jump if Overflow Set                         ««--------no such instruction!!

{ JNO - Jump if No Overflow }                       ««--------sign not considered

JID    - Jump if Indirect Data                         ««--------no such instruction!!

 

Strictly speaking, there are only two conditional jump instructions that depend on comparisons that treat numbers as signed:  JGT and JLT. These are the only instructions that test the “Arithmetic Greater Than” status bit.

 

Also strictly speaking, there are only four conditional jump instructions that depend on comparisons that treat numbers as unsigned: JH, JHE, JL, and JLE. These are the only instructions that test the “Logical Greater Than” status bit.

 

None of the other conditional jump instructions depend on comparisons that consider a number as signed/unsigned.

 

...lee

I just got "lucky" then with my choices of conditional jump instructions, but at least it was a learning opportunity. :)

 

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   1 member

×
×
  • Create New...