Engineering:TI-990
The TI-990 is a series of 16-bit minicomputers sold by Texas Instruments (TI) in the 1970s and 1980s. It served as a replacement for TI's earlier minicomputer systems, the TI-960 and the TI-980. The TI-990 features several unique innovations and was designed to be easier to program than its predecessors.
Among its core concepts is the ability to support multiprogramming using a software-switchable set of processor registers that allowed it to perform rapid context switches between programs. This is enabled through the use of register values stored in main memory that could be swapped by changing a single pointer.
TI later implemented the TI-990 in a single chip, the TMS9900, one of the first 16-bit microprocessors. Intended for use in low-end models of the TI-990, it retained the 990's memory-to-memory architecture. This chip was widely used in the TI-99/4A home computer, where aggressive cost-cutting measures presented significant performance disadvantages.[1]
TI-990 models
The TI-990 processors fell into several natural groups depending on the original design upon which they are based and which I/O bus they used.
All models support the Communications Register Unit (CRU) which is a serial bit addressable I/O bus. Also, supported on higher end models is the TILINE I/O bus which is similar to DEC's popular UNIBUS. The TILINE also supports a master/slave relationship that allowed multiple CPU boards in a common chassis with arbitration control.
CRU-only models
The following models used the CRU as their principal bus:
- TI-990/9 — The original TTL implementation; 1974
- TI-990/4 — TMS9900 microprocessor with 56 KB of memory
TILINE/CRU models
The following models used the TILINE as their principal mass storage bus:
- TI-990/5 — TMS9900 microprocessor with 64 KB of memory
- TI-990/10 — TTL processor with memory mapping support to 2 MB of ECC memory; 1975
- TI-990/10A — TMS99000 microprocessor with memory mapping support to 1 MB of memory
- TI-990/12 — Schottky TTL processor with memory mapping to 2 MB of ECC Memory, workspace caching, hardware floating point, extended mode instructions and writeable control store
Features
Orthogonal instruction set
The TI-990 series has a fairly orthogonal instruction set. The instruction formats allows for one-, two- and three-word instructions. The model 990/12 CPU allows for a four- word instruction with extended mode operations.[clarification needed]
Workspaces
In the TI-990 series, the general-purpose registers are stored in memory and are referred to through a hardware register called the Workspace Pointer. The concept behind the workspace is that main memory was based on the new semiconductor RAM chips that TI had developed and ran at the same speed as the CPU.[clarification needed] This meant that it didn't matter if the "registers" were real registers in the CPU or stored in memory. When the Workspace Pointer is loaded with a memory address, that address is the origin of the registers.
There are only three hardware registers in the 990: the Workspace Pointer (WP), the Program Counter (PC) and the Status register (ST). A context switch entailed the saving and restoring of only the hardware registers.
Architectural details
Addresses are 16-bit byte addresses, so the address space is 216 bytes (65,536 bytes or 32,768 words) large. The byte ordering in words is big endian.
There is no dedicated stack pointer register. Instead, branch instructions exist that save the program counter to a register (BL — Branch and Link), or change the register context (BLWP — Branch and Link Workspace Pointer, or XOP). The 16 hardware and 16 software interrupt vectors each consist of a pair of PC and WP values, so the register context switch is automatically performed by an interrupt as well. Stacks can be implemented atop either of these mechanisms.[2]
Along with the typical single-bit flags seen in most processors, the status register contains a 4-bit interrupt mask. The value, 0 to 15, indicates the maximum interrupt that can be triggered. For instance, if interrupt 10 has been called, and interrupt 12 is triggered, the CPU checks this values, sees that 10 is running, and blocks the request.[3]: 1-11
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There are 16 general-purpose "workspace registers". Several registers have defined purposes in many instructions. These are:[3]
- R0 - shift counter, extended mode counter, Floating point Accumulator (FAC) most significant word
- R1 - FAC+2 (single precision)
- R2 - FAC+4 (double precision)
- R3 - FAC+6 (double precision)
- R11 - return linkage, or pointer to operand of XOP (privileged mode)
- R12 - CRU base address (privileged mode)
- R13 - Saved Workspace Pointer
- R14 - Saved Program Counter
- R15 - Saved Status Register
Addressing modes
Most instruction operands are represented with an addressing mode and a general-purpose register used by that addressing mode. In these examples, Rn is a general-purpose register, 0 to 15. The addressing modes are:
| Code | Name | Example | Description |
|---|---|---|---|
| 0n | Register | Rn | The operand is in Rn |
| 1n | Indirect register | *Rn | Rn contains the address of the operand |
| 2n | Indexed | @mem(Rn) | Rn contains an index value to add to address mem, forming the address of the operand |
| 20 | Symbolic | mem | If Rn is R0, direct memory addressing is specified. The address mem is used as the address of the operand. |
| 3n | Indirect autoincrement | *Rn+ | Rn contains the address of the operand, then increment Rn by data size |
Instructions
The 990/9, 990/4, and 990/5 instruction sets consisted of 69 instructions, the 990/10 had 72 instructions,[3]: 2–1 the 990/10A had 77 instructions,[3]: 2–1 and the 990/12 had 144 instructions.[3]: 2–7
For subroutine calls, the Branch and Load Workspace Pointer (BLWP) instruction loads new WP and PC values, then saves the values of WP, PC, and ST to (new) registers 13, 14, and 15 respectively. At the end of the subroutine, the Return Workspace Pointer (RTWP) restores these in reverse order. Using BLWP/RTWP, it is possible to nest subroutine calls despite the absence of a stack, however, the programmer needs to assign the appropriate register workspace explicitly.
The instruction set also contains a Branch and Link (BL) opcode that only saves PC to register 11 without changing WP. In this case, a branch instruction (B) using WR11 as the destination address can serve as the return opcode, but BL-type subroutines cannot be nested without the programmer taking actions to save the return address.
Then execute instruction "X" (eXecute) executes the instruction in a register or memory location. It can be used for debugging (as a breakpoint instruction), for creating indexed-opcode tables as used in byte-code interpreters and can also be used to perform a time critical I/O instruction during an interrupt. An example of its utility is shown in the code below where an interrupt is being serviced in a very encapsulated manner that would otherwise require many more instructions.
;***********************************
;
; THIS INTERRUPT SIMULATES DMA CONTROL
; ORGANISED AS FOLLOWS:
;
; R9 HOLDS CURRENT COMMAND, E.G.
; IOREAD(34B8H): STCR *R8+,BYTEWIDE ;BYTE WIDE FDC DATA READ
; IOWRITE(30B8H):LDCR *R8+,BYTEWIDE ;BYTE WIDE FDC DATA WRITE
; R8 HOLDS THE CURRENT DMA ADDRESS.
; R12 HOLDS THE CURRENT IO PORT - DATREG
;************************************
INTDRQ X R9 ;CAN BE EITHER READ or WRITE
RTWP
This common piece of code during the interrupt could be used by both I/O read and write commands. Similar methods could be employed in any debugging methods wanting to be used.
TI-990 series processors also support the eXtended OPeration (XOP) instruction. XOP is given a number in the range 0–15 as well as a source address. When invoked, the instruction will perform a context switch through one of sixteen vectors at predefined locations in memory. The XOP instruction also places the effective address of the source operand in register R11 of the new workspace.[3]: 3-227–3-231 The context-saving feature of the XOP instruction can also be used as to implement inline debugging.[4]
XOP is less flexible than a BLWP, as the transfer vectors have to be at fixed locations, but allows one source operand to be directly addressed rather than passed in a register or otherwise.
XOP can be used to implement a system call facility. In TI's DX10 operating system, XOP 15 invokes a system call. A programmer might define an assembler macro, for example SVC, which invokes XOP 15. Another use of XOP was to implement instructions in software which might be handled by dedicated hardware in future versions of the 990 minicomputer series. An example of such actions can be shown in the code below where a CALL function is implemented using and XOP 6 instruction. The beauty of this implementation of a CALL function using an XOP is that it is straightforward to add checks to determine if the stack overflowed, for example C R10,@2*R9(R13), where R9 points to the address of the stack limit.
; ;************************************************ ; CALL SUBROUTINE ; DEFINE XOP: DXOP CALL,6 ; CALLING METHOD: CALL @SUBROUTINE_ADDRESS ; R10 <=> STACK POINTER ;************************************************* ; ED32 C2AD 0014 XOP6: MOV @2*R10(R13),R10 ;GET STACK POINTER ED36 064A DECT R10 ;DECREMENT STACK POINTER ED38 C68E MOV R14,*R10 ;PUSH RETURN PC ONTO STACK ED3A C38B MOV R11,R14 ;MOVE EA INTO R14 (PC) FOR CALL ED3C CB4A 0014 MOV R10,@2*R10(R13) ;UPDATE STACK POINTER ED40 0380 RTWP ;WE ARE NOW USING THE ORIGINAL WP
The 990/10 has a facility to allow specific XOP codes to use plug-in hardware.[5] If the hardware is not present, the regular XOP trap is performed. This allowed for 15 attached devices on a system, although, device 15 is reserved in TI's operating systems for the Supervisor Call (SVC), through which user programs requested I/O and other operating systems services.
On the 990/12, if the writable control store is enabled, the XOP instruction would jump to microcode in the writable control store.
The instructions are grouped according to the instruction format. A format is defined by the layout of bit fields within the instruction word. The leftmost bits of the instruction word are sufficient to identify its format.
These are two-operand move, arithmetic, and comparison instructions. The first field of the word is a 4-bit operation code. The remaining four fields are a 2-bit addressing mode and 4-bit register number for the destination operand and a 2-bit addressing mode and 4-bit register number for the source operand.[3]: 3-9-3-10 This format takes up 75% of available opcodes.
| 0 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 15 | |||||
| Opcode | B | TD | D | TS | S | ||||||||||
- MOV (move word)
- MOVB (move byte)
- A (add word)
- AB (add byte)
- S (subtract word)
- SB (subtract byte)
- C (compare word)
- CB (compare byte)
- SZC (set zeros corresponding word)
- SZCB (set zeros corresponding byte)
- SOC (set ones corresponding word)
- SOCB (set ones corresponding byte)
These operands are jump and CRU bit-manipulation instructions. The first field of the word is an 8-bit operation code. The second field is an 8-bit PC-relative offset to where to go for jump instructions or the relative offset for CRU bit addressing.[3]: 3-10-3-11
| 0 | 7 | 8 | 15 | ||||||||||||
| Opcode | Offset | ||||||||||||||
- JMP (jump unconditionally)
- JLT (jump if less than zero)
- JLE (jump if less than or equal to zero)
- JEQ (jump if zero)
- JHE (jump if logically greater than or equal to zero)
- JGT (jump if greater than zero)
- JNE (jump if not equal zero)
- JNC (jump if carry clear)
- JOC (jump if carry set)
- JNO (jump if overflow clear)
- JOP (jump if odd parity - only relevant after byte operations)
- JL (jump if logically less than zero)
- JH (jump if logically greater than zero)
- SBO (set CRU bit to one)
- SBZ (set CRU bit to zero)
- TB (test CRU bit)
The first field of the word is a 6-bit operation code. The second field is a 4-bit destination register number, and the third and fourth fields are a 2-bit addressing mode and 4-bit register number.[3]: 3-11-3-12
| 0 | 5 | 6 | 9 | 10 | 11 | 12 | 15 | ||||||||
| Opcode | D | TS | S | ||||||||||||
- COC (compare ones corresponding)
- CZC (compare zeros corresponding)
- XOR (exclusive or)
These instructions transfer a specified number of bits between the CRU and a register. The first field of the word is a 6-bit operation code. The second field is a 4-bit field that specifies the bit width of the operation, and the third and fourth fields are a 2-bit addressing mode and 4-bit register number.[3]: 3-12-3-13
| 0 | 5 | 6 | 9 | 10 | 11 | 12 | 15 | ||||||||
| Opcode | C | TS | S | ||||||||||||
- LDCR (load CRU)
- STCR (store CRU)
These are shift instructions. The first field of the word is an 8-bit operation code. The second field is a 4-bit shift count and the third field is a 4-bit register number that specifies the register to shift.[3]: 3-13
| 0 | 7 | 8 | 11 | 12 | 15 | ||||||||||
| Opcode | C | W | |||||||||||||
- SRA (shift right arithmetic)
- SRL (shift right logical)
- SLA (shift left arithmetic)
- SRC (shift right circular)
These are single-operand instructions. The first field is a 10-bit operation code. The second and third fields are a 2-bit addressing mode and 4-bit register number that specify the operand.[3]: 3-14
| 0 | 9 | 10 | 11 | 12 | 15 | ||||||||||
| Opcode | TS | S | |||||||||||||
- BLWP (branch and load workspace pointer)
- B (branch)
- X (execute)
- CLR (clear word)
- NEG (twos complement negate)
- INV (ones complement)
- INC (increment)
- INCT (increment by two)
- DEC (decrement)
- DECT (decrement by two)
- BL (branch and link)
- ABS (absolute value)
- SWPB (swap bytes)
- SETO (set word to ones)
- LDS (long distance source, 990/10, 990/10A, 990/12)
- LDD (long-distance destination, 990/10, 990/10A, 990/12)
- BIND (branch indirect, 990/10A, 990/12)
- MPYS (multiply signed, 990/10A, 990/12)
- DIVS (divide signed, 990/10A, 990/12)
- AR (add real, 990/12)
- CIR (convert integer to real, 990/12)
- SR (subtract real, 990/12)
- MR (multiply real, 990/12)
- DR (divide real, 990/12)
- LR (load real, 990/12)
- STR (store real, 990/12)
- AD (add double, 990/12)
- CID (convert integer to double, 990/12)
- SD (subtract double, 990/12)
- MD (multiply double, 990/12)
- DD (divide double, 990/12)
- LD (load double, 990/12)
- STD (store double, 990/12)
These instructions do not specify an operand. The first field is an 11-bit operation code. The remaining 5 bits are not used.[3]: 3-15
| 0 | 10 | 11 | 15 | ||||||||||||
| Opcode | N | ||||||||||||||
- IDLE (cpu idle)
- RSET (cpu reset)
- RTWP (return workspace pointer)
- CKON (clock on)
- CKOF (clock off)
- LREX (load ROM and execute[6]/load or restart execution[3]: 3–132 )
- EMD (execute micro diagnostic, 990/12)
- EINT (enable interrupt, 990/12)
- DINT (disable interrupt, 990/12)
- CRI (convert real to integer, 990/12)
- CDI (convert double to integer, 990/12)
- NEGR (negate real, 990/12)
- NEGD (negate double, 990/12)
- CRE (convert real to extended integer, 990/12)
- CDE (convert double to extended integer, 990/12)
- CER (convert extended integer to real, 990/12)
- CED (convert extended integer to double, 990/12)
- XIT (exit floating point, 990/12)
These instructions operate on a register and an immediate operand. The first field is an 11-bit operation code. The second field specifies the register if applicable. The third field, if applicable, specifies an immediate operand in a second word.[3]: 3-15-3-16 [clarification needed]
| 0 | 10 | 11 | 15 | ||||||||||||
| Opcode | N | ||||||||||||||
| IOP | |||||||||||||||
- LIMI (load interrupt mask immediate)
- LWPI (load workspace pointer immediate)
| 0 | 10 | 11 | 12 | 15 | |||||||||||
| Opcode | N | W | |||||||||||||
| IOP | |||||||||||||||
- LI (load immediate)
- AI (add immediate)
- ANDI (and immediate)
- ORI (or immediate)
- CI (compare immediate)
- BLSK (branch immediate push link onto stack, 990/12)
| 0 | 10 | 11 | 12 | 15 | |||||||||||
| Opcode | N | W | |||||||||||||
- STWP (store workspace pointer)
- STST (store status)
These instructions either perform an extended operation or an arithmetic operation. For extended operations, XOP, the first field of the word is a 6-bit operation code, the second field is a 4-bit field specifying the extended operation, and the third and fourth fields are a 2-bit addressing mode and 4-bit register number that specify the operand. For arithmetic operations, the first field of the word is a 6-bit operation code, the second field is a 4-bit field containing a register number specifying the destination, and the third and fourth fields are a 2-bit addressing mode and 4-bit register number that specify the source.[3]: 3-16-3-17
| 0 | 5 | 6 | 9 | 10 | 11 | 12 | 15 | ||||||||
| Opcode | D | TS | S | ||||||||||||
- XOP (extended operation)
- MPY (unsigned multiply)
- DIV (unsigned divide)
These instructions load the memory map file. The first field is an 11-bit operation code. The second field is a 1-bit field that specifies the map file (0=kernel, 1=user) and the third field is a 4-bit field that specifies a register with an address.[3]: 3-18
The given map file is loaded with six words from the address in the register.
This instruction is supported on the 990/10A and 990/12, or the 990/10 with memory-map option installed.
| 0 | 10 | 11 | 12 | 15 | |||||||||||
| Opcode | M | W | |||||||||||||
- LMF (load map file)
These instructions operate on multi-byte operands. The first word is the operation code. IN the second word, the first field is a 4-bit byte count field, the second and third fields are a 2-bit addressing mode and 4-bit register number that specify the destination operand and the fourth and fifth fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. These instructions are supported on the 990/12.[3]: 3-18-3-19
- NRM (normalize)
- RTO (right test for ones)
- LTO (left test for ones)
- CNTO (count ones)
- BDC (binary to decimal conversion)
- DBC (decimal to binary conversion)
- SWPM (swap multiple)
- XORM (xor multiple)
- ORM (or multiple)
- ANDM (and multiple)
- SM (subtract multiple)
- AM (add multiple)
The multiple precision instructions allowed for logic and integer arithmetic on operands from 1-15 bytes long. *SM and *AM are supported on the 990/10A.
These are character string instructions. The first field of the first word is a 12-bit operation code. The second field of the first word is a 12-bit register number indicates a checkpoint register, which is used in a machine-dependent fashion. The first field of the second word is a 4-bit byte count field, the second and third fields are a 2-bit addressing mode and 4-bit register number that specify the destination operand and the fourth and fifth fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. These instructions are supported on the 990/12.[3]: 3-19-3-20
- SNEB (search string for not equal byte)
- CRC (cyclic redundancy code calculation)
- TS (translate string)
- CS (compare string)
- SEQB (search string for equal byte)
- MOVS (move string)
- MVSR (move string reversed)
- MVSK (move string from stack)
- POPS (pop string from stack)
- PSHS (push string to stack)
These are multi-byte bit-shift instructions. The first word is the operation code. In the second word, the first field is a 4-bit byte count, the second field is a 4-bit shift count, and the third and fourth fields are a 2-bit addressing mode and 4-bit register number that specify the operand. These instructions are supported on the 990/12 and 990/10A.[3]: 3-21
- SRAM (shift right arithmetic multiple)
- SLAM (shift left arithmetic multiple)
These instructions test one of 2048 bits in a multi-byte operand. The first word is the operation code. The first field of the second word is an 11-bit field that specifies the bit to test and the second and third fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. These instructions are supported on the 990/12.[3]: 3-22
- TMB (test memory bit)
- TCMB (test and clear memory bit)
- TSMB (test and set memory bit)
This instruction reverses the order of bits within a bit field of a multi-byte operand. The first field of the first word is a 12-bit operation code. The second field of the first word is a 4-bit field that specifies the width of the bit field. The first field of the second word is a 4-bit field that specifies the bit position of the bit field, and the second and third fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. This instruction is supported on the 990/12.[3]: 3-23
- IOF (invert order of field)
These instructions extract bit fields from or insert bit fields into a multi-byte operand. The first field of the first word is a 12-bit operation code. The second field of the first word is a 4-bit field that specifies the width of the bit field. TThe first field of the second word is a 4-bit field that specifies the bit position of the bit field, the second and third fields are a 2-bit addressing mode and 4-bit register number that specify the destination operand, and the fourth and fifth fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. These instructions are supported on the 990/12.[3]: 3-24
- INSF (insert field)
- XV (extract value)
- XF (extract field)
These instructions adjust the value in a register and jump to a new address. The first word is the operation code. The first field of the second word is a 4-bit value that is added to or subtracted from the register, the second field is a 4-bit field that specifies the register to be adjusted, and the third field is an 8-bit PC-relative offset for the jump target. These instructions are supported on the 990/12.[3]: 3-25
- SRJ (subtract value from register and jump)
- ARJ (add value to register and jump)
These instructions perform an operation with a single register operand. The first field of the word is a 12-bit operation code. The second field is a 4-bit value that specify the register. These instructions are supported on the 990/12.[3]: 3-25-3-26
- STPC (store PC in register)
- LIM (load interrupt mask from register)
- LST (load status register)
- LWP (load workspace pointer)
- LCS (load control store)
This instruction moves the effective address of the source operand to the destination operand. The first word is the operation code. The first and second fields are a 2-bit addressing mode and 4-bit register number that specify the destination operand, and the third and fourth fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. This instruction is supported on the 990/12.[3]: 3-26-3-27
- MOVA (move address)
These instructions search a list. The first word is the operation code. The first field of the second word is a 4-bit field specifying the condition to be searched for, the second and third fields are a 2-bit addressing mode and 4-bit register number that specify the destination operand, and the fourth and fifth fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. These instructions are supported on the 990/12.[3]: 3-27-3-28
- SLSL (search list logical address)
- SLSP (search list physical address)
These instructions extend the precision of a multi-byte value. The first field of the first word is a 12-bit operation code; the second field is a 4-byte value specifying the length of the destination. The first field of the second word is a 4-byte value specifying the length of the source, the second and third fields are a 2-bit addressing mode and 4-bit register number that specify the destination operand and the fourth and fifth fields are a 2-bit addressing mode and 4-bit register number that specify the source operand. This instruction is only supported on the 990/12.[3]: 3-28
- EP (extend precision)
Assembly Language Programming Example
A complete "Hello, world!" program in TI-990 assembler, to run under DX10:
IDT 'HELLO'
TITL 'HELLO - hello world program'
*
DXOP SVC,15 Define SVC
TMLUNO EQU 0 Terminal LUNO
*
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
R10 EQU 10
R11 EQU 11
R12 EQU 12
R13 EQU 13
R14 EQU 14
R15 EQU 15
*
DATA WP,ENTRY,0
*
* Workspace (On the 990 we can "preload" registers)
*
WP DATA 0 R0
DATA 0 R1
DATA >1600 R2 - End of program SVC
DATA >0000 R3 - Open I/O opcode
DATA >0B00 R4 - Write I/O opcode
DATA >0100 R5 - Close I/O opcode
DATA STRING R6 - Message address
DATA STRLEN R7 - Message length
DATA 0 R8
DATA 0 R9
DATA 0 R10
DATA 0 R11
DATA 0 R12
DATA 0 R13
DATA 0 R14
DATA 0 R15
*
* Terminal SVC block
*
TRMSCB BYTE 0 SVC op code (0 = I/O)
TRMERR BYTE 0 Error code
TRMOPC BYTE 0 I/O OP CODE
TRMLUN BYTE TMLUNO LUNO
TRMFLG DATA 0 Flags
TRMBUF DATA $-$ Buffer address
TRMLRL DATA $-$ Logical record length
TRMCHC DATA $-$ Character count
*
* Message
*
STRING TEXT 'Hello world!'
BYTE >D,>A
STRLEN EQU $-STRING
EVEN
PAGE
*
* Main program entry
*
ENTRY MOVB R3,@TRMOPC Set open opcode in SCB
SVC @TRMSCB Open terminal
MOVB @TRMERR,R0 Check for error
JNE EXIT
MOVB R4,@TRMOPC Set write opcode
MOV R6,@TRMBUF Set buffer address
MOV R7,@TRMLRL Set logical record length
MOV R7,@TRMCHC and character count
SVC @TRMSCB Write message
MOVB @TRMERR,R0 Check for error
JNE CLOSE
CLOSE MOVB R5,@TRMOPC Set close opcode
SVC @TRMSCB Close terminal
EXIT SVC R2 Exit program
*
END
This program can be run on a TI-990 simulator, such as Dave Pitts's "sim990", which emulates the TI-990 and includes software kits for native operating systems (including DX10).
The following program is a standalone version that prints on the serial terminal connected to CRU address 0. It illustrates the CRU I/O and workspace linkage for the PRINT subroutine.
IDT 'HELLO'
TITL 'HELLO - hello world program'
*
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
R10 EQU 10
R11 EQU 11
R12 EQU 12
R13 EQU 13
R14 EQU 14
R15 EQU 15
*
* Terminal CRU bits
*
TRMCRU EQU >0 Terminal device address
XMIT EQU 8
DTR EQU 9
RTS EQU 10
WRQ EQU 11
RRQ EQU 12
NSF EQU 13
*
PAGE
*
* Main program entry
*
ENTRY LWPI WP Load our workspace pointer
BLWP @PRINT Call our print routine
DATA STRING
DATA STRLEN
IDLE
*
WP BSS 32 Main program workspace
*
* Message
*
STRING TEXT 'Hello world!'
BYTE >D,>A
STRLEN EQU $-STRING
EVEN
PAGE
*
* Print a message
*
PRINT DATA PRWS,PRENT
PRENT EQU $
MOV *R14+,R2 Get buffer address
MOV *R14+,R1 Get message length
SBO DTR Enable terminal ready
SBO RTS
PRI010 LDCR *R2+,8 Send out a character
TB WRQ Wait until done
JNE $-2
SBZ WRQ
DEC R1
JGT PRI010
RTWP
*
PRWS DATA 0,0,0,0,0,0,0,0
DATA 0,0,0,0,TRMCRU,0,0,0
*
END ENTRY
Operating systems
Several operating systems were available for the TI-990
From TI:
From third parties:
References
- ↑ Rhines, Walden (22 June 2017). "The Inside Story of Texas Instruments' Biggest Blunder: The TMS9900 Microprocessor". IEEE Spectrum. https://spectrum.ieee.org/the-inside-story-of-texas-instruments-biggest-blunder-the-tms9900-microprocessor.
- ↑ "DX10 Operating System Release 3.5 System Design Document". Texas Instruments, Inc. 1982.. p. 8-1. http://bitsavers.org/pdf/ti/990/dx10/0939153-9701D_3.5_SystemDesignDocument_Sep82.pdf.
- ↑ 3.00 3.01 3.02 3.03 3.04 3.05 3.06 3.07 3.08 3.09 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 3.20 3.21 3.22 3.23 3.24 3.25 3.26 3.27 990/99000 Assembly Language Reference Manual. Texas Instruments. 15 November 1982. https://bitsavers.org/pdf/ti/990/assembler/2270509-9701A_AsmRef_Nov82.pdf.
- ↑ "Using TMS 9000 XOP Instruction to implement a Debugging Function". https://github.com/AlexanderAdelAU/DEBUGGING_TMS9900_USING_XOP.
- ↑ Model 990/10 Computer System Hardware Reference Manual. Texas Instruments. November 1980. pp. 3-50-3-54. https://bitsavers.org/pdf/ti/990/990-10/0945417-9701B_990-10_HWRef_Nov80.pdf. Retrieved 24 August 2026.
- ↑ Model 990 Computer Reference Manual Preliminary. Texas Instruments. 1 October 1974. p. 4-40. https://bitsavers.org/pdf/ti/990/990-10/0943442-9701_990prelim_Oct74.pdf.
External links
- Dave Pitts' TI 990 page — Includes a simulator, cross assembler, cross linker, utilities and Operating System images.
- Translator of SCI 990 to COBOL
- ti990.co.uk in internet archive Site detailing the preservation and restoration of TI 990 series minicomputers
- Texas Instruments records, DeGolyer Library, Southern Methodist University
