apersson850
-
Content Count
1,063 -
Joined
-
Last visited
Posts posted by apersson850
-
-
For the TMS 9900, 70% of the instructions require 14 clock cycles or less. Minimum is 8 cycles. If we settle for an average of 12, then that implies 0.25 MIPS for the TMS 9900. Now of course not adding any wait states, extra memory accesses for addresses etc.
Thus it will not get any faster than this.
Multi-bit CRU instructions, shifts and advanced math takes significantly longer time to ececute. On the other hand, 52 clock cycles for MPY, compared to the complex sequence of instructions required for a CPU like the 6502 or Z80, is still fast. A reasonable 16-bit multiplication algorithm (32 bit result), using shift and add, for the 6502 would require around ten times the number of clock cycles as the MPY instruction requires. If the frqcuency then is 1 MHz for the 6502, vs. 3 MHz for the TMS 9900, we're looking at 30 times longer to do such a multiplication.
-
1
-
-
Since I was interested in hardware too, when I was using my TI 99/4A a lot, I implemented the all 16-bit RAM in my console. Pascal runs about 10% faster when all RAM is 16-bit wide in the machine. The main increase probably comes from things like that parts of the p-system code is loaded into 8 K RAM expansion. The 80-column screen memory is also there. Thus, some p-system runtime is spent in this memory. The inner parts of the PME are transferred to the internal RAM PAD, so they are 16-bit already. The major part of the interpreter is on the p-code card, which is 8-bit access reagardless of the RAM. User's code is running from VDP RAM, space permitting.
-
2
-
-
P-code can run from any memory. The PME (p-machine emulator) is written in such a way, that it will do the same thing to the code, regardless of where it is. There's a flag to keep track of which kind of memory the current code is executing from, so it can see if it needs to do any special action, when the program is calling procedures that may be in a different type of memory.
Thus the p-system has two code pools for the user, in VDP RAM and CPU RAM (24 K expansion), as well as in GROM on the p-code card for the system itself.
-
1
-
-
Yes, and that ROM has a different address space.
The TMS 9900 has a good instruction set, but being a true 16 bit design, each occupies at least two bytes.
-
1
-
-
1 hour ago, HOME AUTOMATION said:
You just made a new friend. Thanks for taking the time!
AORG >7D00 DEF REMOTE REMOTE CLR R0 CLR R12 LI R1,>3FFA A lot of bytes to clear LI R6,>B000 NEXT MOV R0,*R6+ Clear a word at a time DEC R1 But count bytes, so we clear >B000 - >2FF4. Should be DECT JNE NEXT LI R6,>B000 WAIT TB 17 Wait as long as bit is zero JEQ WAIT TEST CLR R5 Now start measuring CHECK0 INC R5 TB 17 JEQ CHECK0 Count as long as it's zero, but we know already it's not, or we wouldn't be here MOV R5,*R6+ CLR R5 CHECK1 INC R5 So we end up here immediately. Thus this part could come first, CHECK1 before CHECK0 TB 17 JNE CHECK1 MOV R5,*R6+ CI R6,>B0FF Much smaller than the buffer that's cleared JLT TEST RT ENDYou're welcome. I added some comments to your code.
-
All the features of BASIC most probably wouldn't have been there, without GPL.
-
1
-
-
I'm repairing my network cables, when the little locking spring falls off the connector.
-
Yes, I was referring to the measurements above.
-
That code can't work. INC affects the status bits, so the following JNE will consider the result of the incremented value vs. zero, not the result of the TB instruction.
-
1
-
1
-
-
Arrrgh, inches...
-
Well, plug in Editor/Assembler, or even better, Mini Memory, and you have that. It's not the bare console, no, but I think many of these were sold to people plugging in Invaders and Parsec, and never brought it any longer than that.
Mini Memory gave you something to work with, but otherwise there wasn't too much that was interesting to the skilled hobbyists inside the machine, as long as it had no memory expansion.
Just making it like my modified console, with 64 K 16-bit contiguous RAM, in additon to the 16 K video RAM, makes it a whole different beast. It's a concept similar to the Commodore 64, which also had 64 K RAM, but not access to all of it when the machine was running "normally". But you could page in RAM all over, under software control, just like my console allows you to.
-
Yes, the mini computer TI 990/9 was the original LSI implementation of the CPU, which became integrated into a chip as the TMS 9900. The TMS 9900, in turn, was used to run the TI 990/4 and TI 990/5 mini computers. Unlike its bigger brothers (e.g. the TI 990/10A), these models were usually limited to max 64 K memory. Hence the width of the address bus.
Those wondering why TI selected model names like 99/4, 99/4A, 99/8 etc. have food for thought, when looking at the mini computer serie's names.
-
On 11/10/2019 at 3:04 PM, HOME AUTOMATION said:Unfortunately, I have never used a TI RAMDISK.
I imagine their main/sole purpose is to speed-up file processing?
That was the main issue for me. To be able to compile a quite comprehensive version of Pascal within the small memory of the TI 99/4A, the UCSD Pascal compiler is heavily segmented. This means the drives are spinning constantly during compile time, to reload different parts of the program during operation, in addition to reading the source code and writing the object code.
By placing the SYSTEM.COMPILER file on a RAMdisk, compile time is reduced to half, even if both the source and the object code files are on physical disks.
-
1
-
-
Oh yes, I do. But then I'm an electric engineer by profession. In Swedish Att mäta är att veta translates to To measure is to know in English. The phrase sounds better in Swedish, though.
-
1
-
-
Thank you. I don't have any emulator installed on this computer.
At least this implies that assuming the user has some programming skill, in the actual language (Forth or BASIC, in this case), then the approaches to use this principle in Forth, and using the method of entering a code line in BASIC, are conceptually equal.
Thus a function plotter could use the plot environment that works best, and allow function input by programming it.
It's not as fool proof as having the user enter a function as a text, parse and generate code for it (evaulate it, that is), but a lot easier to do. Based on this concept study we can say that a solution is in place. Acutally implementing it isn't important, since nobody will use this program anyway.
-
1
-
-
7 hours ago, TheBF said:Yes as Lee mentioned the word EXECUTE and ANS Forth has the word DEFER which is like Forward in PASCAL
Forth's word space is defined as Hyper-static. You can define a routine called X and use it in subsequent code and then define something else called X and the old X will not be affected. This is because lookup of labels starts with the last label defined so the newest X is found first. So the short answer is yes, but I suspect that's not what you were looking for.
Yes, I know you can re-use the same name, but that it doesn't really re-define the word in the contexts where it has already been used.
So you can't define FX, define a plotter that uses FX and finally make new definitions of FX. The new definitions will replace the old, for words written now, but will not re-define FX for the plotter package. It will still see the old FX.
Now I'm not sure exactly how DEFER works. Would this code do the same thing as the example you posted?
\ F(X)=COS(3X) + 3X^2 in Forth INCLUDE DSK1.TOOLS INCLUDE DSK1.TRIG INCLUDE DSK1.DEFER DECIMAL : ^2 DUP * ; DEFER F(X) : COS(3X) ( n -- n') 3 * COS ; : 3X^2 ( n -- n') ^2 3 * ; : TEST ( n -- ) 0 ?DO I F(X) . LOOP ; : FUNCTION1 ( n -- n') DUP COS(3X) SWAP 3X^2 + ; ' FUNCTION1 IS F(X)If you now use TEST, would you get the same result as in your example? Note that I've changed the order of things.
If it does give the same result, then you've accomplished what I was looking for. You can expect the user to re-define F(X) and again use the plotter. This is equivalent to asking the user to key in a BASIC program line defining the function, but perhaps easier to accept in Forth, since you go back and forth between defining and executing words all the time there. In BASIC, there more of a context switch, as you use RUN to start executing, and that's clearly distinguished from immediate mode. In Pascal even more so, as there is no "immediate mode", and you need to run the compiler between creating and executing a new program.
: FUNCTION2 ( n -- n') DUP COS(3X) SWAP 3X^2 - ; ' FUNCTION2 IS F(X)After this, then running TEST would evaluate this function instead. But I'm not sure that's what you get?
-
I've never seen that before. So you had to unplug your expansion box to run it. What an idea.
-
Nobody would ever have used it today. Back in the 80's, yes. But today you use Excel or Matlab or stuff like that, depending on how complex the task is.
So the task has to be fun, because it's just for fun it would be done.
If you're going to start more threads like this one, then next time, I hope you learned from this attempt that you need to participate, work and learn yourself too. Otherwise you'll not encourage people to do things.
-
1
-
-
Without a disk in the drive, what happens is never ending spinning of the drive. But I meant that you can easily measure which side is ground, since each of the pins are the same.
-
You don't have to worry about the slots, if you make your own cable. Ribbon cables can easily be made at home. Push the connectors together in a vice.
Since you don't have any tab for the slot, you have to figure out how to orient them properly. But since one side of the edge connectors are all ground connections, that's not difficult to find out.
-
2 hours ago, Tursi said:(Although, the suggestion to just tell the user to enter it as a line of code and then run the program was pretty brilliant!)
I thought it was the only realistic one, in this context. Didn't render any pizza, though.
No, the task isn't too difficult for this community. As I've written some compilers, I know exactly how to do a recursive descent parser, for example. Including the code generation. But it's ridiculous to do in BASIC, when there are other options. So for BASIC, that suggestion I made works best.
Other languages are available here, but to spend the effort to create a good program nobody will ever use, that doesn't make sense. All the less when it became obvious that you, Sid1968, had no interest whatsoever in learning anything yourself.
Doing this because it has to be done is like work. This is a hobby. Here we learn together and create for fun.
-
2
-
-
Now I'm far from California (most of the time), but it does say it's applicable to computers manufactured in 2018 or later. Our TI 99/4A computers for sure are not, even if they do qualify as "highly expandable"!
-
3
-
-
Good idea to reduce power transmission losses. Computers are frequently bad there.
-
1 hour ago, adamantyr said:The byte versions only work on the first/high byte, you have to use shifts or a swap byte opcode to access the other byte.
This is not generally true.
Byte operations like Add byte can use the addresses 123 and 345, in an instruction like AB @123,@345, and actually add the two odd-addressed bytes together, and store the result at 345. So odd-byte addressing is possible.
However, when using registers (those that aren't, but pretend to be), in an instruction like AB R2,R4, you'll add the most significant byte of R2 with the most significant byte of R4, and store the result "to the left" in R4. If we assume the context that LWPI >1000 which defines the virtual R0 to be at >1000 in memory, preceeded the instruction
AB R2,R4
then this is completely equivalent to
AB @>1004,@>1008
The only difference is that the register only instruction requires one word, the other three. Since the first is shorter and has fewer memory accesses, it's also faster. This means that if you want to add the two least significant bytes of R2 and R4, you can use
AB @>1005,@>1009
The register file in memory makes it easy to use a separate register set momentarily, by LWPI NewWP, do whatever, then LWPI OldWP and you continue with your old values in the registers.
The 9900 doesn't have a predefined stack register. Return from subroutines called by BL @Sub are returned from by executing B *R11. The return address is stored in R11, so by branching indirectly to that, you return to after your Branch and Link instruction. As a consequence, you can't call another subroutine from the first, unless you take care to save the return address on the first level yourself. Either you implement a stack, or save it in some handy location.
But you can do a more elaborate BLWP @SepWSSub, to call a subroutine with a separate workspace. The Branch and Link with Workspace Pointer branches via a vector. This vector consists of two words. The address of the new workspace followed by the address of the code to run.
In the new workspace, the BLWP instruction will automatically store the old WP in R13, the return address (old PC) in R14 and the status register, as it was prior to making the call, in R15. Hence this will give you a subroutine that has its own workspace, but can acess data in the caller's registers via R13, or data stored after the call instruction via R14. To access the caller's R5, and store this in the subroutine's R5, you'd execute
MOV @10(R13),R5
since the caller's R5 is ten bytes down in his workspace.
To fetch in-line data after the call to your R6, you'd use
MOV *R14+,R6
This will move a word located right after the BLWP instruction to R6, and also increment R14 by two, so that it points to the actual code following the call instruction.
When an interrupt is signalled, an implicit BLWP, via a vector in a pre-defined address in memory, occurs. This means that without explicitly saving anything on a stack, the interrupt starts running with a fresh set of registers, as well as with the previous status word handy, so you can return to the previously executing code and restore the context you had completely. A return is done with the RTWP instruction in both cases. RTWP uses the data in R13, R14 and R15 to restore the registers WP, PC and ST in the CPU.
As explained above, the CRU is Texas Instruments version of I/O addressing. You install hardware, wired to look at the CRU command signal and decode the address given, so that you can set or read a bit from this hardware. The hardware can be anything: Latches, LSI chips with pre-defined functions, like UART, general timer/IO-chip, floppy disc controllers etc. Since it's bit-serial, you can easily define hardware ports of odd sizes. Two eight-bit latches can make three ports, five, seven and four bits wide. Many microprocessors would require three eight-bit latches to implement that efficiently, where three, one and four bits were unused.
The 9900 concept is more about flexibility than utmost speed. Many instructions allow a general address, which can be either directly to a register, indirectly via a register, indirect with auto-increment, indexed or symbolic. There are no restrictions on which of these you use in that case.
-
1
-

Texas Instruments Dimension 4
in TI-99/4A Computers
Posted
Everybody interviewed claims that this part never happened. The BASIC in the TI 99/4A is instead based on the BASIC available for the TI-990 mini computers.