Jump to content
IGNORED

xdt99: New TI 99 cross-development tools available


ralphb

Recommended Posts

On 1/13/2021 at 3:06 PM, ralphb said:

I've released version 3.1.0 of xdt99, in which I only updated xas99.  The new features, which are partially incompatible with 3.0.0, are:

 

BANKS.  To define a bank, use BANK <b>, [<addr>].  If an address is given, it sets the base address for other BANK directives without address.  Again, BANK ALL starts at the lowest address after all other banks, and raises the base address.

 

SAVES.  I've reverted the "minimal" address range when using SAVE and now generate values for the entire range.  For example, a SAVE >2000,>4000 yields a file of 8K.  To get the previous behavior back, use the minimize option -M.

 

AUTO.  A new directive AUTO determines the program location where all auto-generated constants should be places.  Omitting AUTO is an error.  Auto-constants are now bank-aware, so AUTO should be placed in each bank where auto-constants are used.  After AUTO, no further auto-constants must be used.

 

BANK CROSS-CHECKS.  I now disabled cross-checks by default.  To enable them, use -X.

 

MACROS.  Labels should now be retained.  Also, the listing now contains information about source units/macros entered and resumed, e.g.


     **** **** > source1.asm
               COPY "source2.asm"
     **** **** > source2.asm
               ...
               < source1.asm
               ...
               .mac r0, r1
     **** **** > MAC
               ...
               < source1.asm

COLORS.  The output of warnings and errors now uses color.  On Linux and macOS, color is on by default.  Since older version of Windows don't support so-called ANSI esc sequences, it's off by default.  To enable/disable color manually, use --color on/off.

 

MISC.  Some additional warnings about incorrect operand usage, and more.

Ralph,

 

Tim and I were discussing the other day about the ability to use other non TI/Geneve programs to assemble MDOS with the direction moving forward to a github repository.

 

The biggest issue here lies in the GenPROG Linker and the linking process and the uses of the PAGES command to build the 18 x 8K segments of MDOS as a single program image file.  I'm guessing there are roughly 100'ish source files creating 50 various object files that are pieced together during the linking process.

 

I don't know the xdt99 tools that well or if you have reviewed the GenPROG package to know if there would be a workaround, or I will use the word "simpler" changes that could be done to the source to move things to an xdt99 platform for assembly and linking process to create the final image.

 

If you have some thoughts on the matter, it would be appreciated.


Beery

 

 

Link to comment
Share on other sites

14 hours ago, BeeryMiller said:

Tim and I were discussing the other day about the ability to use other non TI/Geneve programs to assemble MDOS with the direction moving forward to a github repository.

 

The biggest issue here lies in the GenPROG Linker and the linking process and the uses of the PAGES command to build the 18 x 8K segments of MDOS as a single program image file.  I'm guessing there are roughly 100'ish source files creating 50 various object files that are pieced together during the linking process.

 

I don't know the xdt99 tools that well or if you have reviewed the GenPROG package to know if there would be a workaround, or I will use the word "simpler" changes that could be done to the source to move things to an xdt99 platform for assembly and linking process to create the final image.

That would actually be very interesting to implement!  But even though I do own a Geneve, I haven't done anything with it yet -- postponed that after SDD is ready. ?

 

Assembling multi files at one is possible right now, also linking everything together to object code or binary.  Not sure if the Geneve uses the same format, though.  Also, chunking that into 8K segments is possible, but might need some extra handling.

 

I don't have the GenPROG package, at least IIRC.  Could you send that to me, please?  Also I'd need more documentation about the actual Geneve format.  I might have asked before, but are there any good sources for this?  (Feel free to PM me, since this info might be offtopic.)  I also do have a stuffed Geneve binder, maybe that contains file specs?

 

Not that I could work on that immediately, but it'd be nice to switch between projects at times ...

  • Like 4
Link to comment
Share on other sites

  • 1 month later...
xas99.py -R -b -L tipi.list -o tipi.bin rom.a99
> *** <2> **** - 
***** Warning: Unused constants: BASESTK

Took me a while to figure out BASESTK was one of my symbols, cause it's in lowercase in my source... A nice feature would be if the location of the definition could be included in the warning.

 

Link to comment
Share on other sites

On 2/25/2021 at 6:47 AM, jedimatt42 said:

xas99.py -R -b -L tipi.list -o tipi.bin rom.a99
> *** <2> **** - 
***** Warning: Unused constants: BASESTK

Took me a while to figure out BASESTK was one of my symbols, cause it's in lowercase in my source... A nice feature would be if the location of the definition could be included in the warning.

 

Should be very possible ... I figured you could just search for the symbol, but that's more difficult if you have multiple sources.

 

As for the case, xas99 is case-insensitive, but converts everything to uppercase internally.

Link to comment
Share on other sites

6 hours ago, ralphb said:

Should be very possible ... I figured you could just search for the symbol, but that's more difficult if you have multiple sources.

 

As for the case, xas99 is case-insensitive, but converts everything to uppercase internally.

Yep, I should have

grep -i *.a99

but was tired and making mistakes. As one does. :)

  • Like 1
Link to comment
Share on other sites

  • 8 months later...

I'm currently working, among other things, on improving the cycle counting.  But there is one instruction where the TMS 9900 datasheet gives me headaches: BLWP.

 

image.png.36cd35086cb52de42ad881c444feb06a.png

 

image.png.e975f3a9af0d8c507fa85cec64d0aa28.png

The datasheet states that BLWP needs 6 memory accesses (third column), plus 0 to 2 accesses depending on the addressing mode t of its argument (table A).

 

Now for the case "BLWP @addr" we have 1 access for the opcode, 1 access for the target address value (i.e., LC + 2), and we have 3+3 accesses for writing to R13, R14, R15 (with read-before-write).  That is a total of 8 memory accesses, instead of the listed 7.  Also, we need to read two more words at the address the targets points to.  These accesses cannot be right then.

 

But if we assume that BLWP doesn't do read-before-write, we have 5 accesses, plus 2 for reading WP and LC words at the target.  But is it possible that BLWP doesn't do read-before-write?

 

(Compare to "BL @addr": 1 access for opcode, 1 for target, 1+1 for R11.  Here we seem to have read-before-write.)

 

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

Hi Ralph,

 

for those advanced topics I recommend the "9900 Family Systems Design" book: https://ftp.whtech.com/datasheets and manuals/Datasheets - TI/9900-FamilySystemsDesign-1stEdition/9900-FamilySystemsDesign-04-Hardware Design.pdf, pages 4-89 (PDF pages 89+).

 

Here is a photo (I was too lazy to type). As you can see, there is no read-before-write for R13-R15.

 

 

Screenshot_20211105_193250.png

Screenshot_20211105_193454.png

  • Thanks 2
Link to comment
Share on other sites

And here is BL, also without read-before-write. But note the comment.

 

The Branch instructions have a pecularity: Usually, if the source operand indicates an address, the instruction processes the contents of that address. However, BL and B do not quite work this way; they branch to the address as if it were immediate. Hence, the CPU fetches the contents of that address, discards them, and does the branch.

Screenshot_20211105_193709.png

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

16 hours ago, Asmusr said:

I never noticed the cycle counting in the list file before. Are you assuming a work space in scratch pad? 

Yes, right now it uses some fixed assumptions, like workspace in scratchpad, and everything else not.

 

I hope to improve this, but indirect addressing is a problem.  I plan to offer some pragmas (special comments) where the user can supply the missing information, if they care to.  Since I don't do symbolic execution, this is only useful for small snippets, obviously.

  • Like 1
Link to comment
Share on other sites

On 11/5/2021 at 7:35 PM, mizapf said:

Here is a photo (I was too lazy to type). As you can see, there is no read-before-write for R13-R15.

Now that I actually peruse that document, I see one read access for the opcode, 3 write accesses for register R13-R15, and one read access for the new PC.

 

But what about reading the new WP?  Same for BL, I only see two accesses, but not the reading of the target.

 

Am I reading those lists wrong?  I'm just counting the lines where it says "Memory access".  ?

 

EDIT: I should mention that 5 memory accesses (plus reading of the argument) is consistent with my datasheet, but what is it about WP?

2 accesses for BL is also correct, but where does the reading of the target word happen?

Edited by ralphb
Link to comment
Share on other sites

The operand is read during the "data derivation sequence". This is the most obvious difference to the 9995, which has an "address derivation sequence" instead.

 

That means for BLWP @>A000:

1 Read the BLWP instruction itself

2 Do something internal

 

DDS:

3 Internal

4 Internal

5 Read the word after BLWP (>A000)

6 Internal

7 Read the word at >A000 (new WP)

 

8 Internal

9 Internal

10 Write current status register to nWP+30 (R15)

11 Internal

12 Write current PC+2 to nWP+28 (R14)

13 Internal

14 Write current WP to nWP+26 (R13)

15 Internal

16 Read word at >A002 into PC

17 Internal

  • Like 1
Link to comment
Share on other sites

Yes, @>xxxx or @XXXX is "symbolic". This is what I meant above: The instructions BL and B somewhat misuse the mode by branching to that address (as if it were immediate) instead of using the contents of that address.

 

This was improved in the 9995 where only the address is determined and not automatically read from.

  • Like 1
Link to comment
Share on other sites

OK, that computes, so that leaves only one question: How fast are CRU accesses?

 

In the datasheet, it's just listed as one memory access, but what does that mean on the TI 99?  Are there any waitstates involved?

 

EDIT: And any difference between reading and writing?

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

CRU accesses should not produce wait states in the TI-99/4A console, as MEMEN* is high (not active) and the wait state logic is not active (see snippet of the schematics). The data sheet of the 9900 do not say anything about READY with respect to CRU, but the 9995 does allow for wait states in CRU access.

Screenshot_20211107_154816.png

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

This is why I always thought CRU should be checked on a particular bit as faster then many ways we see people do it with things like KSCAN

Register 12 always has a copy of the CRU bits so would it not be faster to check that bit then to scan the entire keyboard?

Link to comment
Share on other sites

Here's another puzzle for STCR:

 

The Hardware Design manual describes C decode cycle for reading CRU bits and C' cycles for shifting the result so that it is right-aligned, among other cycles.  According to the manual,
 

Quote

 

C' = 8-C-1  if  C<= 8

C' = 16-C  else. 

 

 

Not sure if they really mean 8-C-1 or 8-(C-1), because the former might become negative.

 

The total decode cycles for C and C' is then
 

Quote

 

C + C' = C + 8-C-1 = 7  if C <= 8    (or C + 8-(C-1) = 9)

C + C' = C + 16-C = 16  else

 

 

If we assume a register as argument, we get for the total clock cycles 22 + 4 + 2(C + C') = 26 + 2 * 16 = 58 clock cycles for C>8.  This is mostly consistent with the datasheet, but that lists 60 clock cycles for C=16.

 

image.png.e84a73978b73b18d68acaf71ede63741.png

 

For C < 8, we get 26 + 2*7 (or 2*9) = 40 (or 44), whereas the datasheet lists 42.  And for C=8 we still get 40 or 44, and the datasheet lists 44.

 

So what is the logic behind the datasheet?  Or are the formulas in the Hardware Design manual incorrect?

 

  • Like 2
Link to comment
Share on other sites

Also, for the shift operations SLA etc., if the jump of count != 0 in decode cycle 3 or 4 (I think it's 4)?

 

image.thumb.png.50af23b328e8e2eb869d3b1108de3061.png

EDIT: Actually, let me state that more precisely: If count != 0, do we have 5, 6 or 7 decode cycles, without C?

 

image.thumb.png.d18725e8b8af0475eabd88cf214003ce.png

Edited by ralphb
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...