PDA

View Full Version : TMS-9900 question



commodorejohn
May 25th, 2011, 02:42 PM
So I've got a couple of these CPUs that I've scavenged from broken TI-99/4As, and I've kind of been toying with the idea of building a little homebrew computer around them. My question is, is there any reason at all to use the CRU I/O bus? I've been looking at the manual for the CPU, and the CRU seems like the most needlessly complicated way to access peripherals that I've ever seen. Is there a compelling reason not to just ignore it and settle for memory-mapped I/O?

Chuck(G)
May 25th, 2011, 04:24 PM
It depends. The CRU is sort of a cool bit-serial bus, but without the right peripheral support, is pretty useless.

You have to understand that the TMS9900 was derived from TI's 990 minicomputers. All but a couple of models of the 990 also used the TILine bus--a nice parallel bus similar to DEC's Unibus. However, the TMS9900 doesn't implement TILine.

So, yeah, go ahead and use memory-mapped I/O unless there's some compelling reason to do otherwise.

commodorejohn
May 25th, 2011, 04:39 PM
That's what I figured - it looked like some kind of legacy holdover. Was it included on the TI-990 for compatibility with something older, or was it just a weird design decision to have two I/O buses, one of which was far more complicated?

Chuck(G)
May 25th, 2011, 05:19 PM
That's what I figured - it looked like some kind of legacy holdover. Was it included on the TI-990 for compatibility with something older, or was it just a weird design decision to have two I/O buses, one of which was far more complicated?

Ah, good thing you asked--I'd almost forgotten about it. Yes, the TI960 was an early 1970s mini that TI called its "bit-pusher" and played up the CRU as the perfect process-control interface. Note that the 960 instruction set was completely different from the 990. The 980 was the general-purpose mini marketed by TI before the 990 and did not have a CRU.

commodorejohn
May 25th, 2011, 05:49 PM
Ah, interesting. Process control would explain a lot about the "large numbers of individually-addressable bits" design (though still...yikes.)

matthew180
June 29th, 2011, 09:05 AM
The CRU design is definitely convoluted, but there *are* some instructions dedicated to using it. But like Chuck(G) said, it really depends on your design.

To me it seems like the 9900 was the test-bed for a lot of ideas about CPU design, and unfortunately the designers decided to try them all out in a single CPU. The CRU I/O, no stack pointer, having the general purpose registers stored in external RAM (allegedly to speed up context switching), read-before-write on all memory operations, etc.

Also, the read-before-write makes memory mapped I/O more complicated.

I have thought a lot about making a home-brew around the 9900 too, since I really like the assembly language on the CPU, but they really messed up the hardware implementation. But, we can fix that now. :-) With and FPGA you can implement the 9900 and correct those little problems, plus run it faster (100MHz 9900 anyone?) I've actually started work on a 9900 core (seems no one has done that yet), so we'll see how it goes.

If you do make a system around the 9900, please make all the RAM 16-bit and zero wait-state. That is probably the single biggest kludge of the 99/4A.

Chuck(G)
June 29th, 2011, 09:47 AM
"No stack pointer" is perhaps an oversimplification. The 990/9900's idea of a workspace pointer allows one to form a linked list of workspaces, creating a stack and is quite efficient in concept, but not so good in execution, as register references are also (slow) memory references.

When the 990 came out, there were plenty of systems without a hardware stack and an inspection of architectures in use at the time will give you an idea of the thinking.

Consider, for example, the IBM S/360. No stack and the subroutine linkage convention was very similar to that of the 990/9900. A routine is "called" via a branch and link (BAL), the routine stores (STM) the registers of the caller in the savearea of the caller, then loads (LM) the registers from the current savearea. The 990 skips the separate load and store and simply uses a pointer to a new workspace that's linked to the workspace of the calling routine. On the STAR, we had 256 64-bit registers and a SWAP instruction that loaded the registers from one location, while storing to a different location (very efficient on a core-based machine, not so much on semiconductor RAM).

You can see how the 9900 instruction set has evolved by inspecting the TI MSP430 microcontroller family. Gone is the workspace pointer and CRU, replaced by traditional stack architecture but the instruction set will otherwise look very familiar.

TI's got some very inexpensive dev kits for the MSP430 (http://www.ti.com/corp/docs/landing/mcu/index.htm?DCMP=MSP430&HQS=Tools+OT+ez430) if you're curious about the microcontroller.

matthew180
June 29th, 2011, 10:03 AM
Yeah, I saw the MSP430 and I even have one of the devkits (unopened as of yet.) I chuckled when I saw the instruction set and how similar to the 9900 it is. Makes me wonder if the MSP430 designer worked on the 9900 series? I need to crack open my devkit; should be fun to mess with. :-)

Chuck(G)
June 29th, 2011, 10:15 AM
Old architectures never die; they just mutate.

The National PACE was a single-chip implementation of the IMP-16 multi-chip processor, which was modeled on the Data General NOVA architecture. The GI CP1600 was modeled on the PDP-11. Both made fatal errors, however. PACE required a bunch of fairly exotic support chips and a 4-phase clock and was very, very slow. The CP1600 was slow and squandered code space by using only 10 bits of a 16-bit instruction word--and it was again, slow. The Fairchild 9440 was a fairly complete implementation of a DG MicroNOVA and was also very slow.

PIC µCs still use a design based on a 1975 GI support chip for the CP1600, except for the PIC32 which uses a MIPS 4000 instruction set (not exactly a spring chicken, either).

...and of course, the x86 chips of today are descended from the lowly 8008 to the point where you can recognize features and instructions.

Old designs don't, it seems, die or even fade away... :)

commodorejohn
June 29th, 2011, 10:30 AM
To me it seems like the 9900 was the test-bed for a lot of ideas about CPU design, and unfortunately the designers decided to try them all out in a single CPU. The CRU I/O, no stack pointer, having the general purpose registers stored in external RAM (allegedly to speed up context switching), read-before-write on all memory operations, etc.
Yeah, it's definitely an interesting design. The stackless approach isn't too bad - the link register idea is used in a number of different architectures, and while it's moderately annoying having to save it yourself when making subroutine calls, it does actually save you a stack push if a called subroutine isn't going to call anything else. (Though that's not quite such an advantage given that registers are in memory, but oh well.)

The registers-in-memory thing is kind of weird - definitely an interesting idea with some potentially useful applications (fast task-switching, for instance,) but then again, it kinda bottlenecks things...huh.

If you do make a system around the 9900, please make all the RAM 16-bit and zero wait-state. That is probably the single biggest kludge of the 99/4A.
Oh, definitely. Half the reason I'm considering this is I've got a couple of 32Kx8 FRAM chips I got as a sample that I figure I can put to use - all I've got to do is double them up, and presto! 16-bit nonvolatile main memory. (And way more than fast enough for zero-wait-state, to boot - it might even be possible to run two CPUs off of it, but let's see if I can even get one working first ;D)

matthew180
June 29th, 2011, 11:42 AM
Chuck(G): you have quite the knowledge base stored away there! :-) Speaking of DG, one of my favorite books recently was "The Soul of a New Machine" which chronicled the building of one of Data General's last 16-bit minis.

It's funny (or not so much) how much influence the "old" systems and designs have on modern systems. And everyone thinks we are *so* advanced from the good-old-days... ha. :-)

I never programmed an 8008, but I did learn 8088/8086 assembly after the 9900, and you can definitely see the remnants from those processors in the modern x86 CPUs. I can't decide if that is a good thing or depressing?

commodorejohn: if you have not picked video subsystem yet, you may be interested in my little project, the F18A (http://codehackcreate.com/archives/30), which is a pin-compatible replacement for the 9918A VDP with VGA output. I'm almost done with board revisions (I hope) and it should be ready this summer (again, I hope).

commodorejohn
June 13th, 2012, 06:05 PM
Hey, coming back to this thread, I've been trying to build a TMS-9900 emulator so's I can test some ideas for this project, and I've been trying to figure out the read-before-write behavior. I can understand why it's done on byte writes, but I can't figure out whether it does that on word writes (seems wasteful and pointless,) or only on byte writes. I've even seen someone state that it applies for word writes only on instructions that have a byte variant. I've seen claims made for each behavior online, and I can't find anything about it in the manual. Does anyone know which behavior is actually implemented in the CPU?

billdeg
June 14th, 2012, 02:31 PM
Not sure if this will give clues for your project. I sold this off years ago after losing interest. A four board homebrew system based arouond the 9900

http://vintagecomputer.net/ti/TI%2D990%2D101/

Bill

geoffm3
June 19th, 2012, 01:13 PM
Wasn't the CRU used for the GROM support in the cartridge software?

marc.hull
June 20th, 2012, 08:24 PM
Hey, coming back to this thread, I've been trying to build a TMS-9900 emulator so's I can test some ideas for this project, and I've been trying to figure out the read-before-write behavior. I can understand why it's done on byte writes, but I can't figure out whether it does that on word writes (seems wasteful and pointless,) or only on byte writes. I've even seen someone state that it applies for word writes only on instructions that have a byte variant. I've seen claims made for each behavior online, and I can't find anything about it in the manual. Does anyone know which behavior is actually implemented in the CPU?

I am fairly certain that the read before write issue occurs on every write access regardless of whether or not it has a byte variant. It is fairly invisible as it is performed by the CPU and requires no other support.

The CRU is a pretty neat design. It more or less allows a programmer to easily control hardware without sacrificing memory space. It is more or less a bus under the normal bus. Probably a PITA to implement as you need support IC's (9901.)

Memory mapping is an easy to implement strategy on the 9900. If you keep your ports at word boundaries and access them with the even byte then you don't risk reading a port accidentally.

How far are you on your implementation ?

commodorejohn
June 20th, 2012, 08:57 PM
Oh, it's wholly theoretical at this point; I haven't even desoldered the CPUs from the junk boards yet. The emulator is coming along well in terms of basic coding, but we'll see how long it takes to get into any kind of usable, non-buggy state ;)

geoffm3
June 21st, 2012, 06:51 AM
Oh, it's wholly theoretical at this point; I haven't even desoldered the CPUs from the junk boards yet. The emulator is coming along well in terms of basic coding, but we'll see how long it takes to get into any kind of usable, non-buggy state ;)

Are you starting from scratch, or using bits and pieces from MESS or one of the TI emulators?

commodorejohn
June 21st, 2012, 08:25 AM
Starting from scratch. The whole reason I'm doing it is because it seems like interfacing to any of the existing ones would be more trouble than it's worth. (The homebrew TI emulators less so than MESS, which is a nightmare of intertwined macros from countless different files, but they still all seem to be designed to fit their own particular project, and not for general-purpose usability.)

commodorejohn
June 21st, 2012, 03:36 PM
Okay, I think I've figured it out; the TMS-9900 data manual has a listing of number of memory accesses along with the instruction times, and it's not too difficult to work out the answer from there. MOV and MOVB both have four memory accesses (instruction fetch, source fetch, destination fetch, destination write, I theorize,) while LI, which has no byte variant, has three (instruction fetch, immediate fetch, destination write.) (Other immediate instructions have four, but they need a source fetch.) Seems like most other instructions fit the pattern for the "read-before write only on instructions with a byte variant" theory, so I'm going to go out on a limb and say that's the correct one.

commodorejohn
June 25th, 2012, 03:07 PM
Okay, next question: RESET has its own separate line on the chip with immediate response (i.e. doesn't finish out the current instruction,) but it's also interrupt #0. The data manual calls interrupt #1 "the highest external-priority interrupt" (they number everything backwards,) but the only criterion it gives for interrupt acknowledgement is that the interrupt code being signaled to the CPU is less than or equal to the value of the status-register interrupt mask. That is satisfied when the interrupt code is 0 no matter what the interrupt mask is, so I have to wonder if it's not possible to signal RESET via the normal interrupt lines. You'd lose the immediate acknowledgement, and in decrementing the interrupt-mask value it'd reset it to 15 (mask no interrupts,) but it doesn't seem to say it wouldn't work at any point...

marc.hull
July 1st, 2012, 09:55 AM
Reset is not maskable so it doesn't really apply.

commodorejohn
July 1st, 2012, 11:12 AM
Well yeah, it can't be masked, I'm just curious whether it's possible to trigger it as a normal interrupt as well as using its dedicated instant-response line.

marc.hull
July 2nd, 2012, 04:10 PM
Hmmmmm... I don't know. Would seem redundant to have the reset pin and a reset interrupt to perform a hard reset. I believe that on the TI99 all hard resets are done with the reset pin connected to circuitry on the MOBO (or switches on hacks.)

Same thing may apply to the load "interrupt" pin or the "hold" pin. I don't know If I would actually term them interrupts but rather processor functions triggered by external events (I know sounds like interrupts huh...) The difference being that they really cannot be controlled by software nor masked out (I don't think you can mask out the load" pin anyway nor trigger any of the 3 functions in software.)

You would probably find better info on one of the Y! groups, specifically ask for Stewart (he may even lurk here.) He has a lot of experience using and designing for TI 990 mini's where the interrupt functions is fully developed. The implementation on the ti99 is pretty restricted. I would wager he knows the scoop.

At any rate, it's about time to change you handle to TMSJohn isn't it ;-)

commodorejohn
July 2nd, 2012, 04:48 PM
Heh, nah, you gotta stay true to your first love...

commodorejohn
August 22nd, 2012, 02:12 PM
I've been kind of re-thinking the idea of this project lately, as I read up on the TMS-9995: despite being stuck on an 8-bit bus, it runs at a full 12MHz and features vastly improved instruction times thanks to internal re-jiggering. (Now if they'd only made a 16-bit equivalent!) Add to that the fact that it needs only one clock input and only 5v power instead of 5v and 12v, and I think I'm going to move my focus to using this instead.

And since it's 8-bit, I'm kind of wondering if it wouldn't be simplest to try and set it up as an N8VEM SBC...certainly make adding peripherals easier.

Ksarul
August 22nd, 2012, 04:26 PM
You could always look at the 99105/99110. They were 16-bit.

commodorejohn
August 22nd, 2012, 05:37 PM
I suppose that's a possibility...on the other hand, from what I gather, they only run at 6MHz internally even though the external clock is 24MHz (!?) which would make them slower than the 9995 even taking the 8-bit bus into account, and they also seem to be a bit more difficult to come by than the 9995...

marc.hull
August 26th, 2012, 05:11 PM
IIRC the 9995 runs @ 3Mhz. It uses the same 4 phase clock signal (externally divided). It is a faster CPU internally than the 9900 but again saddled by the data muxing. Seems like TI was always on the verge of a big thing and then shot themselves in the foot.

Pound for pound it is only slightly more powerful than the 9900 (dis regarding speed that is) with only 4(?) additional instructions. Otherwise compatible with the 9900.

Might be a more difficult chip to source ?



I suppose that's a possibility...on the other hand, from what I gather, they only run at 6MHz internally even though the external clock is 24MHz (!?) which would make them slower than the 9995 even taking the 8-bit bus into account, and they also seem to be a bit more difficult to come by than the 9995...

commodorejohn
August 26th, 2012, 06:29 PM
Huh, it looks like you might be right; now that I look at it again, it looks like 12 MHz might just be the input frequency for the built-in clock generator, as the instruction times supposedly go by CLKOUT, which runs at 1/4 that speed. Shoot. Maybe I'll take another look at the 99105 documentation...

marc.hull
August 31st, 2012, 02:51 PM
Well now don't despair, A 12Mhz crystal is just the "suggested" frequency ;-). I have had my ti running well at 3.58 Mhz via a 14.381 crystal for years. I even tried it at 4 MHZ and it ran ROM based games fine (albeit a bit fast.) The rest of the system had problems but since your talking a new computer with faster components I don't think 4Mhz would be an issue. Perhaps even 5 is stable....... Pretty hot for 1978-82ish ;-). If you use fast SRAM and are careful with the VDP and sound access then who knows......

commodorejohn
August 31st, 2012, 03:20 PM
Yeah, true...on the other hand, if the 99105 can hit 6MHz purely within spec, it might even be able to be pushed up to 7-8...guess we'll see whether I can even find one, the only one on eBay at the moment is a $70 part some UK reseller orders from a US warehouse they don't name... :/

Stuart
September 21st, 2012, 07:55 AM
Just come across this thread ... I'll add a couple of comments.

<is there any reason at all to use the CRU I/O bus?>

One reason might be is that it gives you single-chip solutions for single- and multi-bit I/O (the TMS9901) and RS-232 ports (the TMS9902), if your homebrew system requires such features.


<if you have not picked a video subsystem yet>

If for any reason you didn't fancy Matthews excellent F18A jobby, the video processor + video RAM + discrete video circuitry is conveniently arranged in the corner of the TI-99/4A board. If you get a copy of the TI-99 circuit diagram (freely available) you can easily follow the traces on the PCB and with two neat hacksaw cuts you can separate it from the rest of the board. You can then connect it to your homebrew system with the 8-bit data bus, a couple of control signals, and power. You could also just take the 9918 VDP and hook it up to a single, larger capacity byte-wide DRAM chip (rather than a bank of 8 single-bit DRAMs as designed) with the addition of an extra couple of logic gates - should be able to find the details on the web somewhere. The 9918 gives a direct NTSC composite video output.


From Bill Degnan: <Not sure if this will give clues for your project. I sold this off years ago after losing interest. A four board homebrew system based arouond the 9900>

I got the processor board from that system (thanks Bill!), and the card cage and other boards went to a colleague. <www.avjd51.dsl.pipex.com/tm990/tm990.htm>. Note that this wasn't a homebrew system as Bill suggests ... it is from the range of boards that TI designed and manufactured largely for process control applications.


<I'm just curious whether it's possible to trigger it (RESET) as a normal interrupt as well as using its dedicated instant-response line. >

Sort of, and not really! If you do a hardware reset, it will set the processor and peripheral devices (such as the TMS9901 and TMS9902) into a known state (they're all connected to the /RESET line), then the processor does a BLWP @>0000. You could do a 'software reset' in code by doing a BLWP @>0000 but that doesn't do a hardware reset on the peripheral devices. There is an RSET instruction that just sets a specific condition on the address bus and control lines - the intention is that this is decoded externally and used to trigger a hardware reset.


<as I read up on the TMS-9995: despite being stuck on an 8-bit bus, it runs at a full 12MHz>

As I think you worked out for yourself, the 9995 take a 12MHz clock, but this is divided by 4 internally so it runs at the same 3MHz as the 9900. I understand that the performance increase of the 9995 over the 9900 is largely due to the fact that it does instruction prefetch.

The 9995 regularly comes up cheap on ebay, and is an easier chip to 'homebrew' as you don't need to mess with multiple power supplies and the TIM9904 clock generator, and as the data bus is only 8 bits wide you don't need to program odd- and even-byte PROMs as you develop your code.

---

If you're interested, I've done 9995 and 99110 systems on breadboards, with the details available here <www.avjd51.dsl.pipex.com/tms9995_breadboard/tms9995_breadboard.htm> and here <www.avjd51.dsl.pipex.com/tms99110_breadboard/tms99110_breadboard.htm>. The second site also contains some simple benchmarks between the 9900, 9995 and 99110 in various configurations.

I did hear that the 99105/99110 is a difficult chip to play with as the bus timings are very tight, but either I was very lucky or the statement was exaggerated. They're fairly rare on ebay as you've found.

Stuart.

commodorejohn
September 21st, 2012, 09:34 AM
Hi, thanks for the advice!

Yeah, I kind of figured that would be how the reset thing worked. Not much practical use for it, but an interesting behavioral quirk. I hadn't gotten around to planning anything about video; the 9918 would work, to be honest, though I'm kind of thinking that it would be nicer if I could get ahold of a 9938 (seen in the MSX2, as well as the Geneve TI-99 accelerator/upgrade. (http://en.wikipedia.org/wiki/Geneve_9640))

I would like to use the 99105 or 99110 if I can get ahold of one, since they can go up to 6MHz and are 16-bit, but we'll have to see how that works out. (You wouldn't happen to have a spare, would you?)