
| JTT has eight instructions, which together makes up JTT?s mnemonic language (see later). Each has its own specific low-level function, and can be used in conjunction with each other. As with a Turing machine, almost any task can be accomplished with the correct sequence, and number, of any of these eight instructions. The word 'almost' is used here because JTT only has a limited amount of memory space. Set to 4,096 at default, this means that JTT can hold a maximum of 4,096 instructions (plus 4,096 data elements) at any one time. |
| Please Note |
| The instructions work in conjunction with memory, registers and flags. To learn about these in more detail, see Chapter 5 - Memory, Registers and Flags. |
| Do not confuse JTT's instruction set with the CLI's commands. The former is the series of eight instructions the emulator understands to perform operations within a JTT program. The latter are the operations of the CLI and GUI that the user can use to do things not related directly to JTT programs, such as quitting and displaying help. The functions of the CLI and GUI are dealt with in Chapter 6 and Chapter 7 respectively. |
| For a list of common instruction memory address ranges, and their corresponding mnemonic instructions, see Chapter 4.8 (on a separate page). |
|
Each instructions, numbered (decimal) 0 to 7, are explained below, including the machinecode and mnemonic format of each and the limitations of use. The numerical result from all instructions (whether calculating new data or moving existing data) is placed in data memory at the given address. |
| No. | Name | Function |
| 0 | Load Constant | Puts a datum constant directly into data memory |
| 1 | BitSelect | Selects a given bit of a particular register |
| 2 | Add | Adds two values together |
| 3 | Subtract | Subtracts the second value from the first |
| 4 | Logical NAND | NANDs two values together |
| 5 | Rotate Left | Shifts the binary value once to the left |
| 6 | Fetch from Memory | Gets a value from data memory |
| 7 | Store to Memory | Puts a value into data memory |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | T | I | I | I | C | D | D | D | A | A | A | A | B | B | B | B |
|
| Please Note |
The TRAP bit (T) is never set to 1 during the use of one
of the
standard eight instructions. However, two additional implemented
instruction make use of the TRAP expansion facility, HALT,
occurs when all 16 bits are set to 1. In other words, the machinecode
instruction $1111 1111 1111 1111 is HALT,
which stops the program. NULL ($1111 1111 1111
1110) signifies a memory address that has not yet
appropriated an instruction. More on these later.
|
|
Each of the bits can be set to 1 (active) or 0 (inactive). Thus, every possible instruction combination can be represented by a code of 16 bits (i.e. a Word). This is directly recognisable by the processor, or in the case of JTT, by the emulator. Such a binary code, for these reasons, is called a machinecode language. The representation that is immediately recognisable to humans by its use of English words, is termed mnemonic code. The user can program using either convention. An explanation of each instruction, in both formats, is given in the sections below. The instructions will be referenced, in this Manual and in JTT itself, using a specific format. The format is simple, and avoids some ambiguities that may crop up. It is useful to learn the syntax before continuing, and the instructions used as examples will be used in Section 4.2.
|
| Please Note |
| Some of the instructions below may appear to be unnecessarily restricted in their use. Section 4.4 provides the reasons why. However it may be wise to leave this section until you are experienced with using Mnemonic instructions below first. |
|
Template: Instruction 0 - Load Constant <rx>=<value|ry>;There are two uses of Load Constant. The first loads constant value <value> into register <rx>. The second loads the value contained in register <ry> into register <rx>. The constant, <value|ry> may thus be:
The reason why only 7-bit constants are accepted is explained in Section 4.4. Only a constant value has this restriction; the contents of a register can be 16 bits wide, as normal. To load constants from and to data memory addresses, use fetch from memory and store to memory respectively. Examples of Load Constant:
Template: Instruction 1 - BitSelect <rx>=<ry|value> [<rz|value>];With BitSelect, it should be remembered that the square brackets ([ and ]) are typed in as part of the instruction, and do not signify optional instruction arguments. This instruction places a given bit of a given value (or value inside a register) and places it in bit 0 (the least significant bit, to the right) of the destination register. Its major purpose is to test the states of the flags in r7. Since bit 0 of r7 is the Query flag, which can directly be influenced by the JTT programmer, the other bits, such as Negative and Zero, can be placed into Query in order to use the Comparison Instruction Extension (see Chapter 5.4). It can also allow the programmer to perform tests on the values of registers, by examining the settings of their bits without having to use the flags in r7. This way, you can use memory spaces and registers as your own custom flags amongst others. The destination must be a register. This can, and usually does include r7. The next value, <ry|value>, can either be one of the registers from which to take the value to BitSelect, or a constant to BitSelect. The last value is placed inside square brackets, and is the one that designates which bit to take out. Consequently, it can be a constant between 0 and 15, a register, or one of the flag names. The constant corresponds to bit 0 (the least significant, on the right), bit 15 (the most significant, on the left) or any bit in- between. If a register is given, the four least significant bits are red and the corresponding value is used. If any of the eight register names is given, it must be a lower-case, single character from those outlined in Chapter 5.4. Examples of its use follow. Example 1: Place the Zero flag into the Query flag for testing. Solution: r7=r7[z]; Example 2: Place bit 4 of r5 into r0. Solution: r0=r5[4]; Example 3: Place the bit of r1, as designated by r2, into r3. Solution: r3=r1[r2]; Example 4: Place the Carry bit into r0. Solution: r0=r0[c]; Template: Instruction 2 - Add <rx>=<value|ry>+<value|rz>;This simply adds two values, <value|ry> and <value|rz> together, and places the result into register <rx>. The rules for its use are that each constant, <value|reg>, must be:
Thus, add can be used as Load Constant except that:
Memory addresses cannot directly be accessed, so 'Fetch from Memory' and 'Store to Memory' should be utilised. If the result is larger than a 16-bit value, as may happen if two registers are added together, it will be truncated to the least significant 16 bits and the carry bit will be shown. It is therefore your job to check for such values (via the carry flag) and deal with them as necessary. This also means that the larger the value, the more information is lost and it becomes less accurate. Two examples are:
Template: Instruction 3 - Subtract <rx>=<value|ry>-<value|rz>;This simply subtracts the second value (<value|rz>) with from the first (<value|ry>), and places the result into register <rx>. The rules for its use are identical to add (above). The comparative examples to add are:
|
| Please Note |
| The contents of the memory address which is the addition of the two given values is loaded. It is not the case that the memory address of the first is added to the constant of the second. For example, in the instruction r0=memory[r5+20] , where r5 contains 1, r0 does not become (the contents of address 1)+20. Instead, it becomes (the contents of memory address 21). |
|
Template: Instruction 4 - Logical NAND <memory[<value|rx>+<value|ry>]>=<value|rz>;As defined by De Morgan's Laws, any operation using AND, OR, NOT or XOR can be achieved using the appropriate number and combination of NAND. This stems from electronics in the use of logic gates, and thus may be somewhat a misnomer for some readers. However, the basics are simple, and relate to boolean logic. Consider that two values, A and B, can be true (1) or false (0). The result is also either true or false, but it is determined by the state of A and B. AND is used when the result is true only when both A AND B are true. With OR, the result is true if either A OR B are true, or if both are true. NOT causes the result to be true if both A and B are false (NOT true), and is therefore the opposite of AND. XOR, or 'exclusive OR', makes the result true if and only if either A OR B are true (but not both nor neither). The following truth tables show each of the four possibilities and outcomes of each: |
| GATE | A | B | RESULT | GATE | A | B | RESULT | |
| AND | 0 | 0 | 0 | OR | 0 | 0 | 0 | |
| AND | 1 | 0 | 0 | OR | 1 | 0 | 1 | |
| AND | 0 | 1 | 0 | OR | 0 | 1 | 1 | |
| AND | 1 | 1 | 1 | OR | 1 | 1 | 1 | |
| NOT | 0 | 0 | 1 | XOR | 0 | 0 | 0 | |
| NOT | 1 | 0 | 0 | XOR | 1 | 0 | 1 | |
| NOT | 0 | 1 | 0 | XOR | 0 | 1 | 1 | |
| NOT | 1 | 1 | 0 | XOR | 1 | 1 | 0 |
| Consequently, NAND, or 'not AND', is true when either A or B are true, or if neither are true (but not both). NAND is therefore the opposite of AND. This means that if A and B are NANDed (to make A NAND B), the result is thus with each combination: |
| 0 | NAND | 0 | = | 1 |
| 0 | NAND | 1 | = | 1 |
| 1 | NAND | 0 | = | 1 |
| 1 | NAND | 1 | = | 0 |
|
When a result is NANDed by itself, as you can see in the table above, true
becomes false and false becomes true. Therefore, if 'A NAND B = C', 'C NAND
C' produces the same result as 'C NOT C'. Therefore, 'NAND (A NAND B)'
= 'NOT (A AND B'). You will have to work out the repetition and order
required to make NAND work for the other logic gates, but after NOT, more
and more NAND gates will be required.
Template: Instruction 5 - Rotate Left (rol) <rx>=<ry|value>rol<rz|value>;This instruction takes a value (as a constant or the value of a register) and converts it into binary notation. Then, each of the bits are moved ('rotated') to the left and the previous most significant bit (bit 15) is placed into the now vacant least significant bit (bit 0) on the right. Each time the bits are shifted one place, the result is effectively multiplied by 2, and the number of shifts to carry out is defined in the value (or register value) after the rol instruction. This provides a computationally uncostly method of squaring values and providing a 'multiply by two to the power of' function. The command can also be used (with the appropriate number of Rotate Left instructions) to the effect of 'rotating' the value right (and thereby square-rooting the result). As with the add instruction, although the destination has to be a register, the two values to use in the operation (i.e. the value and the number of times to rotate left) can be expressed either as a 7-bit constant or as a register. If the value becomes too large (i.e. more than 16 bits can hold, which is decimal 65,536 or $1111 1111 1111 1111 or 0xffff), the most significant figure (the leftmost bit) is rotated over to become the least significant figure instead of the 0, and the carry flag is set. Some examples of its use follow. The first is a straightforward multiplication of a given constant. The second increases a value by a larger power. The third shows what happens when the register runs out of space. The forth increases the value in a register by the power given in another register, and shows that, if the programmer is not careful (see Note for this instruction, below), the actual result may not bear any resemblance to the expected (or required) result. Example 1: Double the number (decimal) 27. Manual Working: 1. Decimal 27 in binary notation: $0000 0000 0001 1011 2. rotate Left once (27 rol 1): $0000 0000 0011 0110 3. The result is the following in decimal: 54 Example 2: Calculate 0xfff multiplied by two to the power of 4. Manual Working: 1. Hex 0xfff in binary notation: $0000 1111 1111 1111 2. rol four times (0xfff rol 4): $1111 1111 1111 0000 3. The result is the following in hex: 0xfff0 (decimal 65521) Example 3: Double the result calculated in Example 2. Manual Working: 1. Decimal 65521 shown in binary: $1111 1111 1111 0000 2. Rotate left once: $1111 1111 1110 0000 3. Place the prev. rightmost bit on left: $1111 1111 1110 0001 4. The result is the following in hex: 0xffe1 (decimal 65506) Example 4: Multiple the value in r0 by the value in r1. Solution: r0=r0 rol r1; |
| Please Note |
| To avoid garbled results from too many rotations, create a loop that tests the carry flag on each rotation. If the carry flag is set, you may either use it as a 17th bit or exit the loop. In either of these cases, if you just want it to left-shift, to double the result, use BitSelect (below) to clear the least significant bit each time. |
| This command is not fussed whether or not you put spaces between the rol keyword and the two values to the right of the equals symbol. This goes with nand also. |
| With a loop and a bit of brainpower, this instruction can also be used to imitate a 'rotate right' (ror) instruction. Rotate right is also common in some assembly programming languages. |
|
Template: Instruction 6 - Fetch from Memory <rx>=<memory[<value|ry>+<value|rz>]>;Fetch from Memory stores the contents of a data memory address into register rx. Data memory addresses must always be given as two values to add together, and each value must either be a 7-bit number or 16-bit register, as with the add instruction. Also as with add, the maximum memory address that can be implied as a constant is 254. However, memory addresses are temporarily stored as 32-bit numbers and are not truncated, allowing JTT to use a maximum of 4,294,967,295 (just over four billion) data and instruction memory a addresses. Some examples follow (next page).
Template: Instruction 7 - Store to Memory <memory[<value|rx>+<value|ry>]>=<rz>;Store to Memory stores the contents of a register, or a constant value, into the given memory address. See Fetch from Memory for usage guide.
|
| Please Note |
| This instruction can only store the contents of a register (i.e. not a constant value), due to how the machinecode is stored. See Section 4.4 for an explanation why. |
|
|
| Please Note |
| Remember, unlike decimal, binary (and hex) numbers have their most significant figures to the left. As a result, binary numbers appear 'backwards' - that is, the higher bits are given on the left, and bit 0 on the extreme right. Don?t forget to adjust accordingly when dealing with binary values and using the following binary tables. |
|
Only more advanced users of JTT should attempt to insert instructions directly in machinecode notation. Other users should first study and use the mnemonic form of Section 4.1, then move onto this section. It is, however, extremely important to get around to machinecode eventually, since this it is the main goal of JTT to teach users the fundamentals of simple processor operations, and machinecode is at its heart. It is good practice, for learning computer fundamentals and for keeping the brain active. Instruction 0: Load Constant 'Load Constant' loads a constant value, or the contents of a register, into a register. Due to "hardware" restrictions, this value cannot be smaller than 0 or larger than 2^7, or decimal 127, binary $111 1111 or hex 0x7f. It is evident why if we look at the table below that shows the machinecode representation of this instruction: |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 0 | 0 | 0 | C | D | D | D | R | K | K | K | K | K | K | K |
|
The trap bit and instruction bits are all set to 0, and bits (decimal) 0 to
7 (R and K) are treated as one group. Bit 7 denotes whether bits 4 to 6 are
registers (if set to 0) or whether bits 0 to 6 should be treated as a direct
constant value (if set to 1). Thus, the maximum literal value can be 7 bits
wide (2^7, with a range of 0:127/$111 1111/0x7F), or 16 bits wide (by
throwing into the destination the contents of another register) if a
register is given.
To use this instruction in machinecode is easy. Whilst the value or register to use as the constant is given in bits 0 to 7, are above, bits 8 to 10 contain the three bits designating the destination (D) register number ($000 to $111). Bit 11 is the conditional (C) bit. If the Comparison Instruction Extension (see Chapter 5.4) is used to denote a conditional execution of this instruction, bit 11 is set to 1. Examples follow.
Example 1: Load constant (decimal) 44 into register 4 (r4).
Solution:
1. The Trap bit and Instruction bits (i.e. bits 12 to 15) are set to 0.
2. The instruction is not conditional, so bit 11 is set to 0.
3. The destination register is r4, so the D bits become $100.
4. The source is not a register, so bit 7 is set to 1.
5. Bits 0 to 6 therefore contain the number (decimal) 44, or $010 1100.
6. The machinecode instruction is thus: $0000 0100 1010 1100, or
decimal 1,196 or 0x04ac.
Example 2: Load r1 into r0, but only if the query flag is set.
Solution:
1. The trap bit and instruction bits are set to 0.
2. The instruction is conditional, so bit 11 is set to 1.
3. The destination register is r0, so the D bits become $000.
4. The source is a register, so bit 7 is set to 0.
5. Bits 4 to 6 are $001 (r1), and bits 0 to 3 are set to 0.
6. The machinecode instruction is thus: $0000 1000 0001 0000, or
7. decimal 2,064 or 0x0810.
Instruction 1: BitSelect Here, the first value (RAAA) is the value from which to select a bit and the second (RBBB) contains the bit to select. If RBBB is a constant, it can access the least significant half. It a register, the four least significant bits are used to determine which bit to select, from 0 to 15. |
| Please Note |
| The bit is put into the least significant bit (bit 0, to the right) of the destination register. The other bits of the destination register remain as they were before the operation. |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 0 | 0 | 1 | C | D | D | D | R | A | A | A | R | B | B | B |
Example 1: Place bit (decimal) 6 of r2 into bit 0 of r2.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $001.
2. The instruction is not conditional, so carry is set to 0.
3. The destination is r2, so DDD becomes $010.
4. The source value is in r2, so bit 7 is set to 0 and AAA become $010.
5. The bit to select is (decimal) 6, so bit 7 is 1 and BBB become $110.
6. The machinecode instruction is thus: $0001 0010 0010 1110, or
decimal 4,654 or 0x122e.
Example 2: Place the Zero flag into the Query flag, if Query is true.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $001.
2. The instruction is conditional, so carry is set to 1.
3. The destination is r7, so DDD becomes $111.
4. The source value is in r7, so bit 7 is set to 0 and AAA become $111.
5. The bit to select is (decimal) 1, so bit 7 is 1 and BBB become $001.
6. The machinecode instruction is thus: $0001 1111 0111 1001, or
decimal 8,057 or 0x1f79.
Instruction 2: Add 'Add' places the addition of two values into a given register. |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 0 | 1 | 0 | C | D | D | D | R | A | A | A | R | B | B | B |
|
The instruction adds a value or register value to another value or register value, and places the result into the register given in the three DDD bits. If bit 11 is set to 1, the instruction is conditional. If bit 7 is set to 0, then AAA becomes the register from which to take the value. If set to 1, then AAA becomes a constant, from 0 to (decimal) 7. The same can be said for bit three and its relation to BBB. If the result of the addition of the two values is larger than a 16-bit number, the carry flag is set (thereby providing a temporary 17th bit) and the remaining 16 bits hold the 16 least significant bits of the result.
Example 1: Add one to the contents of r1 and place the result into r3.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $010.
2. The instruction is not conditional, so carry is set to 0.
3. The destination is r3, so DDD becomes $011.
4. The first constant is r1, so bit 7 is set to 0 and AAA become $001.
5. The second constant is 1, so bit 7 is set to 1 and BBB become $001.
6. The machinecode instruction is thus: $0010 0011 0001 1001, or
decimal 8,985 or 0x2319.
Example 2: Multiply r5 by 2 and place the result into r0, only if the Query
flag is 1.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $010.
2. The instruction is conditional, so carry is set to 1.
3. The destination is r0, so DDD becomes $000.
4. The first constant is r5, so bit 7 is set to 0 and AAA become $101.
5. The second constant is also r5, so bit 7 is set to 0 & BBB become $101.
6. The machinecode instruction is thus: $0010 1000 0101 0101, or
decimal 10,325 or 0x2855.
Instruction 3: Subtract 'Subtract' places the result of the second value minus the first into a given register. The rules are as with Add. If the result of the subtraction is zero or less, the Zero or Negative flag are set to 1 accordingly, and the value 'wraps around' as in 2s-comp (See Chapter 3.7). |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 0 | 1 | 1 | C | D | D | D | R | A | A | A | R | B | B | B |
Example: Minus two from one and place the result into r4.
Solution: (NB. the result will be decimal 65535 and carry will be set.)
1. The trap bit is set to 0. The instruction bits are set to $011.
2. The instruction is not conditional, so carry is set to 0.
3. The destination is r4, so DDD becomes $100.
4. The first constant is (decimal) 2, so bit 7 is 1 and AAA become $010.
5. The second constant is 1, so bit 7 is set to 1 and BBB become $001.
6. The machinecode instruction is thus: $0011 0100 1010 1001, or
decimal 13,481 or 0x34a9.
Instruction 4: Logical NAND 'NAND' works similarly to Add and Subtract in terms of its syntax: |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 1 | 0 | 0 | C | D | D | D | R | A | A | A | R | B | B | B |
AAA and BBB can, once more, be registers or constants, the limits of the
latter being similar to the other instructions as 7-bit values.
Example 1: NAND r1 and r2 and place the result into r3.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $100.
2. The instruction is not conditional, so carry is set to 0.
3. The destination is r3, so DDD becomes $011.
4. The first constant is in r1, so bit 7 is set to 0 and AAA become $001.
5. The second constant is r2, so bit 7 is 0 and BBB become $010.
6. The machinecode instruction is thus: $0100 0011 0001 0010, or
decimal 17,170 or 0x4312.
Example 2: NAND the value (decimal) 5 by itself and place the result
into r0, only if query is set.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $100.
2. The instruction is conditional, so carry is set to 1.
3. The destination is r0, so DDD becomes $000.
4. The first constant is (decimal) 5, so bit 7 is set to 1 and AAA = $101.
5. The second constant is the same, so bit 7 is 1 and BBB become $101.
6. The machinecode instruction is thus: $0100 1000 0101 0101, or
decimal 18,517 or 0x4855.
Instruction 5: Rotate Left (ROL) |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 1 | 0 | 1 | C | D | D | D | R | A | A | A | R | B | B | B |
Example 1: Rotate r5 by 1 and place the result back into r5.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $101.
2. The instruction is not conditional, so carry is set to 0.
3. The destination is r5, so DDD becomes $101.
4. The first constant is in r5, so bit 7 is set to 0 and AAA become $101.
5. The second constant is 1, so bit 7 is 1 and BBB become $001.
6. The machinecode instruction is thus: $0101 0101 0101 1001, or
decimal 21,849 or 0x5559.
Example 2: Rotate r1 by the value in r2 and place the result into r3,
only if the query flag is set.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $101.
2. The instruction is conditional, so carry is set to 1.
3. The destination is r3, so DDD becomes $011.
4. The first constant is in r1, so bit 7 is set to 0 and AAA become $001.
5. The second constant is in r2, so bit 7 is also 0 and BBB become $010.
6. The machinecode instruction is thus: $0101 1011 0001 0010, or
decimal 23,314 or 0x5b12.
Instruction 6: Fetch from Memory Our first memory instruction places the contents of a given data memory address into a given register. |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 1 | 1 | 0 | C | D | D | D | R | A | A | A | R | B | B | B |
|
The setup is identical to add and subtract. The destination must be one of
the registers, and the address must be given as two values, which are added
to find the appropriate data memory address from which to get the value.
Either AAA or BBB can be either a register or value, but the latter can only
be 3 bits long. Therefore, using only constants, addresses 0 to (decimal) 14
can be accessed.
To get at higher addresses, you must go through registers. To access a 16- bit address (i.e. up to (decimal) 65,535), use a register and a value (such as r0+0, or 0+r4). If two registers are used together, their 32-bit value (rAAA+rBBB) is used. This is useful for JTT memory sizes larger than 16 bits (see MemSize, Chapter 6.2).
Example 1: Place contents of memory address (decimal) 13 into r0.
Solution: (N.B. There is more than one combination of constants to use.)
1. The trap bit is set to 0. The instruction bits are set to $110.
2. The instruction is not conditional, so carry is set to 0.
3. The destination is r0, so DDD becomes $000.
4. The first constant is (decimal) 7, so bit 7 is set to 1 and AAA = $111.
5. The second constant is (decimal) 6, so bit 7 is 1 and BBB = $110.
6. The machinecode instruction is thus: $0110 0000 1111 1110, or
decimal 24,830 or 0x60fe.
Example 2: Place contents of the memory address designated by the
32-bit value r0+r1, placing result in r2, only if query is set.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $110.
2. The instruction is conditional, so carry is set to 1.
3. The destination is r2, so DDD becomes $010.
4. The first constant is in r0, so bit 7 is set to 0 and AAA become $000.
5. The second constant is r1, so bit 7 is 0 and BBB become $001.
6. The machinecode instruction is thus: $0110 1010 0000 0001, or
decimal 27,137 or 0x6a01.
Instruction 7: Store to Memory The second memory instruction places the contents of a given register into the given data memory address. It is slightly different to the rest. Whilst the other instructions hold (in machinecode binary, from right to left) the source and then the destination, Store to Memory holds the destination memory address followed by the source register or value. Thus, in the table below, S denotes the source constant or register. |
| Bit No. | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Name | 0 | 1 | 1 | 1 | C | S | S | S | R | A | A | A | R | B | B | B |
One other thing to note is that the source (bits 8-10) can only refer to a
register, since there is not enough room for the extra bit needed to store
whether the source is a register or constant value. The instruction
otherwise works as the reverse of Instruction 6. To illustrate, the two
examples below are similarly contrary to those of 'Fetch from Memory'.
Example 1: Place contents of r0 into memory address (decimal) 13.
Solution: (N.B. There is more than one combination of constants to use.)
1. The trap bit is set to 0. The instruction bits are set to $111.
2. The instruction is not conditional, so carry is set to 0.
3. The source is r0, so SSS becomes $000.
4. The first constant is (decimal) 7, so bit 7 is set to 1 and AAA = $111.
5. The second constant is (decimal) 6, so bit 7 is 1 and BBB = $110.
6. The machinecode instruction is thus: $0111 0000 1111 1110, or
decimal 28,926 or 0x70fe.
Example 2: Place the contents of r2 into the memory address designated by
the 32-bit value r0+r1, only query is set.
Solution:
1. The trap bit is set to 0. The instruction bits are set to $111.
2. The instruction is conditional, so carry is set to 1.
3. The source is r2, so SSS becomes $010.
4. The first constant is in r0, so bit 7 is set to 0 and AAA become $000.
5. The second constant is r1, so bit 7 is 0 and BBB become $001.
6. The machinecode instruction is thus: $0111 1010 0000 0001, or
decimal 31,233 or 0x7a01.
4.5 Mnemonic Exceptions and Keywords There are a few exceptions and additions to the mnemonic syntax that do not appear in JTT's machinecode language. There are still strictly only eight JTT machinecode instructions, and there can only therefore be eight mnemonic instructions. Those below, however are neither instructions nor CLI or GUI commands. The MaxMem Constant The MaxMem keyword can be used in the place of the largest available memory address. Whilst JTT's actual memory size is set at default to 4,096, this value can be altered by the user via the MemSize command (see Chapter 6.2). As a result, whenever the memory size is changed, a program, which addresses, uses or exceeds a high memory address may have to be altered when JTT's memory capacity is reduced. In mnemonic commands, this can be taken into account by using the MaxMem mnemonic in any operations regarding the largest memory address. Then, when the program is executed, its behaviour will alter depending upon the size of JTT's "physical" memory. You can also make provisions for lower memory states by comparing its value and "cutting out" sections of a program that require more instruction memory addresses than are available. This might work by manipulating the IP to skip sections of your code. As it takes the form of a Trap instruction, MaxMem can also be applied to machinecode (see later). Its primary (and only recommended) use is as a shortcut to changing mnemonic source code to accommodate different JTT versions. Its use must still be treated with the utmost care and skill to avoid overflow errors, memory use conflicts etc., though (see later for an example scenario). There are 8 possible uses of MaxMem (and thus 8 corresponding Trap instruction allocations): Mnemonic Machinecode ========= ================================= r0=maxmem 65520/$1111 1111 1111 0000/0xFFF0 r1=maxmem 65521/$1111 1111 1111 0001/0xFFF1 r2=maxmem 65522/$1111 1111 1111 0010/0xFFF2 r3=maxmem 65523/$1111 1111 1111 0011/0xFFF3 r4=maxmem 65524/$1111 1111 1111 0100/0xFFF4 r5=maxmem 65525/$1111 1111 1111 0101/0xFFF5 r6=maxmem 65526/$1111 1111 1111 0110/0xFFF6 r7=maxmem 65527/$1111 1111 1111 0111/0xFFF7In other words, in binary representation, there are 12 ones, a zero and then the three bits corresponding to the octal value of the register to store to. Note also that code such as r0=maxmem+1 and
r5=IP nand maxmem are not possible. A usage example follows.
Example: Say a program needs to put the value decimal 255 or
$1111 1111 or 0xff into the last, and the second-to-last,
data memory addresses. The code would look something
like this:
r0=MaxMem;
memory[r0+0]=$11111111;
memory[r0-1]=$11111111;
MaxMem may only be used in the form of a Load Constant instruction, and not in any form or as "pure" Load Constant, for architectural reasons. Load Constant only accepts 7-bit literal values and the memory size can be anything up to 16 bits! Therefore, trap instruction spaces are utilised. Moreover, to expand MaxMem to emulate the other instructions is wasteful and would take up considerable "trap space". Make sure that declarations to literal addresses are not going to conflict with the use of MaxMem. For example, the following program stores two literal values into memory at the same time: r0=127; memory[r0+0]=5; r1=MaxMem; memory[r1+0]=7;It would work fine with JTT memory sizes of (dec) 256 and greater, but would conflict by overwriting the same memory address and utilising it for two purposes with a memory size of (dec) 128. Possible work-arounds: r0=maxmem;r1=MaxMem would use address
space 63, so anything lower than this is (at least in our example)
acceptable.
|
| Please Note |
Be careful how MaxMem is used. Using r0=maxmem and then
attempting a r0=r0+1 will result in a runtime error,
and will by definition always be outside the legal memory range.
|
| The MaxMem constant is not case sensitive. |
| See also the comparison instruction extension ( Chapter 5.4), which is also a mnemonic command extension. |
| The comparison instruction extension cannot be used directly in your use of MaxMem; only the 8 representations given (see above) can be used. |
|
Comments A comment is a string, found in mnemonic instruction listings, which is intended to be read by a programmer but not to be executed as an instruction. Such devices allow the programmer to place notes or reminders inside a program at particular places. There are two comment keywords, both taken from other programming languages. These are the ?;? (semicolon) character and the '#' (hash) character. They can be used at any place on a line, and the number of spaces preceding it (whether after an instruction or on a new line) does not technically matter.
During compilation of a mnemonic program into machinecode, these symbols and
the rest of the line after them are ignored. Therefore, they may be used at
the start of a new line, or after an instruction at the end of an old one.
It is conventional to use the hash character to dedicate an entire line to a
comment, and the semicolon to add a comment after an instruction. An entire
mnemonic instruction line dedicated to a comment is treated as a non-
instruction (a When such comments are entered, they are stripped away from the instruction and will not appear with the program listings. However, the comments will be stored in a special database of the CLI consisting of as many entries as there are memory addresses. Whenever you are about to overwrite an instruction memory address that you have marked with a comment, you will be informed of the comment and asked to confirm the overwrite of the address. Alternatively, you can view any or all comments using the comment command (see Chapter 6.2).
Example: The first of the following example lines of code adds a
comment after the given instruction. The second
dedicates an entire in line to a comment.
r6=MaxMem; Places largest mem address into r6
r0=r1+r2;
# The preceding line adds r1 and r2 --> r0
Null Instructions
When JTT is first loaded, there are no instructions in instruction memory
and data memory is filled with a series of 0s. This also occurs when the
programmer uses the command in the CLI (see the Data command,
Chapter 6.2).
This way, when a programmer fills memory with instructions but leaves gaps
between code, unwanted instructions the programmer did not ask for are not
carried out. Such a marker in instruction memory, which tells JTT to carry
out no action is called a non-instruction, or
The JTT machinecode for a
You can insert |
| Please Note |
null is unique to this usage within JTT, and
cannot be used as (and indeed is not) a value in itself. |
Originally, r0=r0 (machinecode 0). However, it is now its own
instruction. There are two reasons for this. Firstly, the specialised
trap instruction does one operation (IE read the instruction) whilst
r0=r0 does three (reads r0; stores r0; puts back into r0)
which is clearly much less efficient and more wasteful. Secondly, it
is easier for you to see whether an instruction in your mnemonic code
is intended as an unfilled space, which is more difficult at a glance
to see if r0=r0 (for example) is used. |
|
HALT Instructions
|
| Please Note |
Because it uses all 16 bits, there is no physical room to store
whether the HALT instruction is conditional, and so can
only make use of the Query flag indirectly. To do this, you should
use a conditional statement that points r6 to a HALT
command elsewhere. HALT itself should be placed with
care. |
4.7 Helpful Tips: More Advanced
|
![]() |
![]() |
![]() |
![]() |
![]() |