apersson850
-
Content Count
1,063 -
Joined
-
Last visited
Posts posted by apersson850
-
-
No, it's more a question about that since an unexpanded TI 99/4A has almost nothing else but video memory. Hence almost everything that takes place goes through video memory. This includes the memory image transfer function, which is used for the Run program file option (#5) in E/A, to load and save BASIC programs and several other stuff.
-
It's not the crystal itself that's interesting, it's how the CPU runs internally. The 99/4A has a 48 MHz crystal inside for the CPU, but that's just to be able to generate all the phases of the main 3 MHz clock.
-
The TMS 99105 has stack support. So has for example the TI 990/12 minicomputer.
When I wrote TMS 99000 it was in a generic sense, since I didn't remember the detailed differences between the different introduced and planned versions of the TMS 99000 CPU.
-
You can define an alternate character set that's inverted. But there's not space to do that for all possible characters within the X-BASIC environment. Nor can you use bit map mode with BASIC, as you get a video memory conflict.
A loader that loads relocatable code can be anywhere, since per definition the code it's loading can be anywhere. But most larger programs are converted to memory images, which must load at a certain memory location.
The machine's support for loading memory images requires them to go to a buffer in VDP RAM, which is so large that you can't have bit map mode enabled when doing that. Not unless you don't care you'll literally see the file being loaded.
But once the file is loaded, you can check in the file where it's supposed to go in memory. If the file is on disk, you can do a sector read of the beginning of the file, and find out where it should be loaded. If you write your own loader, you can then read and load one sector at a time, instead of one up to 8 K byte memory image at a time.
Regarding the flipping cursor, you are right in your assumptions.
-
[Pedantic mode on!]
It's actually a 3 MHz processor, same speed (but more efficient) than the TMS9900. The 12 MHz crystal is internally divided to produce a 4-phase, 3 MHz clock.
[Pedantic mode off!]
True. One reason for the higher efficiency of the TMS 9995 is that it has one stage instruction pipelining. If I remember correctly, it also gets away with the read before write memory access implementation. It's not necessary with a byte-addressable CPU with a byte wide data bus. But it is on a byte-addressable CPU with word wide bus.
-
The TMS 9900 CPU implements the multi-chip CPU from the TI 990/9 minicomputer on one chip. Almost. It has a separate clock chip.
The TI 990/4 and TI 990/5 minicomputers were actually driven by the TMS 9900 CPU. The larger TI 990/10 and the TI 990/12 had more advanced CPU designs, more similar to the later TMS 99000 series of microprocessors.
When TI designed the TMS 9900, at a time when most other LSI manufacturers were starting to consider 8 bit designs, chip technology was such that fast memory designs were capable of following logic circuits in speed. Thus they gained flexibility without really sacrificing anything. But already by the time the TMS 9900 ended up in the TI 99/4A, this had started to change.
Although there's no dedicated stack pointer in the TMS 9900 (there is in the TMS 99000), there is autoincrement. So although a PUSH must be implemented by
DECT SP
MOV Rx,*SP
you can do a POP by simply
MOV *SP+,Rx
I've implemented pre-emptive multitasking within the p-system, and as a separate assembly thing on the TI 99/4A. As you state here, the TMS 9900 is efficient for this. But in the p-system case, you have to keep within the constraints of the PME, as it's supposed to work on Pascal level as well.
-
Things are generally different when running Extended BASIC. Back when I did, I used a DSRLNK that was a bit different compared to the one TI recommends in the E/A documentation. The one I used works regardless of whether the DSR is written in assembly language or in GPL. That has the advantage that you can store a memory image in a file in exactly the same way regardless of whether it ends up on disk or cassette.
This may not be an issue today, but I wrote some software that was intended to be used as subprograms for Extended BASIC, and could work also with systems having only 32 K RAM expansion but no disk system.
If you want to do something that requires learning quite a bit of the internal working of the computer, and Extended BASIC, but still is a project of limited size, you could write a program that makes the cursor in Extended BASIC flash not between the character it's covering and a black block, but between the character it's covering and that character inverted in a black block. Flipping the cursor like this could be enabled by CALL LINK("FLIP") and disabled by CALL LINK("NOFLIP").
This is a good educational exercise, because it's not trivial but still rather small in size.
-
Would you please expand on this a little, I'm intrigued.
Well, I've installed 64 K RAM expansion inside the console. All on 16 bit wide bus, the fastest the TMS 9900 can utilize.
Normally, only 32 K RAM is seen by the CPU, but it's possible to enabled the other 32 K RAM too, 8 K at a time, to overlay internal addresses like operating system, DSR space, cartridge port and I/O ports. Enabling all gives a contiguous 64 K RAM, but then you can't access VDP, sound etcetera without disabling RAM covering addresses 8000H-9FFFH while doing so.
It's also possible to disable the 32 K RAM part which acts like the normal memory expansion. When doing that, the normal memory expansion, if present, is instead visible, so it's possible to have two separate 32 K RAM expansions present at the same time, but available for use one at a time.
All this switching between different memory blocks is done with I/O bits (CRU), which means it's all under software control.
-
1
-
-
I was quite heavily involved in the user's group Programbiten in Sweden for some years. The group no longer exists.
-
3
-
-
I once created a program to compute dimensions of piping for evacuation systems used to extract for example saw dust from saw mills. It ran on the 99/4A and was used professionally by a company selling such systems. It was later ported to PC platform, running under DOS. It can still run as a console application in a command window under Windows XP.
We called the program DUSTBUSTER. What else?
-
Of course you can do things with less hardware than all that stuff that goes into the expansion box. But since I had a box handy, I didn't see any reason.
-
...this is why i rarely post. because people just can't be nice and civil when someone expresses their views. well, you win.
It could depend on how you express them, perhaps...
There were several things that TI had to consider.
Memory space limited to 64 Kbytes, without additional mapping registers. The 990 was a pretty early 16-bit architecture, when memory was expensive. The TMS 9900 integrated the architecture on a chip, so kept this limitation. But TI wanted working RAM, cartridge slot, operating system, expansion devices and internal I/O, like sound and video. All these competed about the memory space. Then they also wanted a comprehensive BASIC, with several features inspired by the BASIC running on the TI 990.
To squeeze all that in, they got the idea to make byte-serial memory (GROM), which stored instructions in a special language (GPL), which was more compact than the native instruction set for the TI 990. A great deal of the operating system ROM in the console was then used to interpret this GPL language, something which added to the time needed to execute the programs. As I've shown earlier, in another post here, even the simplest interpreter typically has a speed penalty of seven times or so, compared to native code.
Since GROM are 8-bit devices, and the VDP as well, cost could be saved by using a scaled down CPU. The TMS 9980 was developed as a TMS 9900 inernally, but with 8-bit wide data bus externally, as well as an internal oscillator. The TMS 9940 is a TMS 9980 with the addition of 8 K ROM and 256 bytes of RAM inside the chip. This is exactly the configuration of the 99/4A console, and perhaps the CPU they were really considering. But it didn't get ready in time, so they had to use the TMS 9900 instead, and do the memory and 8-bit multiplexing externally.
There they ended up with an architecture which could handle quite a lot of memory, but at the cost of slower execution. In applications with a lot of user interfacing, it doesn't matter so much, since the user is comparatively slow anyway. Educational use must have been a tempting market, pretty new and well suited to the architecture. Games could be handled by having 8 K ROM space in the cartridges, if assembly language was needed, and otherwise everything could run from GPL.
The problem turned out to be that few outside TI wanted to write games for it, since it couldn't run assembly programs without additional memory. If the console had been like mine, which is modified to have 64 Kbytes of RAM in addition to the 16 Kbytes video RAM, then amazing games could have been written by anyone, for the 99/4A. They could even have been loaded from cassette, if you were patient enough to let them load.
BASIC became slow due to the design considerations regarding memory use. With an expanded machine, you could run a better Pascal than Apple had, but not enough people wanted to invest in that, when they could keep up with the Jones'es and buy their kids a cheap VIC-20, to make sure they had a computer too. Most of them didn't know what to use the computer for anyway.
-
3
-
-
Many years ago (around 1985), I made an elevator out of Lego (toy construction kit). The motor as well as same lamps and buttons at the different floors were connected to the PIO port through some extra electronics. This interface made the port 8 bits out and 8 bits in at the same time, instead of an 8-bit bidirectional port.
Then a Pascal program, running different concurrent processes for handling user interface and motor control, was operating the lift. The multitasking program was supported by my own multitasking support core, which I developed as an add-on to the p-system.
-
1
-
-
Slightly OT, Vorticon, but have you made many attempts to interface the TI with another retro computer via serial connections?
I'm sorry, I just realized I've already mentioned this once in this thread. Please disregard.
I've done this, more or less, since by now I think you need to consider a computer which runs Windows XP as "vintage".
The reason for it was that I printed files to the Toshiba netbook computer (running HyperTerminal to collect the files), then printed them from there to the printer, which required a Windows driver (or similar) to work. My old impact printer works, but the ink band are dried up.
I've also done this at work. Not with vintage computers, but with more or less vintage machine control systems, which didn't support Ethernet or something like that. I had to use RS232, so I made up a protocol similar to what's normally used for CAN-bus networks, and exchanged information that way between two different machines. Exactly that same protocol could be applied to a 99/4A without any issues.
-
2
-
-
I've considered making an interface for the TI 99/4A, where it would simulate a storage device, so the CC-40 could use the 99/4A as kind of a file server. But I've never really taken the time to start analyzing if it's feasible.
-
1
-
-
You better behave, or I'll show you a picture of the other one too. It looks the same...
-
I doubt I have a cut list for the traces, but I do have some schematics, somewhere.
Meanwhile, the last three pictures in this album shows the internal modification. Only the last one also contains the VDP access wait state logic.
As you can see I never made any PCB, but the modification is completely self-contained inside the original metallic screen inside the 99/4A. Thus you could for example run assembly programs without the PEB, if you loaded from cassette. Like you could with Mini Memory, but here you could also have Extended BASIC plugged in, for example. I did a demo of Forth on a seemingly unexpanded console, with cassette tape recorder connected only, at a meeting in Sweden once.
To begin with, I installed the modification with one single bit toggling all 32 K RAM expansion, and individual bits toggling the other 8 K sections. But I realized that it was smarter to be able to handle the 8 K RAM and the 24 K RAM expansion areas (2000H-3FFFH and A000H-FFFFH) separately, so I modified the logic to Control them by two different bits. Since I also need a bit for the VDP wait state generation control, and I have eight bits in my latch, I couldn't spend one bit per 8 K memory bank. But usually it makes sense to consider the 24 K RAM part as one single section anyway.
Forgive me if I have made some error. I did this modification in the 1980's.
Together with the 56 K Maximem universal module, this additional 64 K RAM memory and some memory on my additional home made wire wrap PEB cards, I simulate a RAM-disk for the p-system. I remember that compiling a Pascal program was done in about half the time when the compiler was in RAM all the time, due to the extensive segmentation of that program.
Later additional memory devices with a lot more memory has been designed, but 176 K RAM was quite a lot in 1985. The fact that my design co-exists with the standard 32 K RAM expansion made a difference.
I used 400H as the base address for the CRU bits used to swap in/out RAM segments.
-
Now I don't have the schematics in front of me, but the principle is to fiddle with the chip select lines. Since all memory is connected to the same data bus, the chips that actually are active are selected. The other chips go to tri-state output level.
What I did was to add to the chip select decoding, to involve also a CRU bit for each bank. At power up, chip select goes to ROM, expansion cards, cartridge memory, ports and the new internal 16-bit wide memory expansion.
But setting the appropriate CRU bit, I can modify chip select to go to new RAM instead of ROM, cartridge space etc. Setting an appropriate bit also disables the new 16-bit wide RAM expansion and instead brings in the standard, 8-bit wide memory expansion, if available.
Thus I have two 32 K RAM expansions in the machine at the same time, one fast 16-bit internal for normal use and one slower 8-bit wide, that can be used for buffers in assembly programs, emulate a RAM disk or whatever you need. Or you can load a program there, if it relies on timing with normal memory to run properly.
Since the TI frequently use writing to ROM areas for memory mapped ports, bank switching and similar, I didn't implement write through, though. To efficiently copy ROM to RAM, I can do like this:
- Enable RAM at 4000H.
- Copy 8 K from 0000H to 4000H.
- Enable RAM at 0000H.
- Copy 8 K from 4000H to 0000H.
- Disable RAM at 4000H (to free up DSR access again).
Now the operating system at 0000H is in RAM, and can be modified as you like.
I also added some hardware which causes a one cylce wait state when accessing the VDP. That too is controlled with a CRU bit, since it's not needed for software which does have that extra NOP which is recommended by TI. But in some cases, with normal memory expansion, such a NOP isn't needed. Thus some programs don't have it, but then fails when you run from faster memory.
-
2
-
This is of course one reason for that I, when I made my 32 K RAM internal 16-bit memory expansion also allowed it to overlap all other memory in the machine. Thus I can copy console ROM to RAM, switch to RAM and change the vectors as I like.
Had TI placed the interrupt vectors in RAM, this discussion would be a moot point. We could eliminate all the extraneous code and focus solely on the RS232 interrupt. Ah well, there are many "if only" laments we must overcome with the TI.

-
1
-
-
I've never really used any TI 99/4A that hasn't been the real thing.
But when the 99 was the computer I had, I mainly used the p-system, and Pascal, for my software development. In that case I wrote everything that was doable in Pascal, and that's quite a lot, in Pascal. When the code worked, I used it as it was, if that was satisfactory. If there was a speed problem, I'd think about what part of the code was best to optimize, and then convert that to assembly. Normally I had a good idea about which part would be a good candidate for conversion to assembly already when starting out, so I made sure I wrote that part as a Pascal function/procedure in such a way that it would be easy to convert it to assembly.
Thus I didn't spend time designing things like data entry or disk access in assembly, since there are other things around these activities that are slowing them down anyway. Like running the drive or me typing on the keyboard. But a procedure to sort numbers or whatever would be very good to convert to assembly, to speed it up. Especially since such tasks often are time consuming.
-
That makes sense. Here's a stub of an interpreter for a byte-coded (to save memory) stack machine (similar to the PME, that runs the p-code card). SP is stack pointer, CP is code pointer. EREC is the current environment record, inside which the currently executing procedure's local variables are stored.
Each op-code is assumed to define the instruction completely. Even with this very simple approach, the instruction fetch and decoding loop is five instructions. Then add the instruction itself, which for these simple examples adds 2-5 instructions to interpret one instruction code. So here we have ten instructions to accomplish what two could do, or seven to do what one could do, if it was normal assembly code that was running instead of interpreted code on byte level.
interp: MOVB *CP+,R1 SRL R1,7 MOV @INTTAB(R1),R0 BL *R0 JMP interp ; Code for ADD values at stack, return result on stack addc: A *SP+,*SP B *R11 ; Code for INC top of stack incc: INC *SP B *R11 ; Code for push integer immediate to stack push: MOVB *CP+,R1 MOVB *CP+,@R1LBYT DECT SP MOV R1,*SP B *R11 ; Code for local store integer (offset into local variable area in byte after instruction) locst: MOVB *CP+,R1 SRL R1,7 MOV *SP+,@EREC(R1) B *R11
-
Reading data from GROM or VDP RAM isn't that extremely slow, as long as you read consecutive addresses. But when you start modifying the address, the overhead to load a new address and then read data is substantial.
At least the GPL interpreter runs from 16 bit ROM.
My console, which has 64 K RAM built in, on 16 bit wide bus, is about 110% faster than an original TI 99/4A, when you run programs that has both code and workspace in expansion RAM. That is, in memory that normally is only 8 bit wide. This give you an idea about how a "real" Commodore 64 competitor version could have performed, with little change to the rest of the architecture.
Of course, all sensibly written software doesn't speed up that much, since it has workspace in RAM PAD, which already is 16 bit wide.
-
I'm one of the few here who were a member of the Swedish user's group Programbiten. If you want an international touch, don't forget us.
-
1
-
-
What I was thinking about is the language type in the 99/4A. I presume most p-systems don't have to differentiate between code that must be loaded in the CPU RAM memory expansion vs. code that can be loaded in the video memory. I don't know what happens with a code file generated on a system without this flag being handled.

TMS9900 is the coolest CPU for multi-tasking
in TI-99/4A Development
Posted
Yes. You assign a register as a stack pointer. I usually use R10, and that's also what the PME uses.